#ifndef BOOST_STATIC_STRING_STATIC_STRING_HPP
#define BOOST_STATIC_STRING_STATIC_STRING_HPP
#if defined(__GNUC__) && __GNUC__ >= 8
#pragma GCC diagnostic push
#pragma GCC system_header
#pragma GCC diagnostic ignored "-Warray-bounds"
#pragma GCC diagnostic ignored "-Wrestrict"
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#if defined(__GNUC__) && __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnoexcept-type"
#endif
#ifndef BOOST_STATIC_STRING_CONFIG_HPP
#include <boost/static_string/config.hpp>
#include <boost/config/workaround.hpp>
#endif
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <functional>
#include <initializer_list>
#include <limits>
#include <iosfwd>
#include <type_traits>
namespace boost {
namespace static_strings {
#ifndef BOOST_STATIC_STRING_DOCS
template<std::size_t N, typename CharT, typename Traits>
class basic_static_string;
template<std::size_t N>
using static_string =
basic_static_string<N, char, std::char_traits<char>>;
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N>
using static_wstring =
basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
#endif
template<std::size_t N>
using static_u16string =
basic_static_string<N, char16_t, std::char_traits<char16_t>>;
template<std::size_t N>
using static_u32string =
basic_static_string<N, char32_t, std::char_traits<char32_t>>;
#ifdef __cpp_char8_t
template<std::size_t N>
using static_u8string =
basic_static_string<N, char8_t, std::char_traits<char8_t>>;
#endif
namespace detail {
template<std::size_t N>
using smallest_width =
typename std::conditional<(N <= (std::numeric_limits<unsigned char>::max)()), unsigned char,
typename std::conditional<(N <= (std::numeric_limits<unsigned short>::max)()), unsigned short,
typename std::conditional<(N <= (std::numeric_limits<unsigned int>::max)()), unsigned int,
typename std::conditional<(N <= (std::numeric_limits<unsigned long>::max)()), unsigned long,
typename std::conditional<(N <= (std::numeric_limits<unsigned long long>::max)()), unsigned long long,
std::size_t>::type>::type>::type>::type>::type;
template<typename To>
void is_nothrow_convertible_helper(To) noexcept;
template<typename From, typename To, typename =
decltype(is_nothrow_convertible_helper<To>(std::declval<From>()))>
struct is_nothrow_convertible_msvc_helper
{
static const bool value =
noexcept(is_nothrow_convertible_helper<To>(std::declval<From>()));
};
template<typename From, typename To, typename = void>
struct is_nothrow_convertible
: std::false_type { };
template<typename From, typename To>
struct is_nothrow_convertible<From, To, typename std::enable_if<
is_nothrow_convertible_msvc_helper<From, To>::value>::type>
: std::true_type { };
template<typename...>
struct void_t_helper
{
using type = void;
};
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
{};
template<std::size_t N, typename T, typename CharT, typename Traits, typename = void>
struct enable_if_viewable { };
template<std::size_t N, typename T, typename CharT, typename Traits>
struct enable_if_viewable<N, T, CharT, Traits,
typename std::enable_if<
#if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
is_string_like<T, CharT>::value &&
!std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::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 &&
!std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::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 &&
!std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
#endif
>::type>
{
using type = void;
};
template<std::size_t N, typename T, typename CharT, typename Traits>
using enable_if_viewable_t = typename enable_if_viewable<N, T, CharT, Traits>::type;
#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
template<typename T, typename = void>
struct is_iterator : std::false_type { };
template<typename T>
struct is_iterator<T,
typename std::enable_if<std::is_class<T>::value,
void_t<typename T::iterator_category>>::type>
: std::true_type { };
template<typename T>
struct is_iterator<T*, void>
: std::true_type { };
template<typename T, typename = void>
struct is_input_iterator : std::false_type { };
template<typename T>
struct is_input_iterator<T, typename std::enable_if<is_iterator<T>::value &&
std::is_convertible<typename std::iterator_traits<T>::iterator_category,
std::input_iterator_tag>::value>::type>
: std::true_type { };
template<typename T, typename = void>
struct is_forward_iterator : std::false_type { };
template<typename T>
struct is_forward_iterator<T, typename std::enable_if<is_iterator<T>::value &&
std::is_convertible<typename std::iterator_traits<T>::iterator_category,
std::forward_iterator_tag>::value>::type>
: std::true_type { };
template<typename T, typename = void>
struct is_subtractable
: std::false_type { };
template<typename T>
struct is_subtractable<T, void_t<decltype(std::declval<T&>() - std::declval<T&>())>>
: std::true_type { };
template<
typename ForwardIt,
typename std::enable_if<!is_subtractable<ForwardIt>::value>::type* = nullptr>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
std::size_t
distance(ForwardIt first, ForwardIt last)
{
std::size_t dist = 0;
for (; first != last; ++first, ++dist);
return dist;
}
template<
typename RandomIt,
typename std::enable_if<is_subtractable<RandomIt>::value>::type* = nullptr>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
std::size_t
distance(RandomIt first, RandomIt last)
{
return last - first;
}
template<typename Traits, typename InputIt, typename CharT>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
copy_with_traits(
InputIt first,
InputIt last,
CharT* out)
{
for (; first != last; ++first, ++out)
Traits::assign(*out, *first);
}
template<std::size_t N, typename CharT, typename Traits>
class static_string_base
{
private:
using size_type = smallest_width<N>;
using value_type = typename Traits::char_type;
using pointer = value_type*;
using const_pointer = const value_type*;
public:
BOOST_STATIC_STRING_CPP11_CONSTEXPR
static_string_base() noexcept { };
BOOST_STATIC_STRING_CPP14_CONSTEXPR
pointer
data_impl() noexcept
{
return data_;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_pointer
data_impl() const noexcept
{
return data_;
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
std::size_t
size_impl() const noexcept
{
return size_;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
std::size_t
set_size(std::size_t n) noexcept
{
return size_ = size_type(n);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
term_impl() noexcept
{
Traits::assign(data_[size_], value_type());
}
size_type size_ = 0;
value_type data_[N + 1]{};
};
template<typename CharT, typename Traits>
class static_string_base<0, CharT, Traits>
{
private:
using value_type = typename Traits::char_type;
using pointer = value_type*;
public:
BOOST_STATIC_STRING_CPP11_CONSTEXPR
static_string_base() noexcept { }
BOOST_STATIC_STRING_CPP11_CONSTEXPR
pointer
data_impl() const noexcept
{
return const_cast<pointer>(&null_);
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
std::size_t
size_impl() const noexcept
{
return 0;
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
std::size_t
set_size(std::size_t) const noexcept
{
return 0;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
term_impl() const noexcept { }
private:
static constexpr const value_type null_{};
};
#ifndef BOOST_STATIC_STRING_CPP17
template<typename CharT, typename Traits>
constexpr
const
typename static_string_base<0, CharT, Traits>::value_type
static_string_base<0, CharT, Traits>::
null_;
#endif
template<typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
int
lexicographical_compare(
const CharT* s1,
std::size_t n1,
const CharT* s2,
std::size_t n2) noexcept
{
if(n1 < n2)
return Traits::compare(
s1, s2, n1) <= 0 ? -1 : 1;
if(n1 > n2)
return Traits::compare(
s1, s2, n2) >= 0 ? 1 : -1;
return Traits::compare(s1, s2, n1);
}
template<typename Traits, typename Integer>
inline
char*
integer_to_string(
char* str_end,
Integer value,
std::true_type) noexcept
{
if (value == 0)
{
Traits::assign(*--str_end, '0');
return str_end;
}
if (value < 0)
{
const bool is_min = value == (std::numeric_limits<Integer>::min)();
if (is_min)
value = (std::numeric_limits<Integer>::max)();
else
value = -value;
const auto last_char = str_end - 1;
for (; value > 0; value /= 10)
Traits::assign(*--str_end, "0123456789"[value % 10]);
if (is_min)
Traits::assign(*last_char, Traits::to_char_type(
Traits::to_int_type(*last_char) + 1));
Traits::assign(*--str_end, '-');
return str_end;
}
for (; value > 0; value /= 10)
Traits::assign(*--str_end, "0123456789"[value % 10]);
return str_end;
}
template<typename Traits, typename Integer>
inline
char*
integer_to_string(
char* str_end,
Integer value,
std::false_type) noexcept
{
if (value == 0)
{
Traits::assign(*--str_end, '0');
return str_end;
}
for (; value > 0; value /= 10)
Traits::assign(*--str_end, "0123456789"[value % 10]);
return str_end;
}
template<typename Traits, typename Integer>
inline
wchar_t*
integer_to_wstring(
wchar_t* str_end,
Integer value,
std::true_type) noexcept
{
if (value == 0)
{
Traits::assign(*--str_end, L'0');
return str_end;
}
if (value < 0)
{
const bool is_min = value == (std::numeric_limits<Integer>::min)();
if (is_min)
value = (std::numeric_limits<Integer>::max)();
else
value = -value;
const auto last_char = str_end - 1;
for (; value > 0; value /= 10)
Traits::assign(*--str_end, L"0123456789"[value % 10]);
if (is_min)
Traits::assign(*last_char, Traits::to_char_type(
Traits::to_int_type(*last_char) + 1));
Traits::assign(*--str_end, L'-');
return str_end;
}
for (; value > 0; value /= 10)
Traits::assign(*--str_end, L"0123456789"[value % 10]);
return str_end;
}
template<typename Traits, typename Integer>
inline
wchar_t*
integer_to_wstring(
wchar_t* str_end,
Integer value,
std::false_type) noexcept
{
if (value == 0)
{
Traits::assign(*--str_end, L'0');
return str_end;
}
for (; value > 0; value /= 10)
Traits::assign(*--str_end, L"0123456789"[value % 10]);
return str_end;
}
template<std::size_t N, typename Integer>
inline
static_string<N>
to_static_string_int_impl(Integer value) noexcept
{
char buffer[N];
const auto digits_end = std::end(buffer);
const auto digits_begin = integer_to_string<std::char_traits<char>, Integer>(
digits_end, value, std::is_signed<Integer>{});
return static_string<N>(digits_begin, std::distance(digits_begin, digits_end));
}
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N, typename Integer>
inline
static_wstring<N>
to_static_wstring_int_impl(Integer value) noexcept
{
wchar_t buffer[N];
const auto digits_end = std::end(buffer);
const auto digits_begin = integer_to_wstring<std::char_traits<wchar_t>, Integer>(
digits_end, value, std::is_signed<Integer>{});
return static_wstring<N>(digits_begin, std::distance(digits_begin, digits_end));
}
#endif
BOOST_STATIC_STRING_CPP11_CONSTEXPR
inline
int
count_digits(std::size_t value)
{
return value < 10 ? 1 : count_digits(value / 10) + 1;
}
#if defined(__GNUC__) && __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
template<std::size_t N>
inline
static_string<N>
to_static_string_float_impl(double value) noexcept
{
const long long narrow =
static_cast<long long>(N);
char buffer[N + 1];
if (std::size_t(std::snprintf(buffer, N + 1, "%f", value)) > N)
{
const int reserved_count =
(std::max)(2, count_digits(
std::numeric_limits<double>::max_exponent10)) + 4;
const int precision = narrow > reserved_count ?
N - reserved_count : 0;
std::snprintf(buffer, N + 1, "%.*e", precision, value);
}
return static_string<N>(buffer);
}
template<std::size_t N>
inline
static_string<N>
to_static_string_float_impl(long double value) noexcept
{
const long long narrow =
static_cast<long long>(N);
char buffer[N + 1];
if (std::size_t(std::snprintf(buffer, N + 1, "%Lf", value)) > N)
{
const int reserved_count =
(std::max)(2, count_digits(
std::numeric_limits<long double>::max_exponent10)) + 4;
const int precision = narrow > reserved_count ?
N - reserved_count : 0;
std::snprintf(buffer, N + 1, "%.*Le", precision, value);
}
return static_string<N>(buffer);
}
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N>
inline
static_wstring<N>
to_static_wstring_float_impl(double value) noexcept
{
const long long narrow =
static_cast<long long>(N);
wchar_t buffer[N + 1];
const long long num_written =
std::swprintf(buffer, N + 1, L"%f", value);
if (num_written < 0 ||
num_written > narrow)
{
const int reserved_count =
(std::max)(2, count_digits(
std::numeric_limits<double>::max_exponent10)) + 4;
const int precision = narrow > reserved_count ?
N - reserved_count : 0;
std::swprintf(buffer, N + 1, L"%.*e", precision, value);
}
return static_wstring<N>(buffer);
}
template<std::size_t N>
inline
static_wstring<N>
to_static_wstring_float_impl(long double value) noexcept
{
const long long narrow =
static_cast<long long>(N);
wchar_t buffer[N + 1];
const long long num_written =
std::swprintf(buffer, N + 1, L"%Lf", value);
if (num_written < 0 ||
num_written > narrow)
{
const int reserved_count =
(std::max)(2, count_digits(
std::numeric_limits<long double>::max_exponent10)) + 4;
const int precision = narrow > reserved_count ?
N - reserved_count : 0;
std::swprintf(buffer, N + 1, L"%.*Le", precision, value);
}
return static_wstring<N>(buffer);
}
#endif
#if defined(__GNUC__) && __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
template<typename Traits, typename CharT, typename ForwardIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
ForwardIterator
find_not_of(
ForwardIterator first,
ForwardIterator last,
const CharT* str,
std::size_t n) noexcept
{
for (; first != last; ++first)
if (!Traits::find(str, n, *first))
return first;
return last;
}
template<typename ForwardIt1, typename ForwardIt2, typename BinaryPredicate>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
ForwardIt1
search(
ForwardIt1 first,
ForwardIt1 last,
ForwardIt2 s_first,
ForwardIt2 s_last,
BinaryPredicate p)
{
for (; ; ++first)
{
ForwardIt1 it = first;
for (ForwardIt2 s_it = s_first; ; ++it, ++s_it)
{
if (s_it == s_last)
return first;
if (it == last)
return last;
if (!p(*it, *s_it))
break;
}
}
}
template<typename InputIt, typename ForwardIt, typename BinaryPredicate>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
InputIt
find_first_of(
InputIt first,
InputIt last,
ForwardIt s_first,
ForwardIt s_last,
BinaryPredicate p)
{
for (; first != last; ++first)
for (ForwardIt it = s_first; it != s_last; ++it)
if (p(*first, *it))
return first;
return last;
}
template<typename T>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
ptr_in_range(
const T* src_first,
const T* src_last,
const T* ptr)
{
#if defined(BOOST_STATIC_STRING_CPP14) && \
defined(BOOST_STATIC_STRING_IS_CONST_EVAL)
if (BOOST_STATIC_STRING_IS_CONST_EVAL)
{
for (; src_first != src_last; ++src_first)
if (ptr == src_first)
return true;
return false;
}
#endif
#if defined(BOOST_STATIC_STRING_CPP14) && \
defined(BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS)
return ptr >= src_first && ptr < src_last;
#else
return std::greater_equal<const T*>()(ptr, src_first) &&
std::less<const T*>()(ptr, src_last);
#endif
}
#ifdef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
template<typename Exception>
struct throw_exception
{
BOOST_STATIC_STRING_NORETURN
BOOST_STATIC_STRING_CPP14_CONSTEXPR
throw_exception(const char* msg)
{
BOOST_STATIC_STRING_THROW(Exception(msg));
}
};
#else
template<typename Exception>
BOOST_STATIC_STRING_NORETURN
inline
void
throw_exception(const char* msg)
{
BOOST_STATIC_STRING_THROW(Exception(msg));
}
#endif
} #endif
template<std::size_t N, typename CharT,
typename Traits = std::char_traits<CharT>>
class basic_static_string
#ifndef BOOST_STATIC_STRING_DOCS
: private detail::static_string_base<N, CharT, Traits>
#endif
{
private:
template<std::size_t, class, class>
friend class basic_static_string;
public:
using traits_type = Traits;
using value_type = typename traits_type::char_type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
using const_pointer = const value_type*;
using const_reference = const value_type&;
using iterator = value_type*;
using const_iterator = const value_type*;
using reverse_iterator =
std::reverse_iterator<iterator>;
using const_reverse_iterator =
std::reverse_iterator<const_iterator>;
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
using string_view_type =
basic_string_view<value_type, traits_type>;
#endif
static constexpr size_type static_capacity = N;
static constexpr size_type npos = size_type(-1);
BOOST_STATIC_STRING_CPP11_CONSTEXPR
basic_static_string() noexcept
{
#ifdef BOOST_STATIC_STRING_CPP20
term();
#endif
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
size_type count,
value_type ch)
{
assign(count, ch);
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
const basic_static_string<M, CharT, Traits>& other,
size_type pos)
{
assign(other, pos);
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
const basic_static_string<M, CharT, Traits>& other,
size_type pos,
size_type count)
{
assign(other, pos, count);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
const_pointer s,
size_type count)
{
assign(s, count);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const_pointer s)
{
assign(s);
}
template<typename InputIterator
#ifndef BOOST_STATIC_STRING_DOCS
, typename std::enable_if<
detail::is_input_iterator<InputIterator>
::value>::type* = nullptr
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
InputIterator first,
InputIterator last)
{
assign(first, last);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const basic_static_string& other) noexcept
{
assign(other);
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
const basic_static_string<M, CharT, Traits>& other)
{
assign(other);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(std::initializer_list<value_type> init)
{
assign(init.begin(), init.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
explicit
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(const T& t)
{
assign(t);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string(
const T& t,
size_type pos,
size_type n)
{
assign(t, pos, n);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator=(const basic_static_string& s)
{
return assign(s);
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator=(const basic_static_string<M, CharT, Traits>& s)
{
return assign(s);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator=(const_pointer s)
{
return assign(s);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator=(value_type ch)
{
return assign_char(ch,
std::integral_constant<bool, (N > 0)>{});
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator=(std::initializer_list<value_type> ilist)
{
return assign(ilist);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator=(const T& t)
{
return assign(t);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(
size_type count,
value_type ch);
template<std::size_t M
#ifndef BOOST_STATIC_STRING_DOCS
, typename std::enable_if<(M < N)>::type* = nullptr
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(const basic_static_string<M, CharT, Traits>& s)
{
return assign_unchecked(s.data(), s.size());
}
#ifndef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(const basic_static_string& s) noexcept
{
if (data() == s.data())
return *this;
return assign_unchecked(s.data(), s.size());
}
template<std::size_t M,
typename std::enable_if<(M > N)>::type* = nullptr>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(const basic_static_string<M, CharT, Traits>& s)
{
return assign(s.data(), s.size());
}
#endif
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(
const basic_static_string<M, CharT, Traits>& s,
size_type pos,
size_type count = npos)
{
return assign(s.data() + pos, s.capped_length(pos, count));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(
const_pointer s,
size_type count);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(const_pointer s)
{
return assign(s, traits_type::length(s));
}
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
#ifdef BOOST_STATIC_STRING_DOCS
basic_static_string&
#else
typename std::enable_if<
detail::is_input_iterator<InputIterator>::value,
basic_static_string&>::type
#endif
assign(
InputIterator first,
InputIterator last);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(
std::initializer_list<value_type> ilist)
{
return assign(ilist.begin(), ilist.end());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign(const T& t)
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return assign(sv.data(), sv.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
basic_static_string&
assign(
const T& t,
size_type pos,
size_type count = npos)
{
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);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
reference
at(size_type pos)
{
if (pos >= size())
detail::throw_exception<std::out_of_range>(
"pos >= size()");
return data()[pos];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_reference
at(size_type pos) const
{
if (pos >= size())
detail::throw_exception<std::out_of_range>(
"pos >= size()");
return data()[pos];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
reference
operator[](size_type pos) noexcept
{
return data()[pos];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_reference
operator[](size_type pos) const noexcept
{
return data()[pos];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
reference
front() noexcept
{
return data()[0];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_reference
front() const noexcept
{
return data()[0];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
reference
back() noexcept
{
return data()[size() - 1];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_reference
back() const noexcept
{
return data()[size() - 1];
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
pointer
data() noexcept
{
return this->data_impl();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_pointer
data() const noexcept
{
return this->data_impl();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_pointer
c_str() const noexcept
{
return data();
}
#ifdef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP11_CONSTEXPR
operator string_view_type() const noexcept
{
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
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
begin() noexcept
{
return data();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_iterator
begin() const noexcept
{
return data();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_iterator
cbegin() const noexcept
{
return data();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
end() noexcept
{
return data() + size();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_iterator
end() const noexcept
{
return data() + size();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
const_iterator
cend() const noexcept
{
return data() + size();
}
BOOST_STATIC_STRING_CPP17_CONSTEXPR
reverse_iterator
rbegin() noexcept
{
return reverse_iterator{end()};
}
BOOST_STATIC_STRING_CPP17_CONSTEXPR
const_reverse_iterator
rbegin() const noexcept
{
return const_reverse_iterator{cend()};
}
BOOST_STATIC_STRING_CPP17_CONSTEXPR
const_reverse_iterator
crbegin() const noexcept
{
return const_reverse_iterator{cend()};
}
BOOST_STATIC_STRING_CPP17_CONSTEXPR
reverse_iterator
rend() noexcept
{
return reverse_iterator{begin()};
}
BOOST_STATIC_STRING_CPP17_CONSTEXPR
const_reverse_iterator
rend() const noexcept
{
return const_reverse_iterator{cbegin()};
}
BOOST_STATIC_STRING_CPP17_CONSTEXPR
const_reverse_iterator
crend() const noexcept
{
return const_reverse_iterator{cbegin()};
}
BOOST_STATIC_STRING_NODISCARD
BOOST_STATIC_STRING_CPP11_CONSTEXPR
bool
empty() const noexcept
{
return size() == 0;
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
size_type
size() const noexcept
{
return this->size_impl();
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
size_type
length() const noexcept
{
return size();
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
size_type
max_size() const noexcept
{
return N;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
reserve(size_type n)
{
if (n > max_size())
detail::throw_exception<std::length_error>(
"n > max_size()");
}
BOOST_STATIC_STRING_CPP11_CONSTEXPR
size_type
capacity() const noexcept
{
return max_size();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
shrink_to_fit() noexcept { }
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
clear() noexcept
{
this->set_size(0);
term();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
size_type count,
value_type ch)
{
if (index > size())
detail::throw_exception<std::out_of_range>(
"index > size()");
insert(begin() + index, count, ch);
return *this;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const_pointer s)
{
return insert(index, s, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const_pointer s,
size_type count)
{
if (index > size())
detail::throw_exception<std::out_of_range>(
"index > size()");
insert(data() + index, s, s + count);
return *this;
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const basic_static_string<M, CharT, Traits>& str)
{
return insert_unchecked(index, str.data(), str.size());
}
#ifndef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const basic_static_string& str)
{
return insert(index, str.data(), str.size());
}
#endif
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const basic_static_string<M, CharT, Traits>& str,
size_type index_str,
size_type count = npos)
{
return insert_unchecked(index, str.data() + index_str, str.capped_length(index_str, count));
}
#ifndef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const basic_static_string& str,
size_type index_str,
size_type count = npos)
{
return insert(index, str.data() + index_str, str.capped_length(index_str, count));
}
#endif
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
insert(
const_iterator pos,
value_type ch)
{
return insert(pos, 1, ch);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
insert(
const_iterator pos,
size_type count,
value_type ch);
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
#ifdef BOOST_STATIC_STRING_DOCS
iterator
#else
typename std::enable_if<
detail::is_input_iterator<
InputIterator>::value &&
!detail::is_forward_iterator<
InputIterator>::value, iterator>::type
#endif
insert(
const_iterator pos,
InputIterator first,
InputIterator last);
#ifndef BOOST_STATIC_STRING_DOCS
template<typename ForwardIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
typename std::enable_if<
detail::is_forward_iterator<
ForwardIterator>::value,
iterator>::type
insert(
const_iterator pos,
ForwardIterator first,
ForwardIterator last);
#endif
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
insert(
const_iterator pos,
std::initializer_list<value_type> ilist)
{
return insert_unchecked(pos, ilist.begin(), ilist.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const T& t)
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return insert(index, sv.data(), sv.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert(
size_type index,
const T& t,
size_type index_str,
size_type count = npos)
{
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));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
erase(
size_type index = 0,
size_type count = npos)
{
erase(data() + index, data() + index + capped_length(index, count));
return *this;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
erase(const_iterator pos)
{
BOOST_STATIC_STRING_ASSERT(!empty());
return erase(pos, pos + 1);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
erase(
const_iterator first,
const_iterator last);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
push_back(value_type ch);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
pop_back() noexcept
{
BOOST_STATIC_STRING_ASSERT(!empty());
this->set_size(size() - 1);
term();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(
size_type count,
value_type ch);
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(
const basic_static_string<M, CharT, Traits>& s)
{
return append(s.data(), s.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(
const basic_static_string<M, CharT, Traits>& s,
size_type pos,
size_type count = npos)
{
return append(s.data() + pos, s.capped_length(pos, count));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(
const_pointer s,
size_type count);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(const_pointer s)
{
return append(s, traits_type::length(s));
}
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
#ifdef BOOST_STATIC_STRING_DOCS
basic_static_string&
#else
typename std::enable_if<
detail::is_input_iterator<InputIterator>::value,
basic_static_string&>::type
#endif
append(
InputIterator first,
InputIterator last)
{
this->set_size(size() + read_back(true, first, last));
return term();
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(
std::initializer_list<value_type> ilist)
{
return append(ilist.begin(), ilist.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(const T& t)
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return append(sv.data(), sv.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
append(
const T& t,
size_type pos,
size_type count = npos)
{
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));
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator+=(
const basic_static_string<M, CharT, Traits>& s)
{
return append(s);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator+=(value_type ch)
{
push_back(ch);
return *this;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator+=(const_pointer s)
{
return append(s);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator+=(
std::initializer_list<value_type> ilist)
{
return append(ilist);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
operator+=(const T& t)
{
return append(t);
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
const basic_static_string<M, CharT, Traits>& s) const noexcept
{
return detail::lexicographical_compare<CharT, Traits>(
data(), size(), s.data(), s.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
size_type pos1,
size_type count1,
const basic_static_string<M, CharT, Traits>& s) const
{
return detail::lexicographical_compare<CharT, Traits>(
data() + pos1, capped_length(pos1, count1), s.data(), s.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
size_type pos1,
size_type count1,
const basic_static_string<M, CharT, Traits>& s,
size_type pos2,
size_type count2 = npos) const
{
return detail::lexicographical_compare<CharT, Traits>(
data() + pos1, capped_length(pos1, count1),
s.data() + pos2, s.capped_length(pos2, count2));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(const_pointer s) const noexcept
{
return detail::lexicographical_compare<CharT, Traits>(
data(), size(), s, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
size_type pos1,
size_type count1,
const_pointer s) const
{
return detail::lexicographical_compare<CharT, Traits>(
data() + pos1, capped_length(pos1, count1), s, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
size_type pos1,
size_type count1,
const_pointer s,
size_type count2) const
{
return detail::lexicographical_compare<CharT, Traits>(
data() + pos1, capped_length(pos1, count1), s, count2);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(const T& t) const noexcept
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return detail::lexicographical_compare<CharT, Traits>(
data(), size(), sv.data(), sv.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
size_type pos1,
size_type count1,
const T& t) const
{
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());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
int
compare(
size_type pos1,
size_type count1,
const T& t,
size_type pos2,
size_type count2 = npos) const
{
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));
}
#ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
BOOST_STATIC_STRING_CPP14_CONSTEXPR
#endif
basic_static_string
substr(
size_type pos = 0,
size_type count = npos) const
{
return basic_static_string(
data() + pos, capped_length(pos, count));
}
#ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
BOOST_STATIC_STRING_CPP14_CONSTEXPR
string_view_type
subview(
size_type pos = 0,
size_type count = npos) const
{
return string_view_type(
data() + pos, capped_length(pos, count));
}
#endif
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
copy(
pointer dest,
size_type count,
size_type pos = 0) const
{
const auto num_copied = capped_length(pos, count);
traits_type::copy(dest, data() + pos, num_copied);
return num_copied;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
resize(size_type n)
{
resize(n, value_type());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
resize(
size_type n,
value_type c);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
swap(basic_static_string& s) noexcept;
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
swap(basic_static_string<M, CharT, Traits>& s);
template<size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos1,
size_type n1,
const basic_static_string<M, CharT, Traits>& str)
{
return replace_unchecked(pos1, n1, str.data(), str.size());
}
#ifndef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos1,
size_type n1,
const basic_static_string& str)
{
return replace(pos1, n1, str.data(), str.size());
}
#endif
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos1,
size_type n1,
const basic_static_string<M, CharT, Traits>& str,
size_type pos2,
size_type n2 = npos)
{
return replace_unchecked(pos1, n1, str.data() + pos2, str.capped_length(pos2, n2));
}
#ifndef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos1,
size_type n1,
const basic_static_string& str,
size_type pos2,
size_type n2 = npos)
{
return replace(pos1, n1, str.data() + pos2, str.capped_length(pos2, n2));
}
#endif
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos1,
size_type n1,
const T& t)
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return replace(pos1, n1, sv.data(), sv.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos1,
size_type n1,
const T& t,
size_type pos2,
size_type n2 = npos)
{
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));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos,
size_type n1,
const_pointer s,
size_type n2)
{
return replace(data() + pos, data() + pos + capped_length(pos, n1), s, n2);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos,
size_type n1,
const_pointer s)
{
return replace(pos, n1, s, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
size_type pos,
size_type n1,
size_type n2,
value_type c)
{
return replace(data() + pos, data() + pos + capped_length(pos, n1), n2, c);
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
const basic_static_string<M, CharT, Traits>& str)
{
return replace_unchecked(i1, i2, str.data(), str.size());
}
#ifndef BOOST_STATIC_STRING_DOCS
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
const basic_static_string& str)
{
return replace(i1, i2, str.data(), str.size());
}
#endif
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
const T& t)
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return replace(i1, i2, sv.data(), sv.data() + sv.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
const_pointer s,
size_type n)
{
return replace(i1, i2, s, s + n);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
const_pointer s)
{
return replace(i1, i2, s, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
size_type n,
value_type c);
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
#ifdef BOOST_STATIC_STRING_DOCS
basic_static_string&
#else
typename std::enable_if<
detail::is_input_iterator<
InputIterator>::value &&
!detail::is_forward_iterator<
InputIterator>::value,
basic_static_string<N, CharT, Traits>&>::type
#endif
replace(
const_iterator i1,
const_iterator i2,
InputIterator j1,
InputIterator j2);
#ifndef BOOST_STATIC_STRING_DOCS
template<typename ForwardIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
typename std::enable_if<
detail::is_forward_iterator<
ForwardIterator>::value,
basic_static_string<N, CharT, Traits>&>::type
replace(
const_iterator i1,
const_iterator i2,
ForwardIterator j1,
ForwardIterator j2);
#endif
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace(
const_iterator i1,
const_iterator i2,
std::initializer_list<value_type> il)
{
return replace_unchecked(i1, i2, il.begin(), il.size());
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
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
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return find(sv.data(), pos, sv.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find(
const basic_static_string<M, CharT, Traits>& str,
size_type pos = 0) const noexcept
{
return find(str.data(), pos, str.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find(
const_pointer s,
size_type pos,
size_type n) const noexcept;
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find(
const_pointer s,
size_type pos = 0) const noexcept
{
return find(s, pos, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find(
value_type c,
size_type pos = 0) const noexcept
{
return find(&c, pos, 1);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
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
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return rfind(sv.data(), pos, sv.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
rfind(
const basic_static_string<M, CharT, Traits>& str,
size_type pos = npos) const noexcept
{
return rfind(str.data(), pos, str.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
rfind(
const_pointer s,
size_type pos,
size_type n) const noexcept;
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
rfind(
const_pointer s,
size_type pos = npos) const noexcept
{
return rfind(s, pos, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
rfind(
value_type c,
size_type pos = npos) const noexcept
{
return rfind(&c, pos, 1);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
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
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return find_first_of(sv.data(), pos, sv.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_of(
const basic_static_string<M, CharT, Traits>& str,
size_type pos = 0) const noexcept
{
return find_first_of(str.data(), pos, str.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_of(
const_pointer s,
size_type pos,
size_type n) const noexcept;
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_of(
const_pointer s,
size_type pos = 0) const noexcept
{
return find_first_of(s, pos, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_of(
value_type c,
size_type pos = 0) const noexcept
{
return find_first_of(&c, pos, 1);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
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
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return find_last_of(sv.data(), pos, sv.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_of(
const basic_static_string<M, CharT, Traits>& str,
size_type pos = npos) const noexcept
{
return find_last_of(str.data(), pos, str.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_of(
const_pointer s,
size_type pos,
size_type n) const noexcept;
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_of(
const_pointer s,
size_type pos = npos) const noexcept
{
return find_last_of(s, pos, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_of(
value_type c,
size_type pos = npos) const noexcept
{
return find_last_of(&c, pos, 1);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
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
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return find_first_not_of(sv.data(), pos, sv.size());
}
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_not_of(
const basic_static_string<M, CharT, Traits>& str,
size_type pos = 0) const noexcept
{
return find_first_not_of(str.data(), pos, str.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_not_of(
const_pointer s,
size_type pos,
size_type n) const noexcept;
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_not_of(
const_pointer s,
size_type pos = 0) const noexcept
{
return find_first_not_of(s, pos, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_first_not_of(
value_type c,
size_type pos = 0) const noexcept
{
return find_first_not_of(&c, pos, 1);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
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
{
detail::common_string_view_type<T, CharT, Traits> sv = t;
return find_last_not_of(sv.data(), pos, sv.size());
}
template<size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_not_of(
const basic_static_string<M, CharT, Traits>& str,
size_type pos = npos) const noexcept
{
return find_last_not_of(str.data(), pos, str.size());
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_not_of(
const_pointer s,
size_type pos,
size_type n) const noexcept;
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_not_of(
const_pointer s,
size_type pos = npos) const noexcept
{
return find_last_not_of(s, pos, traits_type::length(s));
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
find_last_not_of(
value_type c,
size_type pos = npos) const noexcept
{
return find_last_not_of(&c, pos, 1);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
bool
starts_with(
T const& t) const noexcept
{
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);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
bool
starts_with(
value_type c) const noexcept
{
return !empty() && traits_type::eq(front(), c);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
bool
starts_with(
const_pointer s) const noexcept
{
const size_type len = traits_type::length(s);
return size() >= len && !traits_type::compare(data(), s, len);
}
template<typename T
#ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif
>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
bool
ends_with(
T const& t) const noexcept
{
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);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
bool
ends_with(
value_type c) const noexcept
{
return !empty() && traits_type::eq(back(), c);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
bool
ends_with(
const_pointer s) const noexcept
{
const size_type len = traits_type::length(s);
return size() >= len && !traits_type::compare(data() + (size() - len), s, len);
}
private:
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
term() noexcept
{
this->term_impl();
return *this;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign_char(value_type ch, std::true_type) noexcept
{
this->set_size(1);
traits_type::assign(data()[0], ch);
return term();
}
BOOST_STATIC_STRING_NORETURN
basic_static_string&
assign_char(value_type, std::false_type)
{
detail::throw_exception<std::length_error>("max_size() == 0");
#ifdef BOOST_STATIC_STRING_NO_NORETURN
return *this;
#endif
}
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
read_back(
bool overwrite_null,
InputIterator first,
InputIterator last);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace_unchecked(
size_type pos,
size_type n1,
const_pointer s,
size_type n2)
{
if (pos > size())
detail::throw_exception<std::out_of_range>(
"pos > size()");
return replace_unchecked(data() + pos, data() + pos + capped_length(pos, n1), s, n2);
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
replace_unchecked(
const_iterator i1,
const_iterator i2,
const_pointer s,
size_type n2);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
insert_unchecked(
size_type index,
const_pointer s,
size_type count)
{
if (index > size())
detail::throw_exception<std::out_of_range>(
"index > size()");
insert_unchecked(data() + index, s, count);
return *this;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
iterator
insert_unchecked(
const_iterator pos,
const_pointer s,
size_type count);
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string&
assign_unchecked(
const_pointer s,
size_type count) noexcept
{
this->set_size(count);
traits_type::copy(data(), s, size() + 1);
return *this;
}
BOOST_STATIC_STRING_CPP14_CONSTEXPR
size_type
capped_length(
size_type index,
size_type length) const
{
if (index > size())
detail::throw_exception<std::out_of_range>(
"index > size()");
return (std::min)(size() - index, length);
}
};
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator==(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return lhs.compare(rhs) == 0;
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator!=(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return lhs.compare(rhs) != 0;
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator<(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return lhs.compare(rhs) < 0;
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator<=(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return lhs.compare(rhs) <= 0;
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator>(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return lhs.compare(rhs) > 0;
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator>=(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return lhs.compare(rhs) >= 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator==(
const CharT* lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs, Traits::length(lhs),
rhs.data(), rhs.size()) == 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator==(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT* rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs.data(), lhs.size(),
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<N, 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<N, 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
bool
operator!=(
const CharT* lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs, Traits::length(lhs),
rhs.data(), rhs.size()) != 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator!=(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT* rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs.data(), lhs.size(),
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<N, 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<N, 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
bool
operator<(
const CharT* lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs, Traits::length(lhs),
rhs.data(), rhs.size()) < 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator<(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT* rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs.data(), lhs.size(),
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<N, 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<N, 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
bool
operator<=(
const CharT* lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs, Traits::length(lhs),
rhs.data(), rhs.size()) <= 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator<=(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT* rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs.data(), lhs.size(),
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<N, 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<N, 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
bool
operator>(
const CharT* lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs, Traits::length(lhs),
rhs.data(), rhs.size()) > 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator>(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT* rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs.data(), lhs.size(),
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<N, 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<N, 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
bool
operator>=(
const CharT* lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs, Traits::length(lhs),
rhs.data(), rhs.size()) >= 0;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
bool
operator>=(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT* rhs)
{
return detail::lexicographical_compare<CharT, Traits>(
lhs.data(), lhs.size(),
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<N, 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<N, 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>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
basic_static_string<N + M, CharT, Traits>
operator+(
const basic_static_string<N, CharT, Traits>& lhs,
const basic_static_string<M, CharT, Traits>& rhs)
{
return basic_static_string<N + M, CharT, Traits>(lhs) += rhs;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
basic_static_string<N + 1, CharT, Traits>
operator+(
const basic_static_string<N, CharT, Traits>& lhs,
CharT rhs)
{
return basic_static_string<N + 1, CharT, Traits>(lhs) += rhs;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
basic_static_string<N + 1, CharT, Traits>
operator+(
CharT lhs,
const basic_static_string<N, CharT, Traits>& rhs)
{
return basic_static_string<N + 1, CharT, Traits>(rhs).insert(
std::size_t(0), 1, lhs);
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
basic_static_string<N + M, CharT, Traits>
operator+(
const basic_static_string<N, CharT, Traits>& lhs,
const CharT(&rhs)[M])
{
return basic_static_string<N + M, CharT, Traits>(lhs).append(+rhs);
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
basic_static_string<N + M, CharT, Traits>
operator+(
const CharT(&lhs)[N],
const basic_static_string<M, CharT, Traits>& rhs)
{
return basic_static_string<N + M, CharT, Traits>(rhs).insert(
std::size_t(0), +lhs);
}
template<
std::size_t N, typename CharT,
typename Traits, typename UnaryPredicate>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
typename
basic_static_string<N, CharT, Traits>::size_type
erase_if(
basic_static_string<N, CharT, Traits>& str,
UnaryPredicate pred)
{
auto first = str.begin();
for (auto it = first; it != str.end(); ++it)
if (!pred(*it))
*first++ = std::move(*it);
const auto count = str.end() - first;
str.erase(first, str.end());
return count;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
void
swap(
basic_static_string<N, CharT, Traits>& lhs,
basic_static_string<N, CharT, Traits>& rhs)
{
lhs.swap(rhs);
}
template<
std::size_t N, std::size_t M,
typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
inline
void
swap(
basic_static_string<N, CharT, Traits>& lhs,
basic_static_string<M, CharT, Traits>& rhs)
{
lhs.swap(rhs);
}
template<std::size_t N, typename CharT, typename Traits>
inline
std::basic_ostream<CharT, Traits>&
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
}
static_string<std::numeric_limits<int>::digits10 + 2>
inline
to_static_string(int value) noexcept
{
return detail::to_static_string_int_impl<
std::numeric_limits<int>::digits10 + 2>(value);
}
static_string<std::numeric_limits<long>::digits10 + 2>
inline
to_static_string(long value) noexcept
{
return detail::to_static_string_int_impl<
std::numeric_limits<long>::digits10 + 2>(value);
}
static_string<std::numeric_limits<long long>::digits10 + 2>
inline
to_static_string(long long value) noexcept
{
return detail::to_static_string_int_impl<
std::numeric_limits<long long>::digits10 + 2>(value);
}
static_string<std::numeric_limits<unsigned int>::digits10 + 1>
inline
to_static_string(unsigned int value) noexcept
{
return detail::to_static_string_int_impl<
std::numeric_limits<unsigned int>::digits10 + 1>(value);
}
static_string<std::numeric_limits<unsigned long>::digits10 + 1>
inline
to_static_string(unsigned long value) noexcept
{
return detail::to_static_string_int_impl<
std::numeric_limits<unsigned long>::digits10 + 1>(value);
}
static_string<std::numeric_limits<unsigned long long>::digits10 + 1>
inline
to_static_string(unsigned long long value) noexcept
{
return detail::to_static_string_int_impl<
std::numeric_limits<unsigned long long>::digits10 + 1>(value);
}
static_string<std::numeric_limits<float>::max_digits10 + 4>
inline
to_static_string(float value) noexcept
{
return detail::to_static_string_float_impl<
std::numeric_limits<float>::max_digits10 + 4>(value);
}
static_string<std::numeric_limits<double>::max_digits10 + 4>
inline
to_static_string(double value) noexcept
{
return detail::to_static_string_float_impl<
std::numeric_limits<double>::max_digits10 + 4>(value);
}
static_string<std::numeric_limits<long double>::max_digits10 + 4>
inline
to_static_string(long double value) noexcept
{
return detail::to_static_string_float_impl<
std::numeric_limits<long double>::max_digits10 + 4>(value);
}
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
static_wstring<std::numeric_limits<int>::digits10 + 2>
inline
to_static_wstring(int value) noexcept
{
return detail::to_static_wstring_int_impl<
std::numeric_limits<int>::digits10 + 2>(value);
}
static_wstring<std::numeric_limits<long>::digits10 + 2>
inline
to_static_wstring(long value) noexcept
{
return detail::to_static_wstring_int_impl<
std::numeric_limits<long>::digits10 + 2>(value);
}
static_wstring<std::numeric_limits<long long>::digits10 + 2>
inline
to_static_wstring(long long value) noexcept
{
return detail::to_static_wstring_int_impl<
std::numeric_limits<long long>::digits10 + 2>(value);
}
static_wstring<std::numeric_limits<unsigned int>::digits10 + 1>
inline
to_static_wstring(unsigned int value) noexcept
{
return detail::to_static_wstring_int_impl<
std::numeric_limits<unsigned int>::digits10 + 1>(value);
}
static_wstring<std::numeric_limits<unsigned long>::digits10 + 1>
inline
to_static_wstring(unsigned long value) noexcept
{
return detail::to_static_wstring_int_impl<
std::numeric_limits<unsigned long>::digits10 + 1>(value);
}
static_wstring<std::numeric_limits<unsigned long long>::digits10 + 1>
inline
to_static_wstring(unsigned long long value) noexcept
{
return detail::to_static_wstring_int_impl<
std::numeric_limits<unsigned long long>::digits10 + 1>(value);
}
static_wstring<std::numeric_limits<float>::max_digits10 + 4>
inline
to_static_wstring(float value) noexcept
{
return detail::to_static_wstring_float_impl<
std::numeric_limits<float>::max_digits10 + 4>(value);
}
static_wstring<std::numeric_limits<double>::max_digits10 + 4>
inline
to_static_wstring(double value) noexcept
{
return detail::to_static_wstring_float_impl<
std::numeric_limits<double>::max_digits10 + 4>(value);
}
static_wstring<std::numeric_limits<long double>::max_digits10 + 4>
inline
to_static_wstring(long double value) noexcept
{
return detail::to_static_wstring_float_impl<
std::numeric_limits<long double>::max_digits10 + 4>(value);
}
#endif
#ifdef BOOST_STATIC_STRING_USE_DEDUCT
template<std::size_t N, typename CharT>
basic_static_string(const CharT(&)[N]) ->
basic_static_string<N, CharT, std::char_traits<CharT>>;
#endif
#ifndef BOOST_STATIC_STRING_STANDALONE
template <std::size_t N,
typename CharT,
typename Traits>
std::size_t
hash_value(
const basic_static_string<N, CharT, Traits>& str)
{
return boost::hash_range(str.begin(), str.end());
}
#endif
}
using static_strings::static_string;
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
using static_strings::static_wstring;
#endif
using static_strings::static_u16string;
using static_strings::static_u32string;
}
namespace std {
template<std::size_t N, typename CharT, typename Traits>
struct hash<
#ifdef BOOST_STATIC_STRING_DOCS
basic_static_string
#else
boost::static_strings::basic_static_string<N, CharT, Traits>
#endif
>
{
std::size_t
operator()(
const boost::static_strings::basic_static_string<N, CharT, Traits>& str) const noexcept
{
#if !defined(BOOST_STATIC_STRING_STANDALONE)
return boost::hash_range(str.begin(), str.end());
#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)
{
#if BOOST_STATIC_STRING_ARCH == 64
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;
#elif BOOST_STATIC_STRING_ARCH == 32
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;
#endif
}
return seed;
#endif
}
};
}
#ifndef BOOST_STATIC_STRING_DOCS
namespace boost {
namespace static_strings {
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
assign(
size_type count,
value_type ch) ->
basic_static_string&
{
if (count > max_size())
detail::throw_exception<std::length_error>(
"count > max_size()");
this->set_size(count);
traits_type::assign(data(), size(), ch);
return term();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
assign(
const_pointer s,
size_type count) ->
basic_static_string&
{
if (count > max_size())
detail::throw_exception<std::length_error>(
"count > max_size()");
this->set_size(count);
traits_type::move(data(), s, size());
return term();
}
template<std::size_t N, typename CharT, typename Traits>
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
assign(
InputIterator first,
InputIterator last) ->
typename std::enable_if<
detail::is_input_iterator<InputIterator>::value,
basic_static_string&>::type
{
auto ptr = data();
for (std::size_t i = 0; first != last; ++first, ++ptr, ++i)
{
if (i >= max_size())
{
this->set_size(i);
term();
detail::throw_exception<std::length_error>("n > max_size()");
}
traits_type::assign(*ptr, *first);
}
this->set_size(ptr - data());
return term();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
insert(
const_iterator pos,
size_type count,
value_type ch) ->
iterator
{
const auto curr_size = size();
const auto curr_data = data();
if (count > max_size() - curr_size)
detail::throw_exception<std::length_error>(
"count > max_size() - curr_size");
const auto index = pos - curr_data;
traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
traits_type::assign(&curr_data[index], count, ch);
this->set_size(curr_size + count);
return &curr_data[index];
}
template<std::size_t N, typename CharT, typename Traits>
template<typename ForwardIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
insert(
const_iterator pos,
ForwardIterator first,
ForwardIterator last) ->
typename std::enable_if<
detail::is_forward_iterator<
ForwardIterator>::value, iterator>::type
{
const std::size_t count = detail::distance(first, last);
const auto first_addr = &*first;
const auto last_addr = first_addr + count;
const auto curr_size = size();
const auto curr_data = data();
const std::size_t index = pos - curr_data;
auto dest = &curr_data[index];
if (count > max_size() - curr_size)
detail::throw_exception<std::length_error>(
"count > max_size() - curr_size");
traits_type::move(dest + count, dest, curr_size - index + 1);
const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr);
if (!inside || last_addr <= pos)
{
detail::copy_with_traits<Traits>(first, last, dest);
}
else
{
const size_type offset = first_addr - curr_data;
if (offset < index)
{
const size_type diff = index - offset;
traits_type::copy(dest, &curr_data[offset], diff);
traits_type::copy(&curr_data[index + diff], dest + count, count - diff);
}
else
{
auto src = &curr_data[offset + count];
traits_type::copy(dest, src, count);
}
}
this->set_size(curr_size + count);
return curr_data + index;
}
template<std::size_t N, typename CharT, typename Traits>
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
insert(
const_iterator pos,
InputIterator first,
InputIterator last) ->
typename std::enable_if<
detail::is_input_iterator<
InputIterator>::value &&
!detail::is_forward_iterator<
InputIterator>::value, iterator>::type
{
const auto curr_size = size();
const auto curr_data = data();
const auto count = read_back(false, first, last);
const std::size_t index = pos - curr_data;
std::rotate(&curr_data[index], &curr_data[curr_size + 1], &curr_data[curr_size + count + 1]);
this->set_size(curr_size + count);
return curr_data + index;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
erase(
const_iterator first,
const_iterator last) ->
iterator
{
const auto curr_data = data();
const std::size_t index = first - curr_data;
traits_type::move(&curr_data[index], last, (end() - last) + 1);
this->set_size(size() - std::size_t(last - first));
return curr_data + index;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
basic_static_string<N, CharT, Traits>::
push_back(
value_type ch)
{
const auto curr_size = size();
if (curr_size >= max_size())
detail::throw_exception<std::length_error>(
"curr_size >= max_size()");
traits_type::assign(data()[curr_size], ch);
this->set_size(curr_size + 1);
term();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
append(
size_type count,
value_type ch) ->
basic_static_string&
{
const auto curr_size = size();
if (count > max_size() - curr_size)
detail::throw_exception<std::length_error>(
"count > max_size() - size()");
traits_type::assign(end(), count, ch);
this->set_size(curr_size + count);
return term();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
append(
const_pointer s,
size_type count) ->
basic_static_string&
{
const auto curr_size = size();
if (count > max_size() - curr_size)
detail::throw_exception<std::length_error>(
"count > max_size() - size()");
traits_type::copy(end(), s, count);
this->set_size(curr_size + count);
return term();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
basic_static_string<N, CharT, Traits>::
resize(size_type n, value_type c)
{
if (n > max_size())
detail::throw_exception<std::length_error>(
"n > max_size()");
const auto curr_size = size();
if(n > curr_size)
traits_type::assign(data() + curr_size, n - curr_size, c);
this->set_size(n);
term();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
basic_static_string<N, CharT, Traits>::
swap(basic_static_string& s) noexcept
{
const auto curr_size = size();
basic_static_string tmp(s);
s.set_size(curr_size);
traits_type::copy(&s.data()[0], data(), curr_size + 1);
this->set_size(tmp.size());
traits_type::copy(data(), tmp.data(), size() + 1);
}
template<std::size_t N, typename CharT, typename Traits>
template<std::size_t M>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
void
basic_static_string<N, CharT, Traits>::
swap(basic_static_string<M, CharT, Traits>& s)
{
const auto curr_size = size();
if (curr_size > s.max_size())
detail::throw_exception<std::length_error>(
"curr_size > s.max_size()");
if (s.size() > max_size())
detail::throw_exception<std::length_error>(
"s.size() > max_size()");
basic_static_string tmp(s);
s.set_size(curr_size);
traits_type::copy(&s.data()[0], data(), curr_size + 1);
this->set_size(tmp.size());
traits_type::copy(data(), &tmp.data()[0], size() + 1);
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
replace(
const_iterator i1,
const_iterator i2,
size_type n,
value_type c) ->
basic_static_string<N, CharT, Traits>&
{
const auto curr_size = size();
const auto curr_data = data();
const std::size_t n1 = i2 - i1;
if (n > max_size() || curr_size - n1 >= max_size() - n)
detail::throw_exception<std::length_error>(
"replaced string exceeds max_size()");
const auto pos = i1 - curr_data;
traits_type::move(&curr_data[pos + n], i2, (end() - i2) + 1);
traits_type::assign(&curr_data[pos], n, c);
this->set_size((curr_size - n1) + n);
return *this;
}
template<std::size_t N, typename CharT, typename Traits>
template<typename ForwardIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
replace(
const_iterator i1,
const_iterator i2,
ForwardIterator j1,
ForwardIterator j2) ->
typename std::enable_if<
detail::is_forward_iterator<ForwardIterator>::value,
basic_static_string<N, CharT, Traits>&>::type
{
const auto curr_size = size();
const auto curr_data = data();
const auto first_addr = &*j1;
const std::size_t n1 = i2 - i1;
const std::size_t n2 = detail::distance(j1, j2);
const std::size_t pos = i1 - curr_data;
if (n2 > max_size() || curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2)
detail::throw_exception<std::length_error>(
"replaced string exceeds max_size()");
const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr);
if (inside && first_addr == i1 && n1 == n2)
return *this;
if (!inside || (inside && (first_addr + n2 <= i1)))
{
traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
detail::copy_with_traits<Traits>(j1, j2, &curr_data[pos]);
}
else
{
const size_type offset = first_addr - curr_data;
if (n2 >= n1)
{
const size_type diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0;
traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
traits_type::move(&curr_data[pos], &curr_data[offset], diff);
traits_type::move(&curr_data[pos + diff], &curr_data[(offset - n1) + n2 + diff], n2 - diff);
}
else
{
traits_type::move(&curr_data[pos], &curr_data[offset], n2);
traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
}
}
this->set_size((curr_size - n1) + n2);
return *this;
}
template<std::size_t N, typename CharT, typename Traits>
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
replace(
const_iterator i1,
const_iterator i2,
InputIterator j1,
InputIterator j2) ->
typename std::enable_if<
detail::is_input_iterator<
InputIterator>::value &&
!detail::is_forward_iterator<
InputIterator>::value,
basic_static_string<N, CharT, Traits>&>::type
{
const auto curr_size = size();
const auto curr_data = data();
const std::size_t n1 = detail::distance(i1, i2);
const std::size_t n2 = read_back(false, j1, j2);
const std::size_t pos = i1 - curr_data;
std::rotate(&curr_data[pos], &curr_data[curr_size + 1], &curr_data[curr_size + n2 + 1]);
traits_type::move(&curr_data[pos + n2], &curr_data[pos + n2 + n1], ((curr_size - n1) + n2) - pos);
this->set_size((curr_size - n1) + n2);
return *this;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
find(
const_pointer s,
size_type pos,
size_type n) const noexcept ->
size_type
{
const auto curr_size = size();
if (pos > curr_size || n > curr_size - pos)
return npos;
if (!n)
return pos;
const auto res = detail::search(data() + pos, data() + curr_size, s, s + n, traits_type::eq);
return res == end() ? npos : detail::distance(data(), res);
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
rfind(
const_pointer s,
size_type pos,
size_type n) const noexcept ->
size_type
{
const auto curr_size = size();
const auto curr_data = data();
if (curr_size < n)
return npos;
if (pos > curr_size - n)
pos = curr_size - n;
if (!n)
return pos;
for (auto sub = &curr_data[pos]; sub >= curr_data; --sub)
if (!traits_type::compare(sub, s, n))
return detail::distance(curr_data, sub);
return npos;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
find_first_of(
const_pointer s,
size_type pos,
size_type n) const noexcept ->
size_type
{
const auto curr_data = data();
if (pos >= size() || !n)
return npos;
const auto res = detail::find_first_of(&curr_data[pos], &curr_data[size()], s, &s[n], traits_type::eq);
return res == end() ? npos : detail::distance(curr_data, res);
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
find_last_of(
const_pointer s,
size_type pos,
size_type n) const noexcept ->
size_type
{
const auto curr_size = size();
if (!n)
return npos;
if (pos >= curr_size)
pos = 0;
else
pos = curr_size - (pos + 1);
const auto res = detail::find_first_of(rbegin() + pos, rend(), s, &s[n], traits_type::eq);
return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res);
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
find_first_not_of(
const_pointer s,
size_type pos,
size_type n) const noexcept ->
size_type
{
if (pos >= size())
return npos;
if (!n)
return pos;
const auto res = detail::find_not_of<Traits>(data() + pos, data() + size(), s, n);
return res == end() ? npos : detail::distance(data(), res);
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
find_last_not_of(
const_pointer s,
size_type pos,
size_type n) const noexcept ->
size_type
{
const auto curr_size = size();
if (pos >= curr_size)
pos = curr_size - 1;
if (!n)
return pos;
pos = curr_size - (pos + 1);
const auto res = detail::find_not_of<Traits>(rbegin() + pos, rend(), s, n);
return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res);
}
template<std::size_t N, typename CharT, typename Traits>
template<typename InputIterator>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
read_back(
bool overwrite_null,
InputIterator first,
InputIterator last) ->
size_type
{
const auto curr_data = data();
auto new_size = size();
for (; first != last; ++first)
{
if (new_size >= max_size())
{
if (overwrite_null)
term();
detail::throw_exception<std::length_error>(
"count > max_size() - size()");
}
traits_type::assign(curr_data[new_size++ + (!overwrite_null)], *first);
}
return new_size - size();
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
replace_unchecked(
const_iterator i1,
const_iterator i2,
const_pointer s,
size_type n2) ->
basic_static_string&
{
const auto curr_data = data();
const auto curr_size = size();
const std::size_t pos = i1 - curr_data;
const std::size_t n1 = i2 - i1;
if (n2 > max_size() || curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2)
detail::throw_exception<std::length_error>(
"replaced string exceeds max_size()");
traits_type::move(&curr_data[pos + n2], i2, (end() - i2) + 1);
traits_type::copy(&curr_data[pos], s, n2);
this->set_size((curr_size - n1) + n2);
return *this;
}
template<std::size_t N, typename CharT, typename Traits>
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string<N, CharT, Traits>::
insert_unchecked(
const_iterator pos,
const_pointer s,
size_type count) ->
iterator
{
const auto curr_data = data();
const auto curr_size = size();
if (count > max_size() - curr_size)
detail::throw_exception<std::length_error>(
"count > max_size() - curr_size");
const std::size_t index = pos - curr_data;
traits_type::move(&curr_data[index + count], pos, (end() - pos) + 1);
traits_type::copy(&curr_data[index], s, count);
this->set_size(curr_size + count);
return curr_data + index;
}
} }
#if defined(__GNUC__) && __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif
#if defined(__GNUC__) && __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
#endif
#endif