I\'m trying to make a constexpr function that will concatenate an arbitrary number of char arrays by working from the following answer by Xeo, which concatenates two char ar
template
using size=std::integral_constant;
template
constexpr size length( T const(&)[N] ) { return {}; }
template
constexpr size length( std::array const& ) { return {}; }
template
using length_t = decltype(length(std::declval()));
constexpr size_t sum_string_sizes() { return 0; }
template
constexpr size_t sum_string_sizes( size_t i, Ts... ts ) {
return (i?i-1:0) + sum_sizes(ts...);
}
then
template
template
constexpr auto
concat(const char(&a1)[N1], const char(&a2)[N2], const Us&... xs)
-> std::array::value... )+1 >
{
return concat(a1, concat(a2, xs...));
}
which gets rid of the recursion-in-decltype.
Here is a full example using the above approach:
template
using size=std::integral_constant;
template
constexpr size length( T const(&)[N] ) { return {}; }
template
constexpr size length( std::array const& ) { return {}; }
template
using length_t = decltype(length(std::declval()));
constexpr size_t string_size() { return 0; }
template
constexpr size_t string_size( size_t i, Ts... ts ) {
return (i?i-1:0) + string_size(ts...);
}
template
using string_length=size< string_size( length_t{}... )>;
template
using combined_string = std::array{}+1>;
template
constexpr const combined_string
concat_impl( Lhs const& lhs, Rhs const& rhs, seq, seq)
{
// the '\0' adds to symmetry:
return {{ lhs[I1]..., rhs[I2]..., '\0' }};
}
template
constexpr const combined_string
concat(Lhs const& lhs, Rhs const& rhs)
{
return concat_impl(
lhs, rhs,
gen_seq{}>{},
gen_seq{}>{}
);
}
template
constexpr const combined_string
concat(T0 const&t0, T1 const&t1, Ts const&...ts)
{
return concat(t0, concat(t1, ts...));
}
template
constexpr const combined_string
concat(T const&t) {
return concat(t, "");
}
constexpr const combined_string<>
concat() {
return concat("");
}
live example