Edit: /usr/include/boost/hana/string.hpp (12310B)
/*!
@file
Defines `boost::hana::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_STRING_HPP
#define BOOST_HANA_STRING_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
// string<>
//////////////////////////////////////////////////////////////////////////
//! @cond
namespace detail {
template
constexpr char const string_storage[sizeof...(s) + 1] = {s..., '\0'};
}
template
struct string
: detail::operators::adl>
, detail::iterable_operators>
{
static constexpr char const* c_str() {
return &detail::string_storage[0];
}
};
//! @endcond
template
struct tag_of> {
using type = string_tag;
};
//////////////////////////////////////////////////////////////////////////
// make
//////////////////////////////////////////////////////////////////////////
template <>
struct make_impl {
template
static constexpr auto apply(Chars const& ...) {
return hana::string()...>{};
}
};
//////////////////////////////////////////////////////////////////////////
// BOOST_HANA_STRING
//////////////////////////////////////////////////////////////////////////
namespace string_detail {
template
constexpr string
prepare_impl(S, std::index_sequence)
{ return {}; }
template
constexpr decltype(auto) prepare(S s) {
return prepare_impl(s,
std::make_index_sequence{});
}
}
#define BOOST_HANA_STRING(s) \
(::boost::hana::string_detail::prepare([]{ \
struct tmp { \
static constexpr decltype(auto) get() { return s; } \
}; \
return tmp{}; \
}())) \
/**/
#ifdef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
//////////////////////////////////////////////////////////////////////////
// _s user-defined literal
//////////////////////////////////////////////////////////////////////////
namespace literals {
template
constexpr auto operator"" _s() {
static_assert(std::is_same::value,
"hana::string: Only narrow string literals are supported with "
"the _s string literal right now. See https://goo.gl/fBbKD7 "
"if you need support for fancier types of compile-time strings.");
return hana::string_c;
}
}
#endif
//////////////////////////////////////////////////////////////////////////
// Operators
//////////////////////////////////////////////////////////////////////////
namespace detail {
template <>
struct comparable_operators {
static constexpr bool value = true;
};
template <>
struct orderable_operators {
static constexpr bool value = true;
};
}
//////////////////////////////////////////////////////////////////////////
// to
//////////////////////////////////////////////////////////////////////////
template <>
struct to_impl {
template
static constexpr char const* apply(string const&)
{ return string::c_str(); }
};
//////////////////////////////////////////////////////////////////////////
// to
//////////////////////////////////////////////////////////////////////////
namespace detail {
constexpr std::size_t cx_strlen(char const* s) {
std::size_t n = 0u;
while (*s != '\0')
++s, ++n;
return n;
}
template
constexpr hana::string()[I]...> expand(std::index_sequence)
{ return {}; }
}
template
struct to_impl::value &&
std::is_convertible::value
>> {
template
static constexpr auto apply(S const&) {
constexpr char const* s = hana::value();
constexpr std::size_t len = detail::cx_strlen(s);
return detail::expand(std::make_index_sequence{});
}
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
template <>
struct equal_impl {
template
static constexpr auto apply(S const&, S const&)
{ return hana::true_c; }
template
static constexpr auto apply(S1 const&, S2 const&)
{ return hana::false_c; }
};
//////////////////////////////////////////////////////////////////////////
// Orderable
//////////////////////////////////////////////////////////////////////////
template <>
struct less_impl {
template
static constexpr auto
apply(string const&, string const&) {
// We put a '\0' at the end only to avoid empty arrays.
constexpr char const c_str1[] = {s1..., '\0'};
constexpr char const c_str2[] = {s2..., '\0'};
return hana::bool_c;
}
};
//////////////////////////////////////////////////////////////////////////
// Monoid
//////////////////////////////////////////////////////////////////////////
template <>
struct plus_impl {
template
static constexpr auto
apply(string const&, string const&) {
return string{};
}
};
template <>
struct zero_impl {
static constexpr auto apply() {
return string<>{};
}
};
template
constexpr auto operator+(string const&, string const&) {
return hana::string{};
}
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
struct unpack_impl {
template
static constexpr decltype(auto) apply(string const&, F&& f)
{ return static_cast(f)(char_{}...); }
};
template <>
struct length_impl {
template
static constexpr auto apply(string const&)
{ return hana::size_c; }
};
//////////////////////////////////////////////////////////////////////////
// Iterable
//////////////////////////////////////////////////////////////////////////
template <>
struct front_impl {
template
static constexpr auto apply(string const&)
{ return hana::char_c; }
};
template <>
struct drop_front_impl {
template
static constexpr auto helper(string const&, std::index_sequence) {
constexpr char s[] = {xs...};
return hana::string_c;
}
template
static constexpr auto apply(string const& s, N const&) {
return helper(s, std::make_index_sequence<
(N::value < sizeof...(xs)) ? sizeof...(xs) - N::value : 0
>{});
}
template
static constexpr auto apply(string<> const& s, N const&)
{ return s; }
};
template <>
struct is_empty_impl {
template
static constexpr auto apply(string const&)
{ return hana::bool_c; }
};
template <>
struct at_impl {
template
static constexpr auto apply(string const&, N const&) {
// We put a '\0' at the end to avoid an empty array.
constexpr char characters[] = {s..., '\0'};
constexpr auto n = N::value;
return hana::char_c;
}
};
//////////////////////////////////////////////////////////////////////////
// Searchable
//////////////////////////////////////////////////////////////////////////
template <>
struct contains_impl {
template
static constexpr auto
helper(string const&, C const&, hana::true_) {
constexpr char const characters[] = {s..., '\0'};
constexpr char c = hana::value();
return hana::bool_c<
detail::find(characters, characters + sizeof...(s), c)
!= characters + sizeof...(s)
>;
}
template
static constexpr auto helper(S const&, C const&, hana::false_)
{ return hana::false_c; }
template
static constexpr auto apply(S const& s, C const& c)
{ return helper(s, c, hana::bool_c::value>); }
};
template <>
struct find_impl {
template
static constexpr auto apply(string const& str, Char const& c) {
return hana::if_(contains_impl::apply(str, c),
hana::just(c),
hana::nothing
);
}
};
//////////////////////////////////////////////////////////////////////////
// Hashable
//////////////////////////////////////////////////////////////////////////
template <>
struct hash_impl {
template
static constexpr auto apply(String const&) {
return hana::type_c;
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_STRING_HPP