I'm trying to concat filename and line without path at compile time. Like /tmp/main.cpp20
-> main.cpp:20
#include <array>
#include <iostream>
using namespace std;
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)
constexpr const char* file_name(const char* path) {
const char* file = path;
while (*path) {
if (*path++ == '/') {
file = path;
}
}
return file;
}
constexpr std::size_t str_size(const char* str) {
auto i = str;
while (*i != '\0') ++i;
const auto length = i - str;
return length;
}
template <std::size_t N1, std::size_t N2>
constexpr std::array<char, N1 + N2 + 2> formatFilename(const char* name,
const char* line) {
auto total_size = N1 + N2 + 2;
std::array<char, N1 + N2 + 2> res{};
std::size_t i = 0;
for (; i < N1; ++i) {
res[i] = name[i];
}
res[i++] = ':';
for (int j = 0; j < N2; ++j) {
res[i + j] = line[j];
}
res[total_size - 1] = '\0';
return res;
}
int main() {
constexpr char *p = &(
formatFilename<str_size(file_name(__FILE__)), str_size(LINE_STRING)>(
file_name(__FILE__), LINE_STRING)[0]);
cout << p << endl;
}
But it seems not work and return a compilation error
main.cpp: In function ‘int main()’: main.cpp:46:46: error: call to non-‘constexpr’ function ‘std::array<_Tp, _Nm>::value_type& std::array<_Tp, _Nm>::operator[](std::array<_Tp, _Nm>::size_type) [with _Tp = char; long unsigned int _Nm = 12; std::array<_Tp, _Nm>::reference = char&; std::array<_Tp, _Nm>::value_type = char; std::array<_Tp, _Nm>::size_type = long unsigned int]’
Is there any way to do it at compile time?