1+ #ifndef STATIC_STRING_H
2+ #define STATIC_STRING_H 1
3+
14// This is a minimal compile-time string handling library (currently just handling concatenation)
25// which owes much to Andrzej Krzemieński, and his blog post:
36//
2528// If they are constructed as locals, the compiler may reconstruct the object each time the
2629// function is called (i.e. it will allocate stack and copy the constant string result into it).
2730
31+ #include < string>
32+
2833namespace cts {
2934
3035// A static string, designed as a wrapper around string literals:
@@ -98,7 +103,7 @@ constexpr char joined_index(const S1 &s1, const S2 &s2, int i);
98103template <typename T>
99104struct static_length_t
100105{
101- constexpr static int len = T::length;
106+ // default: no member
102107};
103108
104109template <int N>
@@ -107,13 +112,17 @@ struct static_length_t<char [N]>
107112 constexpr static int len = N - 1 ;
108113};
109114
110- template <typename T>
111- constexpr int static_length ()
115+ template <int N>
116+ struct static_length_t <static_string<N>>
117+ {
118+ constexpr static int len = N;
119+ };
120+
121+ template <typename T> constexpr decltype (static_length_t <T>::len) static_length()
112122{
113123 return static_length_t <T>::len;
114124}
115125
116-
117126// A compile-time string
118127template <int N>
119128class array_string
@@ -162,11 +171,17 @@ constexpr char joined_index(const S1 &s1, const S2 &s2, int i)
162171 return (i < S1::length) ? s1[i] : s2[i - S1::length];
163172}
164173
174+ template <int N>
175+ struct static_length_t <array_string<N>>
176+ {
177+ constexpr static int len = N;
178+ };
179+
165180// Allow concatenating array_string and static_string with any compile-time constant string
166181// (including character string literal):
167182
168183template <int N, typename S2> constexpr
169- array_string<N+static_length <S2>() > operator+(const array_string<N> &s1, const S2 &s2)
184+ array_string<N+static_length_t <S2>::len > operator +(const array_string<N> &s1, const S2 &s2)
170185{
171186 return array_string<N+static_length<S2>()>(s1, s2);
172187}
@@ -177,5 +192,31 @@ array_string<N+static_length<S2>()> operator+(const static_string<N> &s1, const
177192 return array_string<N+static_length<S2>()>(s1, s2);
178193}
179194
195+ // Allow concatenating array_string/static_string with a dynamic string:
196+ template <int N>
197+ std::string operator +(const static_string<N> &s1, const std::string &s2)
198+ {
199+ return s1.c_str () + s2;
200+ }
201+
202+ template <int N>
203+ std::string operator +(const array_string<N> &s1, const std::string &s2)
204+ {
205+ return s1.c_str () + s2;
206+ }
207+
208+ template <int N>
209+ std::string operator +(const std::string &s2, const static_string<N> &s1)
210+ {
211+ return s2 + s1.c_str ();
212+ }
213+
214+ template <int N>
215+ std::string operator +(const std::string &s2, const array_string<N> &s1)
216+ {
217+ return s2 + s1.c_str ();
218+ }
180219
181220} // end "cts" namespace
221+
222+ #endif
0 commit comments