Skip to content

Commit 70038ed

Browse files
committed
[basic_string] Added basic_string, wstring
- Added classes basic_string and wstring. - Added macros BOOST_HANA_BASIC_STRING and BOOST_HANA_AUTO_STRING - Added user defined literal _s for basic_string if BOOST_HANA_CONFIG_ENABLE_BASIC_STRING_UDL directive is defined. - Added following integral_constant type aliases. wchar_, char16_, char32_, basic_char - Added following integral_constant constants. wchar_c, char16_c, char32_c, basic_char_c - Added unit test codes for basic_string and wstring.
1 parent 178d14a commit 70038ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3529
-0
lines changed

include/boost/hana/basic_string.hpp

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

include/boost/hana/fwd/integral_constant.hpp

+36
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,42 @@ BOOST_HANA_NAMESPACE_BEGIN
6969
constexpr char_<c> char_c{};
7070

7171

72+
//! @relates hana::integral_constant
73+
template <wchar_t c>
74+
using wchar_ = integral_constant<wchar_t, c>;
75+
76+
//! @relates hana::integral_constant
77+
template <wchar_t c>
78+
constexpr wchar_<c> wchar_c{};
79+
80+
81+
//! @relates hana::integral_constant
82+
template <char16_t c>
83+
using char16_ = integral_constant<char16_t, c>;
84+
85+
//! @relates hana::integral_constant
86+
template <char16_t c>
87+
constexpr char16_<c> char16_c{};
88+
89+
90+
//! @relates hana::integral_constant
91+
template <char32_t c>
92+
using char32_ = integral_constant<char32_t, c>;
93+
94+
//! @relates hana::integral_constant
95+
template <char32_t c>
96+
constexpr char32_<c> char32_c{};
97+
98+
99+
//! @relates hana::integral_constant
100+
template <typename CharT, CharT c>
101+
using basic_char_ = integral_constant<CharT, c>;
102+
103+
//! @relates hana::integral_constant
104+
template <typename CharT, CharT c>
105+
constexpr basic_char_<CharT, c> basic_char_c{};
106+
107+
72108
//! @relates hana::integral_constant
73109
template <short i>
74110
using short_ = integral_constant<short, i>;

include/boost/hana/wstring.hpp

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*!
2+
@file
3+
Defines `boost::hana::wstring`.
4+
5+
@copyright Louis Dionne 2013-2018
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_WSTRING_HPP
11+
#define BOOST_HANA_WSTRING_HPP
12+
13+
#include <boost/hana/basic_string.hpp>
14+
#include <boost/hana/fwd/core/make.hpp>
15+
#include <boost/hana/fwd/core/to.hpp>
16+
17+
BOOST_HANA_NAMESPACE_BEGIN
18+
19+
template <wchar_t ...s>
20+
using wstring = basic_string<wchar_t, s...>;
21+
22+
using wstring_tag = basic_string_tag<wchar_t>;
23+
24+
constexpr auto make_wstring = make<wstring_tag>;
25+
26+
constexpr auto to_wstring = to<wstring_tag>;
27+
28+
template <wchar_t ...s>
29+
constexpr wstring<s...> wstring_c{};
30+
31+
BOOST_HANA_NAMESPACE_END
32+
33+
#endif // !BOOST_HANA_WSTRING_HPP

test/basic_string/any_of.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright Louis Dionne 2013-2017
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4+
5+
#include <boost/hana/any_of.hpp>
6+
#include <boost/hana/assert.hpp>
7+
#include <boost/hana/basic_string.hpp>
8+
#include <boost/hana/equal.hpp>
9+
#include <boost/hana/integral_constant.hpp>
10+
#include <boost/hana/not.hpp>
11+
12+
#include "test_basic_string.hpp"
13+
namespace hana = boost::hana;
14+
15+
template <typename C>
16+
void test() {
17+
BOOST_HANA_CONSTANT_CHECK(hana::any_of(
18+
BOOST_HANA_BASIC_STRING(C, "abcd"),
19+
hana::equal.to(hana::basic_char_c<C, CONVERT_C('b')>)
20+
));
21+
22+
BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
23+
BOOST_HANA_BASIC_STRING(C, ""),
24+
hana::always(hana::true_c)
25+
)));
26+
27+
BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of(
28+
BOOST_HANA_BASIC_STRING(C, "abcd"),
29+
hana::equal.to(hana::basic_char_c<C, CONVERT_C('z')>)
30+
)));
31+
32+
BOOST_HANA_CONSTANT_CHECK(hana::any_of(
33+
BOOST_HANA_BASIC_STRING(C, "abc\x80" "d"),
34+
hana::equal.to(hana::basic_char_c<C, CONVERT_C('\x80')>)
35+
));
36+
}
37+
38+
int main() {
39+
test<char>();
40+
test<wchar_t>();
41+
test<char16_t>();
42+
test<char32_t>();
43+
}

0 commit comments

Comments
 (0)