This code task a const char[]
and finds where is the last slash:
#include <array>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template< int PathIndex, int PathLength >
constexpr const int findlastslash(const char (&path)[PathLength])
{
constexpr const int end = PathLength - PathIndex;
return (PathIndex >= 0 && path[end] != '/' && path[end] != '\\')
? findlastslash< PathIndex - 1, PathLength >( path ) : ( end + 1 );
}
template< int PathLength >
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
return findlastslash< PathLength >( path );
}
int main(int argc, char const *argv[])
{
STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
}
But it does not work because the template recursion never stops:
$ g++ -o main.exe --std=c++14 test_debugger.cpp
test_debugger.cpp: In function ‘int main(int, const char**)’:
test_debugger.cpp:2:28: error: static assertion failed: startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 17
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
^
test_debugger.cpp:18:5: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 17 );
^~~~~~~~~~~~~
test_debugger.cpp: In instantiation of ‘constexpr const int findlastslash(const char (&)[PathLength]) [with int PathIndex = -880; int PathLength = 30]’:
test_debugger.cpp:8:114: recursively required from ‘constexpr const int findlastslash(const char (&)[PathLength]) [with int PathIndex = 19; int PathLength = 30]’
test_debugger.cpp:8:114: required from here
test_debugger.cpp:8:114: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
return (PathIndex >= 0 && path[end] != '/' && path[end] != '\\') ? findlastslash< PathIndex - 1, PathLength >( path ) : ( end + 1 );
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
compilation terminated.
I know can do this easily using const char *
, but I am interested in keeping using string "cppdebugger/test_debugger.cpp"
(const char[]
) as a array, i..e, without decaying into a const char *
pointer.
Update
Correction. A template specialization is like this (with < 1, PathLength >
:
template< int PathLength >
constexpr const int findlastslash< 1, PathLength >(const char (&path)[PathLength])
{
constexpr const int end = PathLength;
return ( path[end] != '/' && path[end] != '\\') ? 0 : 1;
}
Where the compiler correctly complains it:
$ g++ -o main.exe --std=c++14 test_debugger.cpp
test_debugger.cpp:18:82: error: non-class, non-variable partial specialization ‘findlastslash<1, PathLength>’ is not allowed
constexpr const int findlastslash< 1, PathLength >(const char (&path)[PathLength])
^
test_debugger.cpp: In function ‘int main(int, const char**)’:
test_debugger.cpp:2:28: error: static assertion failed: startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
^
test_debugger.cpp:26:5: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
^~~~~~~~~~~~~
test_debugger.cpp: In instantiation of ‘constexpr const int findlastslash(const char (&)[PathLength]) [with int PathIndex = -880; int PathLength = 30]’:
test_debugger.cpp:9:56: recursively required from ‘constexpr const int findlastslash(const char (&)[PathLength]) [with int PathIndex = 19; int PathLength = 30]’
test_debugger.cpp:9:56: required from here
test_debugger.cpp:9:56: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
? findlastslash< PathIndex - 1, PathLength >( path ) : ( end + 1 );
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
compilation terminated.
Related questions: