]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/string.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / hana / string.hpp
1 /*!
2 @file
3 Defines `boost::hana::string`.
4
5 @copyright Louis Dionne 2013-2017
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10 #ifndef BOOST_HANA_STRING_HPP
11 #define BOOST_HANA_STRING_HPP
12
13 #include <boost/hana/fwd/string.hpp>
14
15 #include <boost/hana/bool.hpp>
16 #include <boost/hana/concept/constant.hpp>
17 #include <boost/hana/config.hpp>
18 #include <boost/hana/core/make.hpp>
19 #include <boost/hana/detail/algorithm.hpp>
20 #include <boost/hana/detail/operators/adl.hpp>
21 #include <boost/hana/detail/operators/comparable.hpp>
22 #include <boost/hana/detail/operators/iterable.hpp>
23 #include <boost/hana/detail/operators/orderable.hpp>
24 #include <boost/hana/fwd/at.hpp>
25 #include <boost/hana/fwd/contains.hpp>
26 #include <boost/hana/fwd/core/tag_of.hpp>
27 #include <boost/hana/fwd/core/to.hpp>
28 #include <boost/hana/fwd/drop_front.hpp>
29 #include <boost/hana/fwd/equal.hpp>
30 #include <boost/hana/fwd/find.hpp>
31 #include <boost/hana/fwd/front.hpp>
32 #include <boost/hana/fwd/hash.hpp>
33 #include <boost/hana/fwd/is_empty.hpp>
34 #include <boost/hana/fwd/length.hpp>
35 #include <boost/hana/fwd/less.hpp>
36 #include <boost/hana/fwd/plus.hpp>
37 #include <boost/hana/fwd/unpack.hpp>
38 #include <boost/hana/fwd/zero.hpp>
39 #include <boost/hana/if.hpp>
40 #include <boost/hana/integral_constant.hpp>
41 #include <boost/hana/optional.hpp>
42 #include <boost/hana/type.hpp>
43
44 #include <utility>
45 #include <cstddef>
46 #include <type_traits>
47
48
49 BOOST_HANA_NAMESPACE_BEGIN
50 //////////////////////////////////////////////////////////////////////////
51 // string<>
52 //////////////////////////////////////////////////////////////////////////
53 //! @cond
54 namespace detail {
55 template <char ...s>
56 constexpr char const string_storage[sizeof...(s) + 1] = {s..., '\0'};
57 }
58
59 template <char ...s>
60 struct string
61 : detail::operators::adl<string<s...>>
62 , detail::iterable_operators<string<s...>>
63 {
64 static constexpr char const* c_str() {
65 return &detail::string_storage<s...>[0];
66 }
67 };
68 //! @endcond
69
70 template <char ...s>
71 struct tag_of<string<s...>> {
72 using type = string_tag;
73 };
74
75 //////////////////////////////////////////////////////////////////////////
76 // make<string_tag>
77 //////////////////////////////////////////////////////////////////////////
78 template <>
79 struct make_impl<string_tag> {
80 template <typename ...Chars>
81 static constexpr auto apply(Chars const& ...) {
82 return hana::string<hana::value<Chars>()...>{};
83 }
84 };
85
86 //////////////////////////////////////////////////////////////////////////
87 // BOOST_HANA_STRING
88 //////////////////////////////////////////////////////////////////////////
89 namespace string_detail {
90 template <typename S, std::size_t ...N>
91 constexpr string<S::get()[N]...>
92 prepare_impl(S, std::index_sequence<N...>)
93 { return {}; }
94
95 template <typename S>
96 constexpr decltype(auto) prepare(S s) {
97 return prepare_impl(s,
98 std::make_index_sequence<sizeof(S::get()) - 1>{});
99 }
100 }
101
102 #define BOOST_HANA_STRING(s) \
103 (::boost::hana::string_detail::prepare([]{ \
104 struct tmp { \
105 static constexpr decltype(auto) get() { return s; } \
106 }; \
107 return tmp{}; \
108 }())) \
109 /**/
110
111 #ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
112 //////////////////////////////////////////////////////////////////////////
113 // _s user-defined literal
114 //////////////////////////////////////////////////////////////////////////
115 namespace literals {
116 template <typename CharT, CharT ...s>
117 constexpr auto operator"" _s() {
118 static_assert(std::is_same<CharT, char>::value,
119 "hana::string: Only narrow string literals are supported with "
120 "the _s string literal right now. See https://goo.gl/fBbKD7 "
121 "if you need support for fancier types of compile-time strings.");
122 return hana::string_c<s...>;
123 }
124 }
125 #endif
126
127 //////////////////////////////////////////////////////////////////////////
128 // Operators
129 //////////////////////////////////////////////////////////////////////////
130 namespace detail {
131 template <>
132 struct comparable_operators<string_tag> {
133 static constexpr bool value = true;
134 };
135 template <>
136 struct orderable_operators<string_tag> {
137 static constexpr bool value = true;
138 };
139 }
140
141 //////////////////////////////////////////////////////////////////////////
142 // to<char const*>
143 //////////////////////////////////////////////////////////////////////////
144 template <>
145 struct to_impl<char const*, string_tag> {
146 template <char ...c>
147 static constexpr char const* apply(string<c...> const&)
148 { return string<c...>::c_str(); }
149 };
150
151 //////////////////////////////////////////////////////////////////////////
152 // to<string_tag>
153 //////////////////////////////////////////////////////////////////////////
154 namespace detail {
155 constexpr std::size_t cx_strlen(char const* s) {
156 std::size_t n = 0u;
157 while (*s != '\0')
158 ++s, ++n;
159 return n;
160 }
161
162 template <typename S, std::size_t ...I>
163 constexpr hana::string<hana::value<S>()[I]...> expand(std::index_sequence<I...>)
164 { return {}; }
165 }
166
167 template <typename IC>
168 struct to_impl<hana::string_tag, IC, hana::when<
169 hana::Constant<IC>::value &&
170 std::is_convertible<typename IC::value_type, char const*>::value
171 >> {
172 template <typename S>
173 static constexpr auto apply(S const&) {
174 constexpr char const* s = hana::value<S>();
175 constexpr std::size_t len = detail::cx_strlen(s);
176 return detail::expand<S>(std::make_index_sequence<len>{});
177 }
178 };
179
180 //////////////////////////////////////////////////////////////////////////
181 // Comparable
182 //////////////////////////////////////////////////////////////////////////
183 template <>
184 struct equal_impl<string_tag, string_tag> {
185 template <typename S>
186 static constexpr auto apply(S const&, S const&)
187 { return hana::true_c; }
188
189 template <typename S1, typename S2>
190 static constexpr auto apply(S1 const&, S2 const&)
191 { return hana::false_c; }
192 };
193
194 //////////////////////////////////////////////////////////////////////////
195 // Orderable
196 //////////////////////////////////////////////////////////////////////////
197 template <>
198 struct less_impl<string_tag, string_tag> {
199 template <char ...s1, char ...s2>
200 static constexpr auto
201 apply(string<s1...> const&, string<s2...> const&) {
202 // We put a '\0' at the end only to avoid empty arrays.
203 constexpr char const c_str1[] = {s1..., '\0'};
204 constexpr char const c_str2[] = {s2..., '\0'};
205 return hana::bool_c<detail::lexicographical_compare(
206 c_str1, c_str1 + sizeof...(s1),
207 c_str2, c_str2 + sizeof...(s2)
208 )>;
209 }
210 };
211
212 //////////////////////////////////////////////////////////////////////////
213 // Monoid
214 //////////////////////////////////////////////////////////////////////////
215 template <>
216 struct plus_impl<string_tag, string_tag> {
217 template <char ...s1, char ...s2>
218 static constexpr auto
219 apply(string<s1...> const&, string<s2...> const&) {
220 return string<s1..., s2...>{};
221 }
222 };
223
224 template <>
225 struct zero_impl<string_tag> {
226 static constexpr auto apply() {
227 return string<>{};
228 }
229 };
230
231 template <char ...s1, char ...s2>
232 constexpr auto operator+(string<s1...> const&, string<s2...> const&) {
233 return hana::string<s1..., s2...>{};
234 }
235
236 //////////////////////////////////////////////////////////////////////////
237 // Foldable
238 //////////////////////////////////////////////////////////////////////////
239 template <>
240 struct unpack_impl<string_tag> {
241 template <char ...s, typename F>
242 static constexpr decltype(auto) apply(string<s...> const&, F&& f)
243 { return static_cast<F&&>(f)(char_<s>{}...); }
244 };
245
246 template <>
247 struct length_impl<string_tag> {
248 template <char ...s>
249 static constexpr auto apply(string<s...> const&)
250 { return hana::size_c<sizeof...(s)>; }
251 };
252
253 //////////////////////////////////////////////////////////////////////////
254 // Iterable
255 //////////////////////////////////////////////////////////////////////////
256 template <>
257 struct front_impl<string_tag> {
258 template <char x, char ...xs>
259 static constexpr auto apply(string<x, xs...> const&)
260 { return hana::char_c<x>; }
261 };
262
263 template <>
264 struct drop_front_impl<string_tag> {
265 template <std::size_t N, char ...xs, std::size_t ...i>
266 static constexpr auto helper(string<xs...> const&, std::index_sequence<i...>) {
267 constexpr char s[] = {xs...};
268 return hana::string_c<s[i + N]...>;
269 }
270
271 template <char ...xs, typename N>
272 static constexpr auto apply(string<xs...> const& s, N const&) {
273 return helper<N::value>(s, std::make_index_sequence<
274 (N::value < sizeof...(xs)) ? sizeof...(xs) - N::value : 0
275 >{});
276 }
277
278 template <typename N>
279 static constexpr auto apply(string<> const& s, N const&)
280 { return s; }
281 };
282
283 template <>
284 struct is_empty_impl<string_tag> {
285 template <char ...s>
286 static constexpr auto apply(string<s...> const&)
287 { return hana::bool_c<sizeof...(s) == 0>; }
288 };
289
290 template <>
291 struct at_impl<string_tag> {
292 template <char ...s, typename N>
293 static constexpr auto apply(string<s...> const&, N const&) {
294 // We put a '\0' at the end to avoid an empty array.
295 constexpr char characters[] = {s..., '\0'};
296 constexpr auto n = N::value;
297 return hana::char_c<characters[n]>;
298 }
299 };
300
301 //////////////////////////////////////////////////////////////////////////
302 // Searchable
303 //////////////////////////////////////////////////////////////////////////
304 template <>
305 struct contains_impl<string_tag> {
306 template <char ...s, typename C>
307 static constexpr auto
308 helper(string<s...> const&, C const&, hana::true_) {
309 constexpr char const characters[] = {s..., '\0'};
310 constexpr char c = hana::value<C>();
311 return hana::bool_c<
312 detail::find(characters, characters + sizeof...(s), c)
313 != characters + sizeof...(s)
314 >;
315 }
316
317 template <typename S, typename C>
318 static constexpr auto helper(S const&, C const&, hana::false_)
319 { return hana::false_c; }
320
321 template <typename S, typename C>
322 static constexpr auto apply(S const& s, C const& c)
323 { return helper(s, c, hana::bool_c<hana::Constant<C>::value>); }
324 };
325
326 template <>
327 struct find_impl<string_tag> {
328 template <char ...s, typename Char>
329 static constexpr auto apply(string<s...> const& str, Char const& c) {
330 return hana::if_(contains_impl<string_tag>::apply(str, c),
331 hana::just(c),
332 hana::nothing
333 );
334 }
335 };
336
337 //////////////////////////////////////////////////////////////////////////
338 // Hashable
339 //////////////////////////////////////////////////////////////////////////
340 template <>
341 struct hash_impl<string_tag> {
342 template <typename String>
343 static constexpr auto apply(String const&) {
344 return hana::type_c<String>;
345 }
346 };
347 BOOST_HANA_NAMESPACE_END
348
349 #endif // !BOOST_HANA_STRING_HPP