// https://a...content-available-to-author-only...b.io/blog/2023/11/04/Compiletime-string-literals-processing.html #include <cstddef> #include <limits> namespace a4z { constexpr std::size_t cstr_len(const char* str) { std::size_t len = 0; while (*(str + len) != '\0') { ++len; } return len; } constexpr auto npos = std::numeric_limits<std::size_t>::max(); template <std::size_t N> constexpr std::size_t find_nth_r_occurrence(const char (&str)[N], char ch, std::size_t n) { std::size_t count = 0; for (std::size_t i = N; i-- > 0;) { if (str[i] == ch) { ++count; if (count == n) { return i; } } } return npos; // Not found } constexpr bool on_windows() { #ifdef _WIN32 return true; #else return false; #endif } template <std::size_t N> struct astr { char data[N] = {0}; constexpr astr(const char (&arr)[N]) noexcept { for (std::size_t i = 0; i < N; ++i) { data[i] = *(arr + i); } } constexpr const char* c_str() const noexcept { return &data[0]; } constexpr std::size_t size() const noexcept { return N - 1; } }; constexpr char slash = on_windows() ? '\\' : '/'; #define a4z_file_name \ []() consteval { \ constexpr const char* str = __FILE__; \ constexpr auto len = a4z::cstr_len(str); \ constexpr auto start{a4z::find_nth_r_occurrence(__FILE__, a4z::slash, 2)}; \ static_assert(start != a4z::npos); \ constexpr std::size_t astr_len = len - start; \ char data[astr_len]; \ for (std::size_t i = 0; i < astr_len; ++i) { \ data[i] = *(str + start + i + 1); \ } \ return a4z::astr<astr_len>{data}; \ } } // namespace a4z // -- Application part #include <cstdio> int main() { fprintf(stdout, "%s\n", a4z_file_name().c_str()); return a4z_file_name().size(); }
Standard input is empty
prog.cpp: In lambda function: prog.cpp:58:8: error: expected ‘{’ before ‘consteval’ []() consteval { \ ^~~~~~~~~ prog.cpp:79:28: note: in expansion of macro ‘a4z_file_name’ fprintf(stdout, "%s\n", a4z_file_name().c_str()); ^~~~~~~~~~~~~ prog.cpp: In function ‘int main()’: prog.cpp:58:8: error: expected ‘)’ before ‘consteval’ []() consteval { \ ^~~~~~~~~ prog.cpp:79:28: note: in expansion of macro ‘a4z_file_name’ fprintf(stdout, "%s\n", a4z_file_name().c_str()); ^~~~~~~~~~~~~ prog.cpp:79:11: note: to match this ‘(’ fprintf(stdout, "%s\n", a4z_file_name().c_str()); ^ prog.cpp:79:20: warning: format ‘%s’ expects argument of type ‘char*’, but argument 3 has type ‘main()::<lambda()>’ [-Wformat=] fprintf(stdout, "%s\n", a4z_file_name().c_str()); ^~~~~~ prog.cpp: In lambda function: prog.cpp:58:8: error: expected ‘{’ before ‘consteval’ []() consteval { \ ^~~~~~~~~ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp: In function ‘int main()’: prog.cpp:58:8: error: invalid user-defined conversion from ‘main()::<lambda()>’ to ‘int’ [-fpermissive] []() consteval { \ ^~~~~~~~~ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp:58:6: note: candidate is: ‘main()::<lambda()>::operator void (*)()() const’ <near match> []() consteval { \ ^ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp:58:6: note: no known conversion from ‘void (*)()’ to ‘int’ []() consteval { \ ^ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp:58:8: error: expected ‘;’ before ‘consteval’ []() consteval { \ ^~~~~~~~~ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp:58:8: error: ‘consteval’ was not declared in this scope []() consteval { \ ^~~~~~~~~ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp:58:8: note: suggested alternative: ‘constexpr’ []() consteval { \ ^~~~~~~~~ prog.cpp:80:11: note: in expansion of macro ‘a4z_file_name’ return a4z_file_name().size(); ^~~~~~~~~~~~~ prog.cpp:80:25: error: expected primary-expression before ‘)’ token return a4z_file_name().size(); ^
Standard output is empty