, . , , , , .
constexpr, . , .
;
( GCC-4.7 MacPorts 10- PowerPC Mac.)
(++ 11) :
template < typename Destination, typename ...Source >
constexpr
auto initialize( Source&& ...args ) -> Destination
{ return Destination{ce_forward<Source>(args)...}; }
( ce_forward std::forward, , constexpr.)
( Destination , , , std::initialization_list, , , .)
, . :
template < typename Destination, typename Source, typename Size1, typename Size2, typename ...Args >
constexpr
auto fill_from_array( Source&& source, Size1 index_begin, Size2 index_end, Args&& ...args )
-> Destination
{
return ( index_begin < index_end )
? fill_from_array<Destination>( ce_forward<Source>(source), index_begin + 1, index_end, ce_forward<Args>(args)..., ce_forward<Source>(source)[index_begin] )
: initialize<Destination>( ce_forward<Args>(args)... );
}
( , .)
, - . , - . (, , , .)
.. , :
-, : - I. , initialize ; , , .
- :
#include <cstddef>
template < std::size_t ...Indices >
struct index_tuple
{ using next = index_tuple<Indices..., sizeof...(Indices)>; };
template < std::size_t Size >
struct build_indices
{ using type = typename build_indices<Size - 1>::type::next; };
template < >
struct build_indices< 0 >
{ using type = index_tuple<>; };
index_tuple - , , build_indices index_tuple :
index_tuple<>
index_tuple<0>
index_tuple<0, 1>
index_tuple<0, 1, 2>
...
index_tuple :
template < std::size_t Size >
constexpr
auto make_indices() noexcept -> typename build_indices<Size>::type
{ return {}; }
index_tuple :
#include <array>
template < std::size_t N, std::size_t M, std::size_t ...Indices >
constexpr
std::array<char, N + M - 1u>
fuse_strings_impl( const char (&f)[N], const char (&s)[M], index_tuple<Indices...> );
, . "std:: size_t... Indices" . , "0, 1,..., X". , . :
template < std::size_t N, std::size_t M, std::size_t ...Indices >
constexpr
std::array<char, N + M - 1u>
fuse_strings_impl( const char (&f)[N], const char (&s)[M], index_tuple<Indices...> )
{ return {{ get_strchr<Indices>(f, s)... }}; }
array get_strchr<0>(f,s), - get_strchr<1>(f,s) .. , "_impl", index_tuple , :
template < std::size_t N, std::size_t M >
constexpr
std::array<char, N + M - 1u>
fuse_strings( const char (&f)[N], const char (&s)[M] )
{ return fuse_strings_impl(f, s, make_indices<N + M - 2>()); }
:
#include <iostream>
#include <ostream>
int main()
{
using std::cout;
using std::endl;
constexpr auto initialize_test = initialize<std::array<char, 15>>( 'G',
'o', 'o', 'd', 'b', 'y', 'e', ',', ' ', 'm', 'o', 'o', 'n', '!', '\0' );
constexpr char hello_str[] = "Hello ";
constexpr char world_str[] = "world!";
constexpr auto hw = fuse_strings( hello_str, world_str );
cout << initialize_test.data() << endl;
cout << hw.data() << endl;
}
.
const(expr) char str[] = "Whatever"; [] *, , () .- ,
std::array . , . std::array , , , . std::array , . - .
char, '\0'. NUL , . 1 2 . ( char) , .
, get_strchr:
template < std::size_t N >
constexpr
char ce_strchr( std::size_t i, const char (&s)[N] )
{
static_assert( N, "empty string" );
return (i < ( N - 1 )) ? s[i] : throw "too big";
}
template < std::size_t N, std::size_t M, std::size_t ...L >
constexpr
char ce_strchr( std::size_t i, const char (&f)[N], const char (&s)[M], const char (&...t)[L] )
{
static_assert( N, "empty string" );
return (i < ( N - 1 )) ? f[i] : ce_strchr(i + 1 - N, s, t...);
}
template < std::size_t I, std::size_t N, std::size_t ...M >
constexpr
char get_strchr( const char (&f)[N], const char (&...s)[M] )
{ return ce_strchr(I, f, s...); }
(, .)