#include<array>
#include<cstddef>
#include<utility>
using namespace std;
template < size_t N> using string_literal_t = char [ N] ;
template < class T> struct StrSize; ///< metafunction to get the size of string literal alikes
/// specialize StrSize for string literals
template < size_t N>
struct StrSize < string_literal_t< N>> { static constexpr size_t value = N- 1 ; } ;
/// template variable, just for convenience
template < class T>
constexpr size_t str_size = StrSize< T> :: value ;
/// now do the same but with constexpr function
template < class T>
constexpr auto strsize( const T& ) noexcept- > decltype( str_size< T> ) {
return str_size< T> ;
}
template < class S, size_t ... Is >
constexpr auto test_helper( const S& s, index_sequence< Is...> ) noexcept- > array< char , str_size< S>> {
return { s[ Is] ...} ;
}
template < class S>
constexpr auto test( const S& s) noexcept- > decltype( auto ) {
// return test_helper(s, make_index_sequence<str_size<S>>{}); // this work in both clang and gcc
return test_helper( s, make_index_sequence< strsize( s) > { } ) ; // this works only in gcc
}
auto main( int argc, char * argv[ ] ) - > int {
static_assert( strsize( "qwe" ) == 3 , "" ) ;
static_assert( noexcept( test( "qwe" ) ) == true , "" ) ;
return 0 ;
}
I2luY2x1ZGU8YXJyYXk+CiNpbmNsdWRlPGNzdGRkZWY+CiNpbmNsdWRlPHV0aWxpdHk+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8c2l6ZV90IE4+IHVzaW5nIHN0cmluZ19saXRlcmFsX3QgPSBjaGFyW05dOwoKdGVtcGxhdGU8Y2xhc3MgVD4gc3RydWN0IFN0clNpemU7IC8vLzwgbWV0YWZ1bmN0aW9uIHRvIGdldCB0aGUgc2l6ZSBvZiBzdHJpbmcgbGl0ZXJhbCBhbGlrZXMgCgovLy8gc3BlY2lhbGl6ZSBTdHJTaXplIGZvciBzdHJpbmcgbGl0ZXJhbHMKdGVtcGxhdGU8c2l6ZV90IE4+CnN0cnVjdCBTdHJTaXplIDxzdHJpbmdfbGl0ZXJhbF90PE4+Pnsgc3RhdGljIGNvbnN0ZXhwciBzaXplX3QgdmFsdWUgPSBOLTE7IH07CgovLy8gdGVtcGxhdGUgdmFyaWFibGUsIGp1c3QgZm9yIGNvbnZlbmllbmNlCnRlbXBsYXRlIDxjbGFzcyBUPgpjb25zdGV4cHIgc2l6ZV90IHN0cl9zaXplID0gU3RyU2l6ZTxUPjo6dmFsdWU7CgovLy8gbm93IGRvIHRoZSBzYW1lIGJ1dCB3aXRoIGNvbnN0ZXhwciBmdW5jdGlvbgp0ZW1wbGF0ZTxjbGFzcyBUPgpjb25zdGV4cHIgYXV0byBzdHJzaXplKGNvbnN0IFQmKSBub2V4Y2VwdC0+IGRlY2x0eXBlKHN0cl9zaXplPFQ+KSB7CiAgIHJldHVybiBzdHJfc2l6ZTxUPjsKfQoKdGVtcGxhdGU8Y2xhc3MgUywgc2l6ZV90Li4uIElzPgpjb25zdGV4cHIgYXV0byB0ZXN0X2hlbHBlcihjb25zdCBTJiBzLCBpbmRleF9zZXF1ZW5jZTxJcy4uLj4pIG5vZXhjZXB0LT4gYXJyYXk8Y2hhciwgc3RyX3NpemU8Uz4+IHsKICAgcmV0dXJuIHtzW0lzXS4uLn07Cn0KCnRlbXBsYXRlPGNsYXNzIFM+CmNvbnN0ZXhwciBhdXRvIHRlc3QoY29uc3QgUyYgcykgbm9leGNlcHQtPiBkZWNsdHlwZShhdXRvKSB7Ci8vIHJldHVybiB0ZXN0X2hlbHBlcihzLCBtYWtlX2luZGV4X3NlcXVlbmNlPHN0cl9zaXplPFM+Pnt9KTsgLy8gdGhpcyB3b3JrIGluIGJvdGggY2xhbmcgYW5kIGdjYwogICByZXR1cm4gdGVzdF9oZWxwZXIocywgbWFrZV9pbmRleF9zZXF1ZW5jZTxzdHJzaXplKHMpPnt9KTsgIC8vIHRoaXMgd29ya3Mgb25seSBpbiBnY2MKfQoKYXV0byBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pLT4gaW50IHsKICAgc3RhdGljX2Fzc2VydChzdHJzaXplKCJxd2UiKSA9PSAzLCAiIik7CiAgIHN0YXRpY19hc3NlcnQobm9leGNlcHQodGVzdCgicXdlIikpID09IHRydWUsICIiKTsKICAgCiAgIHJldHVybiAwOwp9Cg==
compilation info
prog.cpp:33:54: error: non-type template argument is not a constant expression
return test_helper(s, make_index_sequence<strsize(s)>{}); // this works only in gcc
^
prog.cpp:38:27: note: in instantiation of function template specialization 'test<char [4]>' requested here
static_assert(noexcept(test("qwe")) == true, "");
^
1 error generated.
stdout