Skip to content

Commit 52cfebb

Browse files
committed
static_string: allow concatenation with dynamic strings
Allow static_string/array_string to concatenate with std::string (yielding std::string as a result).
1 parent f0579b5 commit 52cfebb

File tree

1 file changed

+46
-5
lines changed

1 file changed

+46
-5
lines changed

src/includes/static-string.h

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
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
//
@@ -25,6 +28,8 @@
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+
2833
namespace 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);
98103
template <typename T>
99104
struct static_length_t
100105
{
101-
constexpr static int len = T::length;
106+
// default: no member
102107
};
103108

104109
template <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
118127
template <int N>
119128
class 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

168183
template <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

Comments
 (0)