18#ifndef STRING_CONSTANT_H
19#define STRING_CONSTANT_H
29namespace presage::smartspectra::test{
34template <std::
size_t Length, std::
size_t Index,
typename Left,
typename Right>
35constexpr auto CompareCharacters(
const Left& lhs,
const Right& rhs ) ->
typename std::enable_if<Index != Length, bool>::type
37return lhs[Index] == rhs[Index] ? CompareCharacters<Length, Index + 1>( lhs, rhs ) : false;
41template <std::size_t Length, std::size_t Index, typename Left, typename Right, typename std::enable_if<Index == Length, bool>::type = 0>
42constexpr bool CompareCharacters(
const Left& lhs,
const Right& rhs )
53 static_assert( std::is_void<T>::value,
"Unsupported type for length_of" );
55 static constexpr std::size_t value = 1;
58template <std::
size_t N>
61 static constexpr std::size_t value = N - 1;
64template <std::
size_t N>
67 static constexpr std::size_t value = N - 1;
70template <std::
size_t N>
73 static constexpr std::size_t value = N - 1;
84template <std::
size_t N>
90 template <
typename... Characters>
91 constexpr StringConstant( Characters... characters )
92 : m_value{ characters...,
'\0' }
97 template <std::size_t... Indexes>
98 constexpr StringConstant(
const StringConstant<N>& rhs, std::index_sequence<Indexes...> dummy = StringConstant::g_indexes )
99 : m_value{ rhs[Indexes]...,
'\0' }
103 template <std::size_t X, std::size_t... Indexes>
104 constexpr StringConstant(
const StringConstant<X>& rhs, std::index_sequence<Indexes...> dummy )
105 : m_value{ rhs[Indexes]...,
'\0' }
109 template <std::size_t... Indexes>
110 constexpr StringConstant(
const char(&value)[N + 1], std::index_sequence<Indexes...> dummy )
111 : StringConstant( value[Indexes]... )
115 constexpr StringConstant(
const char(&value)[N + 1] )
116 : StringConstant( value, std::make_index_sequence<N>{} )
121 constexpr char operator[](
const std::size_t index )
const
123 return index < N ? m_value[index] :
throw std::out_of_range(
"Index out of range");
126 constexpr const char* Get( )
const {
return m_value; }
127 constexpr std::size_t Length( )
const {
return N; }
129 std::string ToString( )
const {
return std::string( m_value ); }
132 const char m_value[N + 1];
134 static constexpr auto g_indexes =
typename std::make_index_sequence<N>{};
138template <std::
size_t N>
141 static constexpr std::size_t value = N;
144template <std::
size_t N>
147 static constexpr std::size_t value = N;
150template <std::
size_t N>
153 static constexpr std::size_t value = N;
161 static constexpr bool value =
false;
164template <std::
size_t N>
167 static constexpr bool value =
true;
170template <std::
size_t N>
173 static constexpr bool value =
true;
176template <std::
size_t N>
179 static constexpr bool value =
true;
182template <std::
size_t N>
185 static constexpr bool value =
true;
192template <
typename Left,
typename Right, std::size_t... IndexesLeft, std::size_t... IndexesRight>
193constexpr StringConstant<
sizeof...(IndexesLeft) +
sizeof...(IndexesRight)> ConcatStrings(
const Left& lhs,
const Right& rhs, std::index_sequence<IndexesLeft...> dummy1, std::index_sequence<IndexesRight...> dummy2 )
195 return StringConstant<
sizeof...(IndexesLeft) +
sizeof...(IndexesRight)>( lhs[IndexesLeft]..., rhs[IndexesRight]... );
199template <
typename Left,
typename Right>
200constexpr StringConstant<length_of<Left>::value + length_of<Right>::value> ConcatStrings(
const Left& lhs,
const Right& rhs )
202 return ConcatStrings( lhs, rhs,
typename std::make_index_sequence<length_of<
decltype(lhs)>::value>{},
typename std::make_index_sequence<length_of<
decltype(rhs)>::value>{} );
209template <std::
size_t N,
typename Right>
212 return ConcatStrings( lhs, rhs );
215template <
typename Left, std::
size_t N>
218 return ConcatStrings( lhs, rhs );
221template <std::
size_t X, std::
size_t Y>
224 return ConcatStrings( lhs, rhs );
228template <std::
size_t N,
typename Right>
229constexpr auto operator==(
const StringConstant<N>& lhs,
const Right& rhs ) ->
typename std::enable_if<N == length_of<Right>::value,
bool>::type
231return CompareCharacters<N, 0>( lhs, rhs );
234template <
typename Left, std::
size_t N>
235constexpr auto operator==(
const Left& lhs,
const StringConstant<N>& rhs ) ->
typename std::enable_if<length_of<Left>::value == N,
bool>::type
237return CompareCharacters<N, 0>( lhs, rhs );
240template <std::
size_t X, std::
size_t Y>
243return CompareCharacters<X, 0>( lhs, rhs );
247template <std::size_t N, typename Right, typename std::enable_if<N != length_of<Right>::value,
bool>::type = 0>
254template <typename Left, std::size_t N, typename std::enable_if<length_of<Left>::value != N,
bool>::type = 0>
261template <std::size_t X, std::size_t Y, typename std::enable_if<X != Y, bool>::type = 0>
268template <std::size_t N, std::size_t... Indexes>
269constexpr auto StringFactory(
const char(&value)[N], std::index_sequence<Indexes...> dummy )
277template <std::
size_t N>
278constexpr auto StringFactory(
const char(&value)[N] )
280 return StringFactory( value,
typename std::make_index_sequence<N - 1>{} );
Definition compile_time_string_concatenation.hpp:86
Definition compile_time_string_concatenation.hpp:160
Definition compile_time_string_concatenation.hpp:52