-
Notifications
You must be signed in to change notification settings - Fork 216
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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.
- Loading branch information
Showing
58 changed files
with
3,532 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
/*! | ||
@file | ||
Forward declares `boost::hana::basic_string`. | ||
@copyright Louis Dionne 2013-2017 | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | ||
*/ | ||
|
||
#ifndef BOOST_HANA_FWD_BASIC_STRING_HPP | ||
#define BOOST_HANA_FWD_BASIC_STRING_HPP | ||
|
||
#include <boost/hana/config.hpp> | ||
#include <boost/hana/fwd/core/make.hpp> | ||
#include <boost/hana/fwd/core/to.hpp> | ||
|
||
|
||
BOOST_HANA_NAMESPACE_BEGIN | ||
#ifdef BOOST_HANA_DOXYGEN_INVOKED | ||
//! @ingroup group-datatypes | ||
//! Compile-time basic_string<Ch>. | ||
//! | ||
//! Conceptually, a `hana::string` is like a tuple holding | ||
//! `integral_constant`s of underlying type `char`. However, the | ||
//! interface of `hana::string` is not as rich as that of a tuple, | ||
//! because a string can only hold compile-time characters as opposed | ||
//! to any kind of object. | ||
//! | ||
//! Compile-time strings are used for simple purposes like being keys in a | ||
//! `hana::map` or tagging the members of a `Struct`. However, you might | ||
//! find that `hana::string` does not provide enough functionality to be | ||
//! used as a full-blown compile-time string implementation (e.g. regexp | ||
//! matching or substring finding). Indeed, providing a comprehensive | ||
//! string interface is a lot of job, and it is out of the scope of the | ||
//! library for the time being. | ||
//! | ||
//! | ||
//! @note | ||
//! The representation of `hana::basic_string` takes character type | ||
//! template parameters are `char`s. | ||
//! The proper way to access the contents of | ||
//! a `hana::string` as character constants is to use `hana::unpack`, | ||
//! `.c_str()` or `hana::to<ChT const*>`, as documented below. More | ||
//! details [in the tutorial](@ref tutorial-containers-types). | ||
//! | ||
//! | ||
//! Modeled concepts | ||
//! ---------------- | ||
//! For most purposes, a `hana::basic_string<ChT>` is functionally | ||
//! equivalent to a tuple holding `Constant`s of underlying type `ChT`. | ||
//! | ||
//! 1. `Comparable`\n | ||
//! Two strings are equal if and only if they have the same number of | ||
//! characters and characters at corresponding indices are equal. | ||
//! @include example/string/comparable.cpp | ||
//! | ||
//! 2. `Orderable`\n | ||
//! The total order implemented for `Orderable` is the usual | ||
//! lexicographical comparison of strings. | ||
//! @include example/string/orderable.cpp | ||
//! | ||
//! 3. `Monoid`\n | ||
//! Strings form a monoid under concatenation, with the neutral element | ||
//! being the empty string. | ||
//! @include example/string/monoid.cpp | ||
//! | ||
//! 4. `Foldable`\n | ||
//! Folding a string is equivalent to folding the sequence of its | ||
//! characters. | ||
//! @include example/string/foldable.cpp | ||
//! | ||
//! 5. `Iterable`\n | ||
//! Iterating over a string is equivalent to iterating over the sequence | ||
//! of its characters. Also note that `operator[]` can be used instead of | ||
//! the `at` function. | ||
//! @include example/string/iterable.cpp | ||
//! | ||
//! 6. `Searchable`\n | ||
//! Searching through a string is equivalent to searching through the | ||
//! sequence of its characters. | ||
//! @include example/string/searchable.cpp | ||
//! | ||
//! 7. `Hashable`\n | ||
//! The hash of a compile-time string is a type uniquely representing | ||
//! that string. | ||
//! @include example/string/hashable.cpp | ||
//! | ||
//! | ||
//! Conversion to `char const*` | ||
//! --------------------------- | ||
//! A `hana::string` can be converted to a `constexpr` null-delimited | ||
//! string of type `char const*` by using the `c_str()` method or | ||
//! `hana::to<char const*>`. This makes it easy to turn a compile-time | ||
//! string into a runtime string. However, note that this conversion is | ||
//! not an embedding, because `char const*` does not model the same | ||
//! concepts as `hana::string` does. | ||
//! @include example/string/to.cpp | ||
//! | ||
//! Conversion from any Constant holding a `char const*` | ||
//! ---------------------------------------------------- | ||
//! A `hana::string` can be created from any `Constant` whose underlying | ||
//! value is convertible to a `char const*` by using `hana::to`. The | ||
//! contents of the `char const*` are used to build the content of the | ||
//! `hana::string`. | ||
//! @include example/string/from_c_str.cpp | ||
//! | ||
//! Rationale for `hana::string` not being a `Constant` itself | ||
//! ---------------------------------------------------------- | ||
//! The underlying type held by a `hana::string` could be either `char const*` | ||
//! or some other constexpr-enabled string-like container. In the first case, | ||
//! `hana::string` can not be a `Constant` because the models of several | ||
//! concepts would not be respected by the underlying type, causing `value` | ||
//! not to be structure-preserving. Providing an underlying value of | ||
//! constexpr-enabled string-like container type like `std::string_view` | ||
//! would be great, but that's a bit complicated for the time being. | ||
template <typename Ch, Ch...> | ||
struct basic_string { | ||
// Default-construct a `hana::basic_string`; no-op since `hana::basic_string` is stateless. | ||
constexpr basic_string() = default; | ||
|
||
// Copy-construct a `hana::basic_string`; no-op since `hana::basic_string` is stateless. | ||
constexpr basic_string(basic_string const&) = default; | ||
|
||
//! Equivalent to `hana::equal` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator==(X&& x, Y&& y); | ||
|
||
//! Equivalent to `hana::not_equal` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator!=(X&& x, Y&& y); | ||
|
||
//! Equivalent to `hana::less` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator<(X&& x, Y&& y); | ||
|
||
//! Equivalent to `hana::greater` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator>(X&& x, Y&& y); | ||
|
||
//! Equivalent to `hana::less_equal` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator<=(X&& x, Y&& y); | ||
|
||
//! Equivalent to `hana::greater_equal` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator>=(X&& x, Y&& y); | ||
|
||
//! Performs concatenation; equivalent to `hana::plus` | ||
template <typename X, typename Y> | ||
friend constexpr auto operator+(X&& x, Y&& y); | ||
|
||
//! Equivalent to `hana::at` | ||
template <typename N> | ||
constexpr decltype(auto) operator[](N&& n); | ||
|
||
//! Returns a null-delimited C-style string. | ||
static constexpr Ch const* c_str(); | ||
}; | ||
#else | ||
template <typename CharT, CharT ...s> | ||
struct basic_string; | ||
#endif | ||
|
||
//! Tag representing a compile-time string. | ||
//! @relates hana::string | ||
template <typename CharT> | ||
struct basic_string_tag { }; | ||
|
||
#ifdef BOOST_HANA_DOXYGEN_INVOKED | ||
//! Create a compile-time `hana::string` from a parameter pack of `char` | ||
//! `integral_constant`s. | ||
//! @relates hana::string | ||
//! | ||
//! Given zero or more `integral_constant`s of underlying type `char`, | ||
//! `make<string_tag>` creates a `hana::string` containing those characters. | ||
//! This is provided mostly for consistency with the rest of the library, | ||
//! as `hana::string_c` is more convenient to use in most cases. | ||
//! | ||
//! | ||
//! Example | ||
//! ------- | ||
//! @include example/string/make.cpp | ||
template <typename Ch> | ||
constexpr auto make<basic_string_tag<Ch>> = [](auto&& ...chars) { | ||
return basic_string<Ch>{}; | ||
}; | ||
#endif | ||
|
||
//! Alias to `make<string_tag>`; provided for convenience. | ||
//! @relates hana::string | ||
template <typename CharT> | ||
constexpr auto make_basic_string = make<basic_string_tag<CharT>>; | ||
|
||
//! Equivalent to `to<string_tag>`; provided for convenience. | ||
//! @relates hana::string | ||
template <typename CharT> | ||
constexpr auto to_basic_string = to<basic_string_tag<CharT>>; | ||
|
||
//! Create a compile-time string from a parameter pack of characters. | ||
//! @relates hana::string | ||
//! | ||
//! | ||
//! Example | ||
//! ------- | ||
//! @include example/string/string_c.cpp | ||
#ifdef BOOST_HANA_DOXYGEN_INVOKED | ||
template <typename Ch, Ch ...s> | ||
constexpr basic_string<Ch, s...> basic_string_c{}; | ||
#else | ||
template <typename CharT, CharT ...s> | ||
constexpr basic_string<CharT, s...> basic_string_c{}; | ||
#endif | ||
|
||
//! Create a compile-time string from a string literal. | ||
//! @relates hana::basic_string | ||
//! | ||
//! This macro is a more convenient alternative to `basic_string_c` | ||
//! for creating compile-time strings. However, since this macro uses | ||
//! a lambda internally, it can't be used in an unevaluated context, | ||
//! or where a constant expression is expected before C++17. | ||
//! | ||
//! | ||
//! Example | ||
//! ------- | ||
//! @include example/basic_string/macro.cpp | ||
#ifdef BOOST_HANA_DOXYGEN_INVOKED | ||
auto BOOST_HANA_BASIC_STRING(type, s) = see documentation; | ||
#define BOOST_HANA_BASIC_STRING(type, s) see documentation | ||
|
||
// Note: | ||
// The trick above seems to exploit a bug in Doxygen, which makes the | ||
// BOOST_HANA_STRING macro appear in the related objects of hana::string | ||
// (as we want it to). | ||
#else | ||
// defined in <boost/hana/basic_string.hpp> | ||
#endif | ||
|
||
#ifdef BOOST_HANA_CONFIG_ENABLE_BASIC_STRING_UDL | ||
namespace literals { | ||
//! Creates a compile-time string from a string literal. | ||
//! @relatesalso boost::hana::string | ||
//! | ||
//! The string literal is parsed at compile-time and the result is | ||
//! returned as a `hana::string`. This feature is an extension that | ||
//! is disabled by default; see below for details. | ||
//! | ||
//! @note | ||
//! Only narrow string literals are supported right now; support for | ||
//! fancier types of string literals like wide or UTF-XX might be | ||
//! added in the future if there is a demand for it. See [this issue] | ||
//! [Hana.issue80] if you need this. | ||
//! | ||
//! @warning | ||
//! This user-defined literal is an extension which requires a special | ||
//! string literal operator that is not part of the standard yet. | ||
//! That operator is supported by both Clang and GCC, and several | ||
//! proposals were made for it to enter C++17. However, since it is | ||
//! not standard, it is disabled by default and defining the | ||
//! `BOOST_HANA_CONFIG_ENABLE_STRING_UDL` config macro is required | ||
//! to get this operator. Hence, if you want to stay safe, just use | ||
//! the `BOOST_HANA_STRING` macro instead. If you want to be fast and | ||
//! furious (I do), define `BOOST_HANA_CONFIG_ENABLE_STRING_UDL`. | ||
//! | ||
//! | ||
//! Example | ||
//! ------- | ||
//! @include example/string/literal.cpp | ||
//! | ||
//! [Hana.issue80]: https://github.com/boostorg/hana/issues/80 | ||
template <typename CharT, CharT ...s> | ||
constexpr auto operator"" _s(); | ||
} | ||
#endif | ||
BOOST_HANA_NAMESPACE_END | ||
|
||
#endif // !BOOST_HANA_FWD_BASIC_STRING_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/*! | ||
@file | ||
Defines `boost::hana::wstring`. | ||
@copyright Louis Dionne 2013-2018 | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | ||
*/ | ||
|
||
#ifndef BOOST_HANA_WSTRING_HPP | ||
#define BOOST_HANA_WSTRING_HPP | ||
|
||
#include <boost/hana/basic_string.hpp> | ||
#include <boost/hana/fwd/core/make.hpp> | ||
#include <boost/hana/fwd/core/to.hpp> | ||
|
||
BOOST_HANA_NAMESPACE_BEGIN | ||
|
||
template <wchar_t ...s> | ||
using wstring = basic_string<wchar_t, s...>; | ||
|
||
using wstring_tag = basic_string_tag<wchar_t>; | ||
|
||
constexpr auto make_wstring = make<wstring_tag>; | ||
|
||
constexpr auto to_wstring = to<wstring_tag>; | ||
|
||
template <wchar_t ...s> | ||
constexpr wstring<s...> wstring_c{}; | ||
|
||
BOOST_HANA_NAMESPACE_END | ||
|
||
#endif // !BOOST_HANA_WSTRING_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Copyright Louis Dionne 2013-2017 | ||
// Distributed under the Boost Software License, Version 1.0. | ||
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) | ||
|
||
#include <boost/hana/any_of.hpp> | ||
#include <boost/hana/assert.hpp> | ||
#include <boost/hana/basic_string.hpp> | ||
#include <boost/hana/equal.hpp> | ||
#include <boost/hana/integral_constant.hpp> | ||
#include <boost/hana/not.hpp> | ||
|
||
#include "test_basic_string.hpp" | ||
namespace hana = boost::hana; | ||
|
||
template <typename C> | ||
void test() { | ||
BOOST_HANA_CONSTANT_CHECK(hana::any_of( | ||
BOOST_HANA_BASIC_STRING(C, "abcd"), | ||
hana::equal.to(hana::basic_char_c<C, CONVERT_C('b')>) | ||
)); | ||
|
||
BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( | ||
BOOST_HANA_BASIC_STRING(C, ""), | ||
hana::always(hana::true_c) | ||
))); | ||
|
||
BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( | ||
BOOST_HANA_BASIC_STRING(C, "abcd"), | ||
hana::equal.to(hana::basic_char_c<C, CONVERT_C('z')>) | ||
))); | ||
|
||
BOOST_HANA_CONSTANT_CHECK(hana::any_of( | ||
BOOST_HANA_BASIC_STRING(C, "abc\x80" "d"), | ||
hana::equal.to(hana::basic_char_c<C, CONVERT_C('\x80')>) | ||
)); | ||
} | ||
|
||
int main() { | ||
test<char>(); | ||
test<wchar_t>(); | ||
test<char16_t>(); | ||
test<char32_t>(); | ||
} |
Oops, something went wrong.