]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | @file | |
3 | Forward declares `boost::hana::string`. | |
4 | ||
b32b8144 | 5 | @copyright Louis Dionne 2013-2017 |
7c673cae FG |
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_FWD_STRING_HPP | |
11 | #define BOOST_HANA_FWD_STRING_HPP | |
12 | ||
13 | #include <boost/hana/config.hpp> | |
14 | #include <boost/hana/fwd/core/make.hpp> | |
11fdf7f2 | 15 | #include <boost/hana/fwd/core/to.hpp> |
7c673cae FG |
16 | |
17 | ||
18 | BOOST_HANA_NAMESPACE_BEGIN | |
19 | #ifdef BOOST_HANA_DOXYGEN_INVOKED | |
20 | //! @ingroup group-datatypes | |
21 | //! Compile-time string. | |
22 | //! | |
23 | //! Conceptually, a `hana::string` is like a tuple holding | |
24 | //! `integral_constant`s of underlying type `char`. However, the | |
25 | //! interface of `hana::string` is not as rich as that of a tuple, | |
26 | //! because a string can only hold compile-time characters as opposed | |
27 | //! to any kind of object. | |
28 | //! | |
29 | //! Compile-time strings are used for simple purposes like being keys in a | |
30 | //! `hana::map` or tagging the members of a `Struct`. However, you might | |
31 | //! find that `hana::string` does not provide enough functionality to be | |
32 | //! used as a full-blown compile-time string implementation (e.g. regexp | |
33 | //! matching or substring finding). Indeed, providing a comprehensive | |
34 | //! string interface is a lot of job, and it is out of the scope of the | |
35 | //! library for the time being. | |
36 | //! | |
37 | //! | |
38 | //! @note | |
39 | //! The representation of `hana::string` is implementation-defined. | |
40 | //! In particular, one should not take for granted that the template | |
41 | //! parameters are `char`s. The proper way to access the contents of | |
b32b8144 FG |
42 | //! a `hana::string` as character constants is to use `hana::unpack`, |
43 | //! `.c_str()` or `hana::to<char const*>`, as documented below. | |
7c673cae FG |
44 | //! |
45 | //! | |
46 | //! Modeled concepts | |
47 | //! ---------------- | |
48 | //! For most purposes, a `hana::string` is functionally equivalent to a | |
49 | //! tuple holding `Constant`s of underlying type `char`. | |
50 | //! | |
51 | //! 1. `Comparable`\n | |
52 | //! Two strings are equal if and only if they have the same number of | |
53 | //! characters and characters at corresponding indices are equal. | |
54 | //! @include example/string/comparable.cpp | |
55 | //! | |
56 | //! 2. `Orderable`\n | |
57 | //! The total order implemented for `Orderable` is the usual | |
58 | //! lexicographical comparison of strings. | |
59 | //! @include example/string/orderable.cpp | |
60 | //! | |
b32b8144 FG |
61 | //! 3. `Monoid`\n |
62 | //! Strings form a monoid under concatenation, with the neutral element | |
63 | //! being the empty string. | |
64 | //! @include example/string/monoid.cpp | |
65 | //! | |
66 | //! 4. `Foldable`\n | |
7c673cae FG |
67 | //! Folding a string is equivalent to folding the sequence of its |
68 | //! characters. | |
69 | //! @include example/string/foldable.cpp | |
70 | //! | |
b32b8144 | 71 | //! 5. `Iterable`\n |
7c673cae FG |
72 | //! Iterating over a string is equivalent to iterating over the sequence |
73 | //! of its characters. Also note that `operator[]` can be used instead of | |
74 | //! the `at` function. | |
75 | //! @include example/string/iterable.cpp | |
76 | //! | |
b32b8144 | 77 | //! 6. `Searchable`\n |
7c673cae FG |
78 | //! Searching through a string is equivalent to searching through the |
79 | //! sequence of its characters. | |
80 | //! @include example/string/searchable.cpp | |
81 | //! | |
b32b8144 | 82 | //! 7. `Hashable`\n |
7c673cae FG |
83 | //! The hash of a compile-time string is a type uniquely representing |
84 | //! that string. | |
85 | //! @include example/string/hashable.cpp | |
86 | //! | |
87 | //! | |
88 | //! Conversion to `char const*` | |
89 | //! --------------------------- | |
90 | //! A `hana::string` can be converted to a `constexpr` null-delimited | |
b32b8144 FG |
91 | //! string of type `char const*` by using the `c_str()` method or |
92 | //! `hana::to<char const*>`. This makes it easy to turn a compile-time | |
93 | //! string into a runtime string. However, note that this conversion is | |
94 | //! not an embedding, because `char const*` does not model the same | |
95 | //! concepts as `hana::string` does. | |
7c673cae FG |
96 | //! @include example/string/to.cpp |
97 | //! | |
11fdf7f2 TL |
98 | //! Conversion from any Constant holding a `char const*` |
99 | //! ---------------------------------------------------- | |
100 | //! A `hana::string` can be created from any `Constant` whose underlying | |
101 | //! value is convertible to a `char const*` by using `hana::to`. The | |
102 | //! contents of the `char const*` are used to build the content of the | |
103 | //! `hana::string`. | |
104 | //! @include example/string/from_c_str.cpp | |
105 | //! | |
106 | //! Rationale for `hana::string` not being a `Constant` itself | |
107 | //! ---------------------------------------------------------- | |
108 | //! The underlying type held by a `hana::string` could be either `char const*` | |
109 | //! or some other constexpr-enabled string-like container. In the first case, | |
110 | //! `hana::string` can not be a `Constant` because the models of several | |
111 | //! concepts would not be respected by the underlying type, causing `value` | |
112 | //! not to be structure-preserving. Providing an underlying value of | |
113 | //! constexpr-enabled string-like container type like `std::string_view` | |
114 | //! would be great, but that's a bit complicated for the time being. | |
7c673cae FG |
115 | template <typename implementation_defined> |
116 | struct string { | |
b32b8144 FG |
117 | // Default-construct a `hana::string`; no-op since `hana::string` is stateless. |
118 | constexpr string() = default; | |
119 | ||
120 | // Copy-construct a `hana::string`; no-op since `hana::string` is stateless. | |
121 | constexpr string(string const&) = default; | |
122 | ||
7c673cae FG |
123 | //! Equivalent to `hana::equal` |
124 | template <typename X, typename Y> | |
125 | friend constexpr auto operator==(X&& x, Y&& y); | |
126 | ||
127 | //! Equivalent to `hana::not_equal` | |
128 | template <typename X, typename Y> | |
129 | friend constexpr auto operator!=(X&& x, Y&& y); | |
130 | ||
131 | //! Equivalent to `hana::less` | |
132 | template <typename X, typename Y> | |
133 | friend constexpr auto operator<(X&& x, Y&& y); | |
134 | ||
135 | //! Equivalent to `hana::greater` | |
136 | template <typename X, typename Y> | |
137 | friend constexpr auto operator>(X&& x, Y&& y); | |
138 | ||
139 | //! Equivalent to `hana::less_equal` | |
140 | template <typename X, typename Y> | |
141 | friend constexpr auto operator<=(X&& x, Y&& y); | |
142 | ||
143 | //! Equivalent to `hana::greater_equal` | |
144 | template <typename X, typename Y> | |
145 | friend constexpr auto operator>=(X&& x, Y&& y); | |
146 | ||
b32b8144 FG |
147 | //! Performs concatenation; equivalent to `hana::plus` |
148 | template <typename X, typename Y> | |
149 | friend constexpr auto operator+(X&& x, Y&& y); | |
150 | ||
7c673cae FG |
151 | //! Equivalent to `hana::at` |
152 | template <typename N> | |
153 | constexpr decltype(auto) operator[](N&& n); | |
b32b8144 FG |
154 | |
155 | //! Returns a null-delimited C-style string. | |
156 | static constexpr char const* c_str(); | |
7c673cae FG |
157 | }; |
158 | #else | |
159 | template <char ...s> | |
160 | struct string; | |
161 | #endif | |
162 | ||
163 | //! Tag representing a compile-time string. | |
164 | //! @relates hana::string | |
165 | struct string_tag { }; | |
166 | ||
167 | #ifdef BOOST_HANA_DOXYGEN_INVOKED | |
168 | //! Create a compile-time `hana::string` from a parameter pack of `char` | |
169 | //! `integral_constant`s. | |
170 | //! @relates hana::string | |
171 | //! | |
172 | //! Given zero or more `integral_constant`s of underlying type `char`, | |
173 | //! `make<string_tag>` creates a `hana::string` containing those characters. | |
174 | //! This is provided mostly for consistency with the rest of the library, | |
175 | //! as `hana::string_c` is more convenient to use in most cases. | |
176 | //! | |
177 | //! | |
178 | //! Example | |
179 | //! ------- | |
180 | //! @include example/string/make.cpp | |
181 | template <> | |
182 | constexpr auto make<string_tag> = [](auto&& ...chars) { | |
183 | return string<implementation_defined>{}; | |
184 | }; | |
185 | #endif | |
186 | ||
187 | //! Alias to `make<string_tag>`; provided for convenience. | |
188 | //! @relates hana::string | |
189 | constexpr auto make_string = make<string_tag>; | |
190 | ||
11fdf7f2 TL |
191 | //! Equivalent to `to<string_tag>`; provided for convenience. |
192 | //! @relates hana::string | |
193 | constexpr auto to_string = to<string_tag>; | |
194 | ||
7c673cae FG |
195 | //! Create a compile-time string from a parameter pack of characters. |
196 | //! @relates hana::string | |
197 | //! | |
198 | //! | |
199 | //! Example | |
200 | //! ------- | |
201 | //! @include example/string/string_c.cpp | |
202 | #ifdef BOOST_HANA_DOXYGEN_INVOKED | |
203 | template <char ...s> | |
204 | constexpr string<implementation_defined> string_c{}; | |
205 | #else | |
206 | template <char ...s> | |
207 | constexpr string<s...> string_c{}; | |
208 | #endif | |
209 | ||
210 | //! Create a compile-time string from a string literal. | |
211 | //! @relates hana::string | |
212 | //! | |
213 | //! This macro is a more convenient alternative to `string_c` for creating | |
214 | //! compile-time strings. However, since this macro uses a lambda | |
215 | //! internally, it can't be used in an unevaluated context. | |
216 | //! | |
217 | //! | |
218 | //! Example | |
219 | //! ------- | |
220 | //! @include example/string/macro.cpp | |
221 | #ifdef BOOST_HANA_DOXYGEN_INVOKED | |
222 | auto BOOST_HANA_STRING(s) = see documentation; | |
223 | #define BOOST_HANA_STRING(s) see documentation | |
224 | ||
225 | // Note: | |
226 | // The trick above seems to exploit a bug in Doxygen, which makes the | |
227 | // BOOST_HANA_STRING macro appear in the related objects of hana::string | |
228 | // (as we want it to). | |
229 | #else | |
230 | // defined in <boost/hana/string.hpp> | |
231 | #endif | |
232 | ||
233 | #ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL | |
234 | namespace literals { | |
235 | //! Creates a compile-time string from a string literal. | |
236 | //! @relatesalso boost::hana::string | |
237 | //! | |
238 | //! The string literal is parsed at compile-time and the result is | |
239 | //! returned as a `hana::string`. This feature is an extension that | |
240 | //! is disabled by default; see below for details. | |
241 | //! | |
242 | //! @note | |
243 | //! Only narrow string literals are supported right now; support for | |
244 | //! fancier types of string literals like wide or UTF-XX might be | |
245 | //! added in the future if there is a demand for it. See [this issue] | |
246 | //! [Hana.issue80] if you need this. | |
247 | //! | |
248 | //! @warning | |
249 | //! This user-defined literal is an extension which requires a special | |
250 | //! string literal operator that is not part of the standard yet. | |
251 | //! That operator is supported by both Clang and GCC, and several | |
252 | //! proposals were made for it to enter C++17. However, since it is | |
253 | //! not standard, it is disabled by default and defining the | |
254 | //! `BOOST_HANA_CONFIG_ENABLE_STRING_UDL` config macro is required | |
255 | //! to get this operator. Hence, if you want to stay safe, just use | |
256 | //! the `BOOST_HANA_STRING` macro instead. If you want to be fast and | |
257 | //! furious (I do), define `BOOST_HANA_CONFIG_ENABLE_STRING_UDL`. | |
258 | //! | |
259 | //! | |
260 | //! Example | |
261 | //! ------- | |
262 | //! @include example/string/literal.cpp | |
263 | //! | |
264 | //! [Hana.issue80]: https://github.com/boostorg/hana/issues/80 | |
265 | template <typename CharT, CharT ...s> | |
266 | constexpr auto operator"" _s(); | |
267 | } | |
268 | #endif | |
269 | BOOST_HANA_NAMESPACE_END | |
270 | ||
271 | #endif // !BOOST_HANA_FWD_STRING_HPP |