fork download
  1. // https://a...content-available-to-author-only...b.io/blog/2023/11/04/Compiletime-string-literals-processing.html
  2. #include <cstddef>
  3. #include <limits>
  4. namespace a4z {
  5.  
  6. constexpr std::size_t cstr_len(const char* str) {
  7. std::size_t len = 0;
  8. while (*(str + len) != '\0') {
  9. ++len;
  10. }
  11. return len;
  12. }
  13.  
  14. constexpr auto npos = std::numeric_limits<std::size_t>::max();
  15.  
  16. template <std::size_t N>
  17. constexpr std::size_t find_nth_r_occurrence(const char (&str)[N],
  18. char ch,
  19. std::size_t n) {
  20. std::size_t count = 0;
  21. for (std::size_t i = N; i-- > 0;) {
  22. if (str[i] == ch) {
  23. ++count;
  24. if (count == n) {
  25. return i;
  26. }
  27. }
  28. }
  29. return npos; // Not found
  30. }
  31.  
  32. constexpr bool on_windows() {
  33. #ifdef _WIN32
  34. return true;
  35. #else
  36. return false;
  37. #endif
  38. }
  39.  
  40. template <std::size_t N>
  41. struct astr {
  42. char data[N] = {0};
  43.  
  44. constexpr astr(const char (&arr)[N]) noexcept {
  45. for (std::size_t i = 0; i < N; ++i) {
  46. data[i] = *(arr + i);
  47. }
  48. }
  49.  
  50. constexpr const char* c_str() const noexcept { return &data[0]; }
  51.  
  52. constexpr std::size_t size() const noexcept { return N - 1; }
  53. };
  54.  
  55. constexpr char slash = on_windows() ? '\\' : '/';
  56.  
  57. #define a4z_file_name \
  58.   []() consteval { \
  59.   constexpr const char* str = __FILE__; \
  60.   constexpr auto len = a4z::cstr_len(str); \
  61.   constexpr auto start{a4z::find_nth_r_occurrence(__FILE__, a4z::slash, 2)}; \
  62.   static_assert(start != a4z::npos); \
  63.   constexpr std::size_t astr_len = len - start; \
  64.   char data[astr_len]; \
  65.   for (std::size_t i = 0; i < astr_len; ++i) { \
  66.   data[i] = *(str + start + i + 1); \
  67.   } \
  68.   return a4z::astr<astr_len>{data}; \
  69.   }
  70.  
  71. } // namespace a4z
  72.  
  73. // -- Application part
  74.  
  75. #include <cstdio>
  76.  
  77. int main() {
  78.  
  79. fprintf(stdout, "%s\n", a4z_file_name().c_str());
  80. return a4z_file_name().size();
  81. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
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();
                         ^
stdout
Standard output is empty