forked from boostorg/static_string
committed by
Alan de Freitas
parent
269987446e
commit
ac84c4f40e
@ -147,15 +147,51 @@
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_STATIC_STRING_STANDALONE
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) || \
|
||||
defined(BOOST_STATIC_STRING_CXX17_STRING_VIEW)
|
||||
#include <string_view>
|
||||
#define BOOST_STATIC_STRING_HAS_STD_STRING_VIEW
|
||||
#endif
|
||||
#else
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
/*
|
||||
* Replicate the logic from Boost.Config
|
||||
*/
|
||||
// GNU libstdc++3:
|
||||
#if defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||
#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L)
|
||||
# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW
|
||||
#endif
|
||||
// libc++:
|
||||
#elif defined(_LIBCPP_VERSION)
|
||||
#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L)
|
||||
# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW
|
||||
#endif
|
||||
// MSVC uses logic from catch all for BOOST_NO_CXX17_HDR_STRING_VIEW
|
||||
// catch all:
|
||||
#elif !defined(_YVALS) && !defined(_CPPLIB_VER)
|
||||
#if (!defined(__has_include) || (__cplusplus < 201700))
|
||||
# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW
|
||||
#elif !__has_include(<string_view>)
|
||||
# define BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_STATIC_STRING_NO_CXX17_HDR_STRING_VIEW) || \
|
||||
defined(BOOST_STATIC_STRING_CXX17_STRING_VIEW)
|
||||
#include <string_view>
|
||||
#define BOOST_STATIC_STRING_HAS_STD_STRING_VIEW
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Compiler bug prevents constexpr from working with clang 4.x and 5.x
|
||||
@ -192,6 +228,12 @@ defined(BOOST_STATIC_STRING_CPP14)
|
||||
#define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
|
||||
#endif
|
||||
|
||||
// Define the basic string_view type used by the library
|
||||
// Conversions to and from other available string_view types
|
||||
// are still defined.
|
||||
#if !defined(BOOST_STATIC_STRING_STANDALONE) || \
|
||||
defined(BOOST_STATIC_STRING_HAS_STD_STRING_VIEW)
|
||||
#define BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
namespace boost {
|
||||
namespace static_strings {
|
||||
|
||||
@ -205,4 +247,6 @@ using basic_string_view =
|
||||
#endif
|
||||
} // static_strings
|
||||
} // boost
|
||||
#endif
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@
|
||||
#include <cwchar>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <limits>
|
||||
#include <iosfwd>
|
||||
#include <type_traits>
|
||||
|
||||
@ -126,16 +127,43 @@ struct void_t_helper
|
||||
template<typename... Ts>
|
||||
using void_t = typename void_t_helper<Ts...>::type;
|
||||
|
||||
template <class T, typename CharT, typename = void>
|
||||
struct is_string_like : std::false_type {};
|
||||
|
||||
template<typename T, typename CharT>
|
||||
struct is_string_like<
|
||||
T, CharT,
|
||||
void_t<
|
||||
decltype(std::declval<CharT const*&>() = std::declval<T>().data()),
|
||||
decltype(std::declval<std::size_t&>() = std::declval<T>().size())>>
|
||||
: std::true_type
|
||||
{};
|
||||
|
||||
// Check if a type can be used for templated
|
||||
// overloads string_view_type
|
||||
// This will be used by overloads that accept the string_view types
|
||||
// directly and other convertible types such as std::string.
|
||||
// When no string_view type is available, then we check for the
|
||||
// data and size member functions, and use them directly for assignments.
|
||||
template<typename T, typename CharT, typename Traits, typename = void>
|
||||
struct enable_if_viewable { };
|
||||
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
struct enable_if_viewable<T, CharT, Traits,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value &&
|
||||
!std::is_convertible<const T&, const CharT*>::value>::type>
|
||||
typename std::enable_if<
|
||||
#if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
|
||||
is_string_like<T, CharT>::value
|
||||
#elif defined(BOOST_STATIC_STRING_STANDALONE)
|
||||
std::is_convertible<const T&, std::basic_string_view<CharT, Traits>>::value &&
|
||||
!std::is_convertible<const T&, const CharT*>::value
|
||||
#else
|
||||
(
|
||||
std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value ||
|
||||
std::is_convertible<const T&, core::basic_string_view<CharT>>::value
|
||||
) &&
|
||||
!std::is_convertible<const T&, const CharT*>::value
|
||||
#endif
|
||||
>::type>
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
@ -143,6 +171,59 @@ struct enable_if_viewable<T, CharT, Traits,
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
using enable_if_viewable_t = typename enable_if_viewable<T, CharT, Traits>::type;
|
||||
|
||||
// The common string_view type used in private operations with enable_if_viewable_t
|
||||
// - T const& itself when no string_view type is available
|
||||
// - basic_string_view (boost::string_view or std::string_view) when in
|
||||
// standalone because core::detail::string_view is unavailable
|
||||
// - core::detail::basic_string_view otherwise because it's convertible
|
||||
// to and from most types, including std::string_view
|
||||
// After converting a parameter to a common_string_view_type reference, we
|
||||
// can use the data() and size() member functions.
|
||||
#if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
using common_string_view_type = T const&;
|
||||
#elif defined(BOOST_STATIC_STRING_STANDALONE)
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
using common_string_view_type = basic_string_view<CharT, Traits>;
|
||||
#else
|
||||
template <class T, typename CharT, typename Traits, typename = void>
|
||||
struct common_string_view_type_impl {};
|
||||
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
struct common_string_view_type_impl<
|
||||
T, CharT, Traits,
|
||||
typename std::enable_if<
|
||||
is_string_like<T, CharT>::value &&
|
||||
!std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value &&
|
||||
!std::is_convertible<const T&, core::basic_string_view<CharT>>::value>::type>
|
||||
{
|
||||
using type = T const&;
|
||||
};
|
||||
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
struct common_string_view_type_impl<
|
||||
T, CharT, Traits,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value &&
|
||||
!std::is_convertible<const T&, core::basic_string_view<CharT>>::value>::type>
|
||||
{
|
||||
using type = basic_string_view<CharT, Traits>;
|
||||
};
|
||||
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
struct common_string_view_type_impl<
|
||||
T, CharT, Traits,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<const T&, core::basic_string_view<CharT>>::value>::type>
|
||||
{
|
||||
using type = core::basic_string_view<CharT>;
|
||||
};
|
||||
|
||||
template<typename T, typename CharT, typename Traits>
|
||||
using common_string_view_type = typename common_string_view_type_impl<T, CharT, Traits>::type;
|
||||
#endif
|
||||
|
||||
|
||||
// Simplified check for if a type is an iterator
|
||||
template<typename T, typename = void>
|
||||
struct is_iterator : std::false_type { };
|
||||
@ -879,9 +960,11 @@ public:
|
||||
using const_reverse_iterator =
|
||||
std::reverse_iterator<const_iterator>;
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
/// The string view type.
|
||||
using string_view_type =
|
||||
basic_string_view<value_type, traits_type>;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@ -1538,7 +1621,7 @@ public:
|
||||
basic_static_string&
|
||||
assign(const T& t)
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return assign(sv.data(), sv.size());
|
||||
}
|
||||
|
||||
@ -1590,8 +1673,12 @@ public:
|
||||
size_type pos,
|
||||
size_type count = npos)
|
||||
{
|
||||
const auto sv = string_view_type(t).substr(pos, count);
|
||||
return assign(sv.data(), sv.size());
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
if( pos > sv.size() )
|
||||
detail::throw_exception<std::out_of_range>(
|
||||
"pos >= t.size()");
|
||||
std::size_t rlen = (std::min)( count, sv.size() - pos );
|
||||
return assign(sv.data() + pos, rlen);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -1837,6 +1924,7 @@ public:
|
||||
return data();
|
||||
}
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
/** Convert to a string view referring to the string.
|
||||
|
||||
Returns a string view referring to the
|
||||
@ -1851,6 +1939,28 @@ public:
|
||||
{
|
||||
return string_view_type(data(), size());
|
||||
}
|
||||
#else
|
||||
#ifdef BOOST_STATIC_STRING_HAS_STD_STRING_VIEW
|
||||
BOOST_STATIC_STRING_CPP11_CONSTEXPR
|
||||
operator std::basic_string_view<CharT, Traits>() const noexcept
|
||||
{
|
||||
return std::basic_string_view<CharT, Traits>(data(), size());
|
||||
}
|
||||
#endif
|
||||
#ifndef BOOST_STATIC_STRING_STANDALONE
|
||||
BOOST_STATIC_STRING_CPP11_CONSTEXPR
|
||||
operator ::boost::basic_string_view<CharT, Traits>() const noexcept
|
||||
{
|
||||
return ::boost::basic_string_view<CharT, Traits>(data(), size());
|
||||
}
|
||||
|
||||
BOOST_STATIC_STRING_CPP11_CONSTEXPR
|
||||
operator ::boost::core::basic_string_view<CharT>() const noexcept
|
||||
{
|
||||
return ::boost::core::basic_string_view<CharT>(data(), size());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@ -2503,7 +2613,7 @@ public:
|
||||
size_type index,
|
||||
const T& t)
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return insert(index, sv.data(), sv.size());
|
||||
}
|
||||
|
||||
@ -2552,8 +2662,10 @@ public:
|
||||
size_type index_str,
|
||||
size_type count = npos)
|
||||
{
|
||||
const auto sv = string_view_type(t).substr(index_str, count);
|
||||
return insert(index, sv.data(), sv.size());
|
||||
detail::common_string_view_type<T, CharT, Traits> sv(t);
|
||||
if ( index_str > sv.size() )
|
||||
detail::throw_exception<std::out_of_range>("index_str > t.size()");
|
||||
return insert(index, sv.data() + index_str, (std::min)(sv.size() - index_str, count));
|
||||
}
|
||||
|
||||
/** Erase from the string.
|
||||
@ -2912,7 +3024,7 @@ public:
|
||||
basic_static_string&
|
||||
append(const T& t)
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return append(sv.data(), sv.size());
|
||||
}
|
||||
|
||||
@ -2957,8 +3069,10 @@ public:
|
||||
size_type pos,
|
||||
size_type count = npos)
|
||||
{
|
||||
const auto sv = string_view_type(t).substr(pos, count);
|
||||
return append(sv.data(), sv.size());
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
if ( pos > sv.size() )
|
||||
detail::throw_exception<std::out_of_range>("pos > t.size()");
|
||||
return append(sv.data() + pos, (std::min)(sv.size() - pos, count));
|
||||
}
|
||||
|
||||
/** Append to the string.
|
||||
@ -3342,7 +3456,7 @@ public:
|
||||
int
|
||||
compare(const T& t) const noexcept
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
data(), size(), sv.data(), sv.size());
|
||||
}
|
||||
@ -3393,7 +3507,7 @@ public:
|
||||
size_type count1,
|
||||
const T& t) const
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
data() + pos1, capped_length(pos1, count1), sv.data(), sv.size());
|
||||
}
|
||||
@ -3450,9 +3564,12 @@ public:
|
||||
size_type pos2,
|
||||
size_type count2 = npos) const
|
||||
{
|
||||
const auto sv = string_view_type(t).substr(pos2, count2);
|
||||
return compare(pos1, count1,
|
||||
sv.data(), sv.size());
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
if ( pos2 > sv.size())
|
||||
detail::throw_exception<std::out_of_range>("pos2 > sv.size()");
|
||||
return compare(
|
||||
pos1, count1, sv.data() + pos2,
|
||||
(std::min)(sv.size() - pos2, count2));
|
||||
}
|
||||
|
||||
/** Return a substring.
|
||||
@ -3485,6 +3602,7 @@ public:
|
||||
data() + pos, capped_length(pos, count));
|
||||
}
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
/** Return a string view of a substring.
|
||||
|
||||
Returns a view of a substring.
|
||||
@ -3512,6 +3630,7 @@ public:
|
||||
return string_view_type(
|
||||
data() + pos, capped_length(pos, count));
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Copy a substring to another string.
|
||||
|
||||
@ -3771,7 +3890,7 @@ public:
|
||||
size_type n1,
|
||||
const T& t)
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return replace(pos1, n1, sv.data(), sv.size());
|
||||
}
|
||||
|
||||
@ -3823,8 +3942,12 @@ public:
|
||||
size_type pos2,
|
||||
size_type n2 = npos)
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
return replace(pos1, n1, sv.substr(pos2, n2));
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
if ( pos2 > sv.size())
|
||||
detail::throw_exception<std::out_of_range>("pos2 > t.size()");
|
||||
return replace(
|
||||
pos1, n1, sv.data() + pos2,
|
||||
(std::min)(sv.size() - pos2, n2));
|
||||
}
|
||||
|
||||
/** Replace a part of the string.
|
||||
@ -4029,8 +4152,8 @@ public:
|
||||
const_iterator i2,
|
||||
const T& t)
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
return replace(i1, i2, sv.begin(), sv.end());
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return replace(i1, i2, sv.data(), sv.data() + sv.size());
|
||||
}
|
||||
|
||||
/** Replace a part of the string.
|
||||
@ -4290,9 +4413,13 @@ public:
|
||||
find(
|
||||
const T& t,
|
||||
size_type pos = 0) const
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
|
||||
#else
|
||||
noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
|
||||
#endif
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return find(sv.data(), pos, sv.size());
|
||||
}
|
||||
|
||||
@ -4443,9 +4570,13 @@ public:
|
||||
rfind(
|
||||
const T& t,
|
||||
size_type pos = npos) const
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
|
||||
#else
|
||||
noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
|
||||
#endif
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return rfind(sv.data(), pos, sv.size());
|
||||
}
|
||||
|
||||
@ -4591,9 +4722,13 @@ public:
|
||||
find_first_of(
|
||||
const T& t,
|
||||
size_type pos = 0) const
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
|
||||
#else
|
||||
noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
|
||||
#endif
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return find_first_of(sv.data(), pos, sv.size());
|
||||
}
|
||||
|
||||
@ -4734,9 +4869,13 @@ public:
|
||||
find_last_of(
|
||||
const T& t,
|
||||
size_type pos = npos) const
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
|
||||
#else
|
||||
noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
|
||||
#endif
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return find_last_of(sv.data(), pos, sv.size());
|
||||
}
|
||||
|
||||
@ -4876,9 +5015,13 @@ public:
|
||||
find_first_not_of(
|
||||
const T& t,
|
||||
size_type pos = 0) const
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
|
||||
#else
|
||||
noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
|
||||
#endif
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return find_first_not_of(sv.data(), pos, sv.size());
|
||||
}
|
||||
|
||||
@ -5017,9 +5160,13 @@ public:
|
||||
find_last_not_of(
|
||||
const T& t,
|
||||
size_type pos = npos) const
|
||||
#ifdef BOOST_STATIC_STRING_DOCS
|
||||
noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
|
||||
#else
|
||||
noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
|
||||
#endif
|
||||
{
|
||||
const string_view_type sv = t;
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
return find_last_not_of(sv.data(), pos, sv.size());
|
||||
}
|
||||
|
||||
@ -5133,15 +5280,21 @@ public:
|
||||
|
||||
Linear.
|
||||
|
||||
@param s The string view to check for.
|
||||
@param t The string view to check for.
|
||||
*/
|
||||
template<typename T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
bool
|
||||
starts_with(
|
||||
string_view_type s) const noexcept
|
||||
T const& t) const noexcept
|
||||
{
|
||||
const size_type len = s.size();
|
||||
return size() >= len && !traits_type::compare(data(), s.data(), len);
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
const size_type len = sv.size();
|
||||
return size() >= len && !traits_type::compare(data(), sv.data(), len);
|
||||
}
|
||||
|
||||
/** Return whether the string begins with a character.
|
||||
@ -5191,15 +5344,21 @@ public:
|
||||
|
||||
Linear.
|
||||
|
||||
@param s The string view to check for.
|
||||
@param t The string view to check for.
|
||||
*/
|
||||
template<typename T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
bool
|
||||
ends_with(
|
||||
string_view_type s) const noexcept
|
||||
T const& t) const noexcept
|
||||
{
|
||||
const size_type len = s.size();
|
||||
return size() >= len && !traits_type::compare(data() + (size() - len), s.data(), len);
|
||||
detail::common_string_view_type<T, CharT, Traits> sv = t;
|
||||
const size_type len = sv.size();
|
||||
return size() >= len && !traits_type::compare(data() + (size() - len), sv.data(), len);
|
||||
}
|
||||
|
||||
/** Return whether the string ends with a character.
|
||||
@ -5456,6 +5615,42 @@ operator==(
|
||||
rhs, Traits::length(rhs)) == 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator==(
|
||||
const T& lhs,
|
||||
const basic_static_string<N, CharT, Traits>& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhsv.data(), lhsv.size(),
|
||||
rhs.data(), rhs.size()) == 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator==(
|
||||
const basic_static_string<N, CharT, Traits>& lhs,
|
||||
const T& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhs.data(), lhs.size(),
|
||||
rhsv.data(), rhsv.size()) == 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
@ -5482,6 +5677,42 @@ operator!=(
|
||||
rhs, Traits::length(rhs)) != 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator!=(
|
||||
const T& lhs,
|
||||
const basic_static_string<N, CharT, Traits>& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhsv.data(), lhsv.size(),
|
||||
rhs.data(), rhs.size()) != 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator!=(
|
||||
const basic_static_string<N, CharT, Traits>& lhs,
|
||||
const T& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhs.data(), lhs.size(),
|
||||
rhsv.data(), rhsv.size()) != 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
@ -5508,6 +5739,42 @@ operator<(
|
||||
rhs, Traits::length(rhs)) < 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator<(
|
||||
const T& lhs,
|
||||
const basic_static_string<N, CharT, Traits>& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhsv.data(), lhsv.size(),
|
||||
rhs.data(), rhs.size()) < 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator<(
|
||||
const basic_static_string<N, CharT, Traits>& lhs,
|
||||
const T& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhs.data(), lhs.size(),
|
||||
rhsv.data(), rhsv.size()) < 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
@ -5534,6 +5801,42 @@ operator<=(
|
||||
rhs, Traits::length(rhs)) <= 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator<=(
|
||||
const T& lhs,
|
||||
const basic_static_string<N, CharT, Traits>& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhsv.data(), lhsv.size(),
|
||||
rhs.data(), rhs.size()) <= 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator<=(
|
||||
const basic_static_string<N, CharT, Traits>& lhs,
|
||||
const T& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhs.data(), lhs.size(),
|
||||
rhsv.data(), rhsv.size()) <= 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
@ -5560,6 +5863,43 @@ operator>(
|
||||
rhs, Traits::length(rhs)) > 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator>(
|
||||
const T& lhs,
|
||||
const basic_static_string<N, CharT, Traits>& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhsv.data(), lhsv.size(),
|
||||
rhs.data(), rhs.size()) > 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator>(
|
||||
const basic_static_string<N, CharT, Traits>& lhs,
|
||||
const T& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhs.data(), lhs.size(),
|
||||
rhsv.data(), rhsv.size()) > 0;
|
||||
}
|
||||
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
@ -5586,6 +5926,42 @@ operator>=(
|
||||
rhs, Traits::length(rhs)) >= 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator>=(
|
||||
const T& lhs,
|
||||
const basic_static_string<N, CharT, Traits>& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhsv.data(), lhsv.size(),
|
||||
rhs.data(), rhs.size()) >= 0;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename CharT, typename Traits, class T
|
||||
#ifndef BOOST_STATIC_STRING_DOCS
|
||||
, typename = detail::enable_if_viewable_t<T, CharT, Traits>
|
||||
#endif
|
||||
>
|
||||
BOOST_STATIC_STRING_CPP14_CONSTEXPR
|
||||
inline
|
||||
bool
|
||||
operator>=(
|
||||
const basic_static_string<N, CharT, Traits>& lhs,
|
||||
const T& rhs)
|
||||
{
|
||||
detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
|
||||
return detail::lexicographical_compare<CharT, Traits>(
|
||||
lhs.data(), lhs.size(),
|
||||
rhsv.data(), rhsv.size()) >= 0;
|
||||
}
|
||||
|
||||
template<
|
||||
std::size_t N, std::size_t M,
|
||||
typename CharT, typename Traits>
|
||||
@ -5721,7 +6097,13 @@ operator<<(
|
||||
std::basic_ostream<CharT, Traits>& os,
|
||||
const basic_static_string<N, CharT, Traits>& s)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
return os << basic_string_view<CharT, Traits>(s.data(), s.size());
|
||||
#else
|
||||
for (auto c: s)
|
||||
os << c;
|
||||
return os;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -5961,14 +6343,47 @@ struct hash<
|
||||
operator()(
|
||||
const boost::static_strings::basic_static_string<N, CharT, Traits>& str) const noexcept
|
||||
{
|
||||
#ifndef BOOST_STATIC_STRING_STANDALONE
|
||||
#if !defined(BOOST_STATIC_STRING_STANDALONE)
|
||||
return boost::hash_range(str.begin(), str.end());
|
||||
#else
|
||||
#elif defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
|
||||
using view_type = typename
|
||||
boost::static_strings::basic_string_view<CharT, Traits>;
|
||||
return std::hash<view_type>()(view_type(str.data(), str.size()));
|
||||
#else
|
||||
std::size_t seed = 0;
|
||||
for (CharT const& c : str) {
|
||||
mix_impl(std::integral_constant<bool, sizeof(std::size_t) >= 8>{}, seed, c);
|
||||
}
|
||||
return seed;
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
mix_impl(std::true_type, std::size_t& seed, CharT c)
|
||||
{
|
||||
seed += 0x9e3779b9 + std::hash<CharT>()( c );
|
||||
std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d;
|
||||
seed ^= seed >> 32;
|
||||
seed *= m;
|
||||
seed ^= seed >> 32;
|
||||
seed *= m;
|
||||
seed ^= seed >> 28;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
mix_impl(std::false_type, std::size_t& seed, CharT c)
|
||||
{
|
||||
seed += 0x9e3779b9 + std::hash<CharT>()( c );
|
||||
std::size_t const m1 = 0x21f0aaad;
|
||||
std::size_t const m2 = 0x735a2d97;
|
||||
seed ^= seed >> 16;
|
||||
seed *= m1;
|
||||
seed ^= seed >> 15;
|
||||
seed *= m2;
|
||||
seed ^= seed >> 15;
|
||||
}
|
||||
};
|
||||
} // std
|
||||
|
||||
|
@ -357,8 +357,10 @@ testConstantEvaluation()
|
||||
a.substr(0);
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_HAS_STRING_VIEW
|
||||
// subview
|
||||
a.subview(0);
|
||||
#endif
|
||||
|
||||
// copy
|
||||
char k[20]{};
|
||||
|
@ -26,7 +26,15 @@ namespace static_strings {
|
||||
|
||||
template class basic_static_string<420, char>;
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
using string_view = basic_string_view<char, std::char_traits<char>>;
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
using string_like = basic_string_view<char, std::char_traits<char>>;
|
||||
#else
|
||||
using string_like = std::string;
|
||||
#endif
|
||||
|
||||
template <class S>
|
||||
bool
|
||||
@ -51,13 +59,21 @@ testSV(const S& s, typename S::size_type pos, typename S::size_type n)
|
||||
{
|
||||
if (pos <= s.size())
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
typename S::string_view_type str = s.subview(pos, n);
|
||||
#else
|
||||
auto str = s.substr(pos, n);
|
||||
#endif
|
||||
typename S::size_type rlen = (std::min)(n, s.size() - pos);
|
||||
return (S::traits_type::compare(s.data() + pos, str.data(), rlen) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
BOOST_TEST_THROWS((s.subview(pos, n)), std::out_of_range);
|
||||
#else
|
||||
BOOST_TEST_THROWS((s.substr(pos, n)), std::out_of_range);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -342,11 +358,11 @@ testConstruct()
|
||||
}
|
||||
{
|
||||
static_string<3> s1(
|
||||
string_view("123"));
|
||||
string_like("123"));
|
||||
BOOST_TEST(s1 == "123");
|
||||
BOOST_TEST(*s1.end() == 0);
|
||||
BOOST_TEST_THROWS(
|
||||
(static_string<2>(string_view("123"))),
|
||||
(static_string<2>(string_like("123"))),
|
||||
std::length_error);
|
||||
}
|
||||
{
|
||||
@ -424,6 +440,7 @@ testAssignment()
|
||||
|
||||
// assign(T const& t)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
struct T
|
||||
{
|
||||
operator string_view() const noexcept
|
||||
@ -431,6 +448,21 @@ testAssignment()
|
||||
return "abc";
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct T
|
||||
{
|
||||
char const* data() const noexcept
|
||||
{
|
||||
static char p[] = "abc";
|
||||
return p;
|
||||
}
|
||||
|
||||
std::size_t size() const noexcept
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
BOOST_TEST(static_string<3>{}.assign(T{}) == "abc");
|
||||
BOOST_TEST(static_string<3>{"*"}.assign(T{}) == "abc");
|
||||
BOOST_TEST(static_string<3>{"***"}.assign(T{}) == "abc");
|
||||
@ -439,6 +471,7 @@ testAssignment()
|
||||
|
||||
// assign(T const& t, size_type pos, size_type count = npos)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
struct T
|
||||
{
|
||||
operator string_view() const noexcept
|
||||
@ -446,6 +479,23 @@ testAssignment()
|
||||
return "abcde";
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct T
|
||||
{
|
||||
char const*
|
||||
data() const noexcept
|
||||
{
|
||||
static char p[] = "abcde";
|
||||
return p;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
BOOST_TEST(static_string<5>{}.assign(T{}, 0) == "abcde");
|
||||
BOOST_TEST(static_string<5>{}.assign(T{}, 0, 5) == "abcde");
|
||||
BOOST_TEST(static_string<5>{}.assign(T{}, 1, 3) == "bcd");
|
||||
@ -507,15 +557,14 @@ testAssignment()
|
||||
}
|
||||
{
|
||||
static_string<3> s1;
|
||||
s1 = string_view("123");
|
||||
s1 = string_like("123");
|
||||
BOOST_TEST(s1 == "123");
|
||||
BOOST_TEST(*s1.end() == 0);
|
||||
static_string<1> s2;
|
||||
BOOST_TEST_THROWS(
|
||||
s2 = string_view("123"),
|
||||
s2 = string_like("123"),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
{
|
||||
static_string<4> s1;
|
||||
s1.assign(3, 'x');
|
||||
@ -603,14 +652,14 @@ testAssignment()
|
||||
}
|
||||
{
|
||||
static_string<5> s1;
|
||||
s1.assign(string_view("123"));
|
||||
s1.assign(string_like("123"));
|
||||
BOOST_TEST(s1 == "123");
|
||||
BOOST_TEST(*s1.end() == 0);
|
||||
s1.assign(string_view("12345"));
|
||||
s1.assign(string_like("12345"));
|
||||
BOOST_TEST(s1 == "12345");
|
||||
BOOST_TEST(*s1.end() == 0);
|
||||
BOOST_TEST_THROWS(
|
||||
s1.assign(string_view("1234567")),
|
||||
s1.assign(string_like("1234567")),
|
||||
std::length_error);
|
||||
}
|
||||
{
|
||||
@ -795,11 +844,20 @@ testElements()
|
||||
BOOST_TEST(std::memcmp(
|
||||
s.c_str(), "123\0", 4) == 0);
|
||||
}
|
||||
#ifdef BOOST_STATIC_ASSERT_HAS_STRING_VIEW
|
||||
{
|
||||
static_string<3> s("123");
|
||||
string_view sv = s;
|
||||
BOOST_TEST(static_string<5>(sv) == "123");
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_STATIC_ASSERT_HAS_STD_STRING_VIEW
|
||||
{
|
||||
static_string<3> s("123");
|
||||
std::string_view sv = s;
|
||||
BOOST_TEST(static_string<5>(sv) == "123");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// done
|
||||
@ -916,7 +974,7 @@ static
|
||||
void
|
||||
testInsert()
|
||||
{
|
||||
using sv = string_view;
|
||||
using sv = string_like;
|
||||
using S = static_string<100>;
|
||||
|
||||
// insert(size_type index, size_type count, CharT ch)
|
||||
@ -997,6 +1055,7 @@ testInsert()
|
||||
|
||||
// insert(size_type index, T const& t)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
struct T
|
||||
{
|
||||
operator string_view() const noexcept
|
||||
@ -1004,6 +1063,23 @@ testInsert()
|
||||
return "b";
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct T
|
||||
{
|
||||
char const*
|
||||
data() const noexcept
|
||||
{
|
||||
static char p[] = "b";
|
||||
return p;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
BOOST_TEST(static_string<3>{"ac"}.insert(1, T{}) == "abc");
|
||||
BOOST_TEST_THROWS(static_string<4>{"abc"}.insert(4, T{}), std::out_of_range);
|
||||
BOOST_TEST_THROWS(static_string<3>{"abc"}.insert(1, T{}), std::length_error);
|
||||
@ -1011,6 +1087,7 @@ testInsert()
|
||||
|
||||
// insert(size_type index, T const& t, size_type index_str, size_type count = npos)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
struct T
|
||||
{
|
||||
operator string_view() const noexcept
|
||||
@ -1018,6 +1095,23 @@ testInsert()
|
||||
return "abcd";
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct T
|
||||
{
|
||||
char const*
|
||||
data() const noexcept
|
||||
{
|
||||
static char p[] = "abcd";
|
||||
return p;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
BOOST_TEST(static_string<6>{"ae"}.insert(1, T{}, 1) == "abcde");
|
||||
BOOST_TEST(static_string<6>{"abe"}.insert(2, T{}, 2) == "abcde");
|
||||
BOOST_TEST(static_string<4>{"ac"}.insert(1, T{}, 1, 1) == "abc");
|
||||
@ -1145,16 +1239,16 @@ testInsert()
|
||||
}
|
||||
{
|
||||
static_string<5> s1("123");
|
||||
s1.insert(1, string_view("UV"));
|
||||
s1.insert(1, string_like("UV"));
|
||||
BOOST_TEST(s1 == "1UV23");
|
||||
BOOST_TEST(*s1.end() == 0);
|
||||
static_string<4> s2("123");
|
||||
BOOST_TEST_THROWS(
|
||||
(s2.insert(1, string_view("UV"))),
|
||||
(s2.insert(1, string_like("UV"))),
|
||||
std::length_error);
|
||||
static_string<5> s3("123");
|
||||
BOOST_TEST_THROWS(
|
||||
(s3.insert(5, string_view("UV"))),
|
||||
(s3.insert(5, string_like("UV"))),
|
||||
std::out_of_range);
|
||||
}
|
||||
{
|
||||
@ -1986,7 +2080,7 @@ void
|
||||
testAppend()
|
||||
{
|
||||
using S = static_string<400>;
|
||||
using sv = string_view;
|
||||
using sv = string_like;
|
||||
|
||||
// append(size_type count, CharT ch)
|
||||
BOOST_TEST(static_string<1>{}.append(1, 'a') == "a");
|
||||
@ -2031,6 +2125,7 @@ testAppend()
|
||||
|
||||
// append(T const& t)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
struct T
|
||||
{
|
||||
operator string_view() const noexcept
|
||||
@ -2038,12 +2133,29 @@ testAppend()
|
||||
return "c";
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct T
|
||||
{
|
||||
char const*
|
||||
data() const noexcept
|
||||
{
|
||||
return "c";
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
BOOST_TEST(static_string<3>{"ab"}.append(T{}) == "abc");
|
||||
BOOST_TEST_THROWS(static_string<3>{"abc"}.append(T{}), std::length_error);
|
||||
}
|
||||
|
||||
// append(T const& t, size_type pos, size_type count = npos)
|
||||
{
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
struct T
|
||||
{
|
||||
operator string_view() const noexcept
|
||||
@ -2051,6 +2163,22 @@ testAppend()
|
||||
return "abcd";
|
||||
}
|
||||
};
|
||||
#else
|
||||
struct T
|
||||
{
|
||||
char const*
|
||||
data() const noexcept
|
||||
{
|
||||
return "abcd";
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
BOOST_TEST(static_string<4>{"ab"}.append(T{}, 2) == "abcd");
|
||||
BOOST_TEST(static_string<3>{"a"}.append(T{}, 1, 2) == "abc");
|
||||
BOOST_TEST_THROWS(static_string<4>{"abc"}.append(T{}, 5), std::out_of_range);
|
||||
@ -2141,7 +2269,7 @@ testAppend()
|
||||
std::length_error);
|
||||
}
|
||||
{
|
||||
string_view s1("XYZ");
|
||||
string_like s1("XYZ");
|
||||
static_string<5> s2("12");
|
||||
s2.append(s1);
|
||||
BOOST_TEST(s2 == "12XYZ");
|
||||
@ -2196,7 +2324,7 @@ static
|
||||
void
|
||||
testPlusEquals()
|
||||
{
|
||||
using sv = string_view;
|
||||
using sv = string_like;
|
||||
|
||||
// operator+=(CharT ch)
|
||||
BOOST_TEST((static_string<3>{"ab"} += 'c') == "abc");
|
||||
@ -2252,7 +2380,7 @@ testPlusEquals()
|
||||
std::length_error);
|
||||
}
|
||||
{
|
||||
string_view s1("34");
|
||||
string_like s1("34");
|
||||
static_string<4> s2("12");
|
||||
s2 += s1;
|
||||
BOOST_TEST(s2 == "1234");
|
||||
@ -2288,6 +2416,7 @@ testCompare()
|
||||
BOOST_TEST(s1.compare(0, 2, s2.data()) < 0);
|
||||
BOOST_TEST(s2.compare(0, 1, s1.data()) > 0);
|
||||
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
BOOST_TEST(s1.compare(s2.subview()) < 0);
|
||||
BOOST_TEST(s2.compare(s1.subview()) > 0);
|
||||
|
||||
@ -2296,6 +2425,7 @@ testCompare()
|
||||
|
||||
BOOST_TEST(s1.compare(0, 2, s2.subview(), 0, 1) < 0);
|
||||
BOOST_TEST(s2.compare(0, 1, s1.subview(), 0, 2) > 0);
|
||||
#endif
|
||||
|
||||
BOOST_TEST(s1 < "10");
|
||||
BOOST_TEST(s2 > "1");
|
||||
@ -2304,6 +2434,14 @@ testCompare()
|
||||
BOOST_TEST(s1 < "20");
|
||||
BOOST_TEST(s2 > "1");
|
||||
BOOST_TEST(s2 > "2");
|
||||
|
||||
BOOST_TEST(s1 < string_like("10"));
|
||||
BOOST_TEST(s2 > string_like("1"));
|
||||
BOOST_TEST(string_like("10") > s1);
|
||||
BOOST_TEST(string_like("1") < s2);
|
||||
BOOST_TEST(s1 < string_like("20"));
|
||||
BOOST_TEST(s2 > string_like("1"));
|
||||
BOOST_TEST(s2 > string_like("2"));
|
||||
}
|
||||
{
|
||||
str2 s1("x");
|
||||
@ -2339,6 +2477,19 @@ testCompare()
|
||||
BOOST_TEST(! ("x" < s));
|
||||
BOOST_TEST(! ("x" > s));
|
||||
BOOST_TEST(! ("x" != s));
|
||||
|
||||
BOOST_TEST(s == string_like("x"));
|
||||
BOOST_TEST(s <= string_like("x"));
|
||||
BOOST_TEST(s >= string_like("x"));
|
||||
BOOST_TEST(! (s < string_like("x")));
|
||||
BOOST_TEST(! (s > string_like("x")));
|
||||
BOOST_TEST(! (s != string_like("x")));
|
||||
BOOST_TEST(string_like("x") == s);
|
||||
BOOST_TEST(string_like("x") <= s);
|
||||
BOOST_TEST(string_like("x") >= s);
|
||||
BOOST_TEST(! (string_like("x") < s));
|
||||
BOOST_TEST(! (string_like("x") > s));
|
||||
BOOST_TEST(! (string_like("x") != s));
|
||||
}
|
||||
{
|
||||
str2 s("x");
|
||||
@ -2354,6 +2505,19 @@ testCompare()
|
||||
BOOST_TEST(! ("y" == s));
|
||||
BOOST_TEST(! ("y" <= s));
|
||||
BOOST_TEST(! ("y" < s));
|
||||
|
||||
BOOST_TEST(s <= string_like("y"));
|
||||
BOOST_TEST(s < string_like("y"));
|
||||
BOOST_TEST(s != string_like("y"));
|
||||
BOOST_TEST(! (s == string_like("y")));
|
||||
BOOST_TEST(! (s >= string_like("y")));
|
||||
BOOST_TEST(! (s > "x"));
|
||||
BOOST_TEST(string_like("y") >= s);
|
||||
BOOST_TEST(string_like("y") > s);
|
||||
BOOST_TEST(string_like("y") != s);
|
||||
BOOST_TEST(! (string_like("y") == s));
|
||||
BOOST_TEST(! (string_like("y") <= s));
|
||||
BOOST_TEST(! (string_like("y") < s));
|
||||
}
|
||||
{
|
||||
str1 s1("x");
|
||||
@ -3815,8 +3979,8 @@ testFind()
|
||||
{
|
||||
const char* cs1 = "12345";
|
||||
const char* cs2 = "2345";
|
||||
string_view v1 = cs1;
|
||||
string_view v2 = cs2;
|
||||
string_like v1 = cs1;
|
||||
string_like v2 = cs2;
|
||||
static_string<5> fs1 = cs1;
|
||||
static_string<4> fs2 = cs2;
|
||||
using S = static_string<400>;
|
||||
@ -5139,8 +5303,8 @@ testFind()
|
||||
|
||||
const char* cs3 = "12456";
|
||||
const char* cs4 = "2356";
|
||||
string_view v3 = cs3;
|
||||
string_view v4 = cs4;
|
||||
string_like v3 = cs3;
|
||||
string_like v4 = cs4;
|
||||
static_string<5> fs3 = cs3;
|
||||
static_string<4> fs4 = cs4;
|
||||
|
||||
@ -5925,12 +6089,12 @@ testReplace()
|
||||
// replace(size_type pos1, size_type n1, const T& t);
|
||||
{
|
||||
static_string<20> fs1 = "helloworld";
|
||||
BOOST_TEST(fs1.replace(0, fs1.size(), string_view(fs1)) == "helloworld");
|
||||
BOOST_TEST(fs1.replace(0, fs1.size(), string_like(fs1.data(), fs1.size())) == "helloworld");
|
||||
}
|
||||
// replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos);
|
||||
{
|
||||
static_string<20> fs1 = "helloworld";
|
||||
BOOST_TEST(fs1.replace(0, fs1.size(), string_view(fs1), 0, fs1.size()) == "helloworld");
|
||||
BOOST_TEST(fs1.replace(0, fs1.size(), string_like(fs1.data(), fs1.size()), 0, fs1.size()) == "helloworld");
|
||||
}
|
||||
// replace(size_type pos, size_type n, const charT * s);
|
||||
{
|
||||
@ -5956,7 +6120,7 @@ testReplace()
|
||||
// replace(const_iterator i1, const_iterator i2, const T& t);
|
||||
{
|
||||
static_string<20> fs1 = "helloworld";
|
||||
BOOST_TEST(fs1.replace(fs1.begin(), fs1.end(), string_view(fs1)) == "helloworld");
|
||||
BOOST_TEST(fs1.replace(fs1.begin(), fs1.end(), string_like(fs1.data(), fs1.size())) == "helloworld");
|
||||
}
|
||||
// replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
|
||||
{
|
||||
@ -7103,21 +7267,21 @@ testStartsEnds()
|
||||
BOOST_TEST(S("1234567890").starts_with("1234567890"));
|
||||
BOOST_TEST(!S("1234567890").starts_with("234"));
|
||||
BOOST_TEST(!S("1234567890").starts_with("12345678900"));
|
||||
BOOST_TEST(S("1234567890").starts_with(string_view("1234567890")));
|
||||
BOOST_TEST(S("1234567890").starts_with(string_like("1234567890")));
|
||||
|
||||
BOOST_TEST(S("1234567890").ends_with('0'));
|
||||
BOOST_TEST(S("1234567890").ends_with("890"));
|
||||
BOOST_TEST(S("1234567890").ends_with("1234567890"));
|
||||
BOOST_TEST(!S("1234567890").ends_with("234"));
|
||||
BOOST_TEST(!S("1234567890").ends_with("12345678900"));
|
||||
BOOST_TEST(S("1234567890").ends_with(string_view("1234567890")));
|
||||
BOOST_TEST(S("1234567890").ends_with(string_like("1234567890")));
|
||||
|
||||
BOOST_TEST(!S().starts_with('0'));
|
||||
BOOST_TEST(!S().starts_with("0"));
|
||||
BOOST_TEST(!S().starts_with(string_view("0")));
|
||||
BOOST_TEST(!S().starts_with(string_like("0")));
|
||||
BOOST_TEST(!S().ends_with('0'));
|
||||
BOOST_TEST(!S().ends_with("0"));
|
||||
BOOST_TEST(!S().ends_with(string_view("0")));
|
||||
BOOST_TEST(!S().ends_with(string_like("0")));
|
||||
}
|
||||
|
||||
void
|
||||
@ -7158,7 +7322,9 @@ testStream()
|
||||
static_string<10> b = "abcdefghij";
|
||||
a << b;
|
||||
static_string<10> c(std::istream_iterator<char>{a}, std::istream_iterator<char>{});
|
||||
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
|
||||
BOOST_TEST(a.str() == b.subview());
|
||||
#endif
|
||||
BOOST_TEST(b == c);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user