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