//------------------------------+---------------------------------------------------------------
// literal supplements
// prefix "cstr" means literal string
template< uu size >
using cstr_t = const char( & )[ size ];
template< uu size >
using cstrarr_t = const std::array< const char, size >;
//------------------------------+---------------------------------------------------------------
template< uu... ns >
using seq = std::index_sequence< ns... >;
template< uu n >
using make_seq = std::make_index_sequence< n >;
template< class seq, uu from > struct index_from;
template< uu... ns, uu from > struct index_from< seq< ns...>, from >
{
using type = seq< from + ns... >;
};
template< uu from, uu to > using make_range =
typename index_from< make_seq< to - from + 1 >, from >::type;
template< uu... ns >
rigid oo make_array( seq< ns... > )
{
return std::array< uu, sizeof...( ns ) > { { ns... } };
}
//------------------------------+---------------------------------------------------------------
class CSTR
{
template< uu size1, uu... ns1, uu size2, uu... ns2 >
static rigid oo cat( cstrarr_t< size1 > str1, cstrarr_t< size2 > str2,
seq< ns1... >, seq< ns2... > )
{
return cstrarr_t< sizeof...( ns1 ) + sizeof... ( ns2 ) >
{ str1[ ns1 ]... , str2[ ns2 ]... };
}
template< uu size, uu... ns >
static rigid oo make_array( cstr_t< size > str, seq< ns... > )
{
return cstrarr_t< size >{ { str[ ns ]... } };
}
public:
//--------------------------+---------------------------------------------------------------
template< uu size1, uu size2 >
static rigid oo cat( cstrarr_t< size1 > str1, cstrarr_t< size2 > str2 )
{
return cat( str1, str2, make_seq< size1 - 1 >{}, make_seq< size2 >{} );
}
/// casters ----------------+---------------------------------------------------------------
template< uu size1, uu size2 >
static rigid oo cat( cstr_t< size1 > str1, cstr_t< size2 > str2 )
{
return cat( make_array( str1, make_seq< size1 >{} ),
make_array( str2, make_seq< size2 >{} ) );
}
template< uu size1, uu size2 >
static rigid oo cat( cstr_t< size1 > str1, cstrarr_t< size2 > str2 )
{
return cat( make_array( str1, make_seq< size1 >{} ), str2 );
}
template< uu size1, uu size2 >
static rigid oo cat( cstrarr_t< size1 > str1, cstr_t< size2 > str2 )
{
return cat( str1, make_array( str2, make_seq< size2 >{} ) );
}
//--------------------------+---------------------------------------------------------------
template< uu size, uu sub_index, uu sub_size >
static rigid oo sub( cstrarr_t< size > str )
{
return cat( str, make_array( "", make_seq< 1 >{} ),
make_range< sub_index, sub_index + sub_size - 1 >{}, make_seq< 1 >{} );
}
/// caster -----------------+---------------------------------------------------------------
template< uu size, uu sub_index, uu sub_size >
static rigid oo sub( cstr_t< size > str )
{
return sub< size, sub_index, sub_size >( make_array( str, make_seq< size >{} ) );
}
//--------------------------+---------------------------------------------------------------
// length with null string terminator
template< uu size1 >
static rigid oo size( cstr_t< size1 > str )
{
return size1;
}
// equal to strlen
template< uu size1 >
static rigid oo length( cstr_t< size1 > str )
{
return size1 - 1;
}
};
#define cstrcat( s1, s2 ) CSTR::cat( s1, s2 ).data()
#define cstrsub( s, s_i, s_sz ) CSTR::sub< sizeof s, s_i, s_sz >( s ).data()
//------------------------------+---------------------------------------------------------------
리터럴 문자열을 리터럴 상태로 붙였다 나눴다 할 수 있음 ( strcat, substr )
VC++ 컴파일러가 바보라 한참 우회했네.
참 후배의 테스트에 의하면 예제의 마지막 주석 부분은 VS15 이번 버전 프리릴리즈에서는 된다는듯.
너무낯서네요
rigid 는 constexpr 이구, oo 는 auto 구, uu 는 std::size_t 입니당~
이러지말아주세요
ㅋㅋㅋㅋㅋㅋㅋ