Removed some string_view dependency

This commit is contained in:
Krystian Stasiowski
2019-10-27 16:12:06 -04:00
parent 885aa38d3e
commit b8695d8644
4 changed files with 300 additions and 141 deletions

View File

@ -10,23 +10,61 @@
#ifndef BOOST_FIXED_STRING_CONFIG_HPP #ifndef BOOST_FIXED_STRING_CONFIG_HPP
#define BOOST_FIXED_STRING_CONFIG_HPP #define BOOST_FIXED_STRING_CONFIG_HPP
#define BOOST_FIXED_STRING_USE_BOOST
#if __cplusplus >= 201703L
#define BOOST_FIXED_STRING_CPP17
#elif __cplusplus >= 201402L
#define BOOST_FIXED_STRING_CPP14
#else
#define BOOST_FIXED_STRING_CPP11
#endif
#if defined(BOOST_FIXED_STRING_CPP17) || defined(BOOST_FIXED_STRING_USE_BOOST)
#define BOOST_FIXED_STRING_STRING_VIEW
#endif
#ifdef BOOST_FIXED_STRING_USE_BOOST
#include <boost/utility/string_view.hpp> #include <boost/utility/string_view.hpp>
#elif defined(BOOST_FIXED_STRING_CPP17)
#include <string_view>
#endif
namespace boost { namespace boost {
namespace fixed_string { namespace fixed_string {
/// The type of `string_view` used by the library /// The type of `string_view` used by the library
using string_view = boost::string_view; #ifdef BOOST_FIXED_STRING_STRING_VIEW
using string_view =
#ifdef BOOST_FIXED_STRING_USE_BOOST
boost::string_view;
#else
std::string_view;
#endif
#endif
/// The type of `basic_string_view` used by the library /// The type of `basic_string_view` used by the library
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename CharT, typename Traits> template<typename CharT, typename Traits>
using basic_string_view = using basic_string_view =
#ifdef BOOST_FIXED_STRING_USE_BOOST
boost::basic_string_view<CharT, Traits>; boost::basic_string_view<CharT, Traits>;
#else
std::basic_string_view<CharT, Traits>;
#endif
#endif
#ifndef BOOST_NODISCARD #ifndef BOOST_NODISCARD
#define BOOST_NODISCARD #define BOOST_NODISCARD
#endif #endif
#ifdef BOOST_FIXED_STRING_USE_BOOST
#define BOOST_FIXED_STRING_THROW(e) (BOOST_THROW_EXCEPTION(e))
#else
#define BOOST_FIXED_STRING_THROW(e) (throw e)
#endif
} // fixed_string } // fixed_string
} // boost } // boost

View File

@ -126,6 +126,20 @@ raw_to_string(CharT* last, std::size_t size, Integer i)
last, i, std::is_signed<Integer>{}); last, i, std::is_signed<Integer>{});
} }
template<
typename Traits,
typename CharT,
typename ForwardIt>
ForwardIt
find_not_of(
ForwardIt first, ForwardIt last, const CharT* str, std::size_t n) noexcept
{
for (; first != last; ++first)
if (!Traits::find(str, n, *first))
return first;
return last;
}
} // detail } // detail
} // fixed_string } // fixed_string
} // boost } // boost

View File

@ -77,8 +77,10 @@ public:
std::reverse_iterator<const_iterator>; std::reverse_iterator<const_iterator>;
/// The type of `string_view` returned by the interface /// The type of `string_view` returned by the interface
#ifdef BOOST_FIXED_STRING_STRING_VIEW
using string_view_type = using string_view_type =
basic_string_view<CharT, Traits>; string_view;
#endif
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
@ -90,7 +92,7 @@ public:
static std::size_t constexpr static_capacity = N; static std::size_t constexpr static_capacity = N;
/// A special index /// A special index
static constexpr size_type npos = string_view_type::npos; static constexpr size_type npos = size_type(-1);
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
@ -157,9 +159,12 @@ public:
std::initializer_list<CharT> init); std::initializer_list<CharT> init);
/// Construct from a `string_view` /// Construct from a `string_view`
#ifdef BOOST_FIXED_STRING_STRING_VIEW
explicit explicit
fixed_string( fixed_string(
string_view_type sv); string_view_type sv);
#endif
/** Construct from any object convertible to `string_view_type`. /** Construct from any object convertible to `string_view_type`.
@ -167,6 +172,7 @@ public:
obtained by converting `t` to `string_view_type`, obtained by converting `t` to `string_view_type`,
and used to construct the string. and used to construct the string.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T template<typename T
#ifndef GENERATING_DOCUMENTATION #ifndef GENERATING_DOCUMENTATION
, class = typename std::enable_if< , class = typename std::enable_if<
@ -177,6 +183,7 @@ public:
T const& t, T const& t,
size_type pos, size_type pos,
size_type n); size_type n);
#endif
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
@ -237,12 +244,14 @@ public:
} }
/// Assign from `string_view_type`. /// Assign from `string_view_type`.
#ifdef BOOST_FIXED_STRING_STRING_VIEW
fixed_string& fixed_string&
operator=( operator=(
string_view_type sv) string_view_type sv)
{ {
return assign(sv); return assign(sv);
} }
#endif
/** Replace the contents with `count` copies of character `ch` /** Replace the contents with `count` copies of character `ch`
@ -345,6 +354,7 @@ public:
@throw std::length_error if `string_view_type{t}.size() > max_size()` @throw std::length_error if `string_view_type{t}.size() > max_size()`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -359,6 +369,7 @@ public:
string_view_type ss{t}; string_view_type ss{t};
return assign(ss.data(), ss.size()); return assign(ss.data(), ss.size());
} }
#endif
/** Replace the contents with a copy of the characters from `string_view_type{t}.substr(pos, count)` /** Replace the contents with a copy of the characters from `string_view_type{t}.substr(pos, count)`
@ -369,6 +380,8 @@ public:
@throw std::out_of_range if `pos > string_view_type{t}.size()` @throw std::out_of_range if `pos > string_view_type{t}.size()`
@throw std::length_error if `string_view_type{t}.substr(pos, count).size() > max_size()` @throw std::length_error if `string_view_type{t}.substr(pos, count).size() > max_size()`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -385,6 +398,7 @@ public:
{ {
return assign(string_view_type{t}.substr(pos, count)); return assign(string_view_type{t}.substr(pos, count));
} }
#endif
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
@ -488,11 +502,13 @@ public:
} }
/// Convert a static string to a `string_view_type` /// Convert a static string to a `string_view_type`
#ifdef BOOST_FIXED_STRING_STRING_VIEW
operator string_view_type() const noexcept operator string_view_type() const noexcept
{ {
return basic_string_view< return basic_string_view<
CharT, Traits>{data(), size()}; CharT, Traits>{data(), size()};
} }
#endif
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
@ -708,6 +724,7 @@ public:
@throw std::length_error if `size() + sv.size() > max_size()` @throw std::length_error if `size() + sv.size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
fixed_string& fixed_string&
insert( insert(
size_type index, size_type index,
@ -715,6 +732,7 @@ public:
{ {
return insert(index, sv.data(), sv.size()); return insert(index, sv.data(), sv.size());
} }
#endif
/** Inserts the string `sv.substr(index_str, count)` at the position `index` /** Inserts the string `sv.substr(index_str, count)` at the position `index`
@ -724,6 +742,7 @@ public:
@throw std::length_error if `size() + sv.substr(index_str, count).size() > max_size()` @throw std::length_error if `size() + sv.substr(index_str, count).size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
fixed_string& fixed_string&
insert( insert(
size_type index, size_type index,
@ -733,6 +752,7 @@ public:
{ {
return insert(index, sv.substr(index_str, count)); return insert(index, sv.substr(index_str, count));
} }
#endif
/** Inserts character `ch` before the character (if any) pointed by `pos` /** Inserts character `ch` before the character (if any) pointed by `pos`
@ -809,6 +829,7 @@ public:
@throw std::length_error if `size() + string_view{t}.substr(index_str, count).size() > max_size()` @throw std::length_error if `size() + string_view{t}.substr(index_str, count).size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -823,6 +844,7 @@ public:
insert( insert(
size_type index, size_type index,
T const& t); T const& t);
#endif
/** Inserts elements from `string_view{t}.substr(index_str, count)` at the position `index` /** Inserts elements from `string_view{t}.substr(index_str, count)` at the position `index`
@ -835,6 +857,7 @@ public:
@throw std::length_error if `size() + string_view{t}.substr(index_str, count).size() > max_size()` @throw std::length_error if `size() + string_view{t}.substr(index_str, count).size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -849,6 +872,7 @@ public:
T const& t, T const& t,
size_type index_str, size_type index_str,
size_type count = npos); size_type count = npos);
#endif
/** Removes `min(count, size() - index)` characters starting at `index` /** Removes `min(count, size() - index)` characters starting at `index`
@ -918,12 +942,14 @@ public:
@throw std::length_error if `size() + sv.size() > max_size()` @throw std::length_error if `size() + sv.size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
fixed_string& fixed_string&
append( append(
string_view_type sv) string_view_type sv)
{ {
return append(sv.data(), sv.size()); return append(sv.data(), sv.size());
} }
#endif
/** Appends the contents of `sv.substr(pos, count)` /** Appends the contents of `sv.substr(pos, count)`
@ -933,6 +959,7 @@ public:
@throw std::length_error if `size() + sv.substr(pos, count).size() > max_size()` @throw std::length_error if `size() + sv.substr(pos, count).size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
fixed_string& fixed_string&
append( append(
string_view_type sv, string_view_type sv,
@ -941,6 +968,7 @@ public:
{ {
return append(sv.substr(pos, count)); return append(sv.substr(pos, count));
} }
#endif
/** Appends characters in the range `(s, s + count)` /** Appends characters in the range `(s, s + count)`
@ -1019,6 +1047,7 @@ public:
@throw std::length_error if `size() + string_view{t} > max_size()` @throw std::length_error if `size() + string_view{t} > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -1035,6 +1064,7 @@ public:
{ {
return append(string_view{t}); return append(string_view{t});
} }
#endif
/** Appends characters from `string_view{t}.substr{pos, count}` /** Appends characters from `string_view{t}.substr{pos, count}`
@ -1047,6 +1077,7 @@ public:
@throw std::length_error if `size() + string_view{t}.substr(pos, count).size() > max_size()` @throw std::length_error if `size() + string_view{t}.substr(pos, count).size() > max_size()`
@return `*this` @return `*this`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -1065,6 +1096,7 @@ public:
{ {
return append(string_view{t}.substr(pos, count)); return append(string_view{t}.substr(pos, count));
} }
#endif
template<std::size_t M> template<std::size_t M>
fixed_string& fixed_string&
@ -1124,6 +1156,7 @@ public:
@throw std::length_error if `string_view_type{t}.size() > max_size()` @throw std::length_error if `string_view_type{t}.size() > max_size()`
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -1138,6 +1171,7 @@ public:
{ {
return append(t); return append(t);
} }
#endif
template<std::size_t M> template<std::size_t M>
int int
@ -1201,6 +1235,7 @@ public:
substr(pos1, count1), s, count2); substr(pos1, count1), s, count2);
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
int int
compare( compare(
string_view_type s) const string_view_type s) const
@ -1209,6 +1244,9 @@ public:
&s_[0], n_, s.data(), s.size()); &s_[0], n_, s.data(), s.size());
} }
#endif
#ifdef BOOST_FIXED_STRING_STRING_VIEW
int int
compare( compare(
size_type pos1, size_type pos1,
@ -1218,7 +1256,9 @@ public:
return detail::lexicographical_compare<CharT, Traits>( return detail::lexicographical_compare<CharT, Traits>(
substr(pos1, count1), s); substr(pos1, count1), s);
} }
#endif
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
int int
@ -1238,8 +1278,9 @@ public:
return compare(pos1, count1, return compare(pos1, count1,
string_view_type(t).substr(pos2, count2)); string_view_type(t).substr(pos2, count2));
} }
#endif
string_view_type fixed_string
substr( substr(
size_type pos = 0, size_type pos = 0,
size_type count = npos) const; size_type count = npos) const;
@ -1302,6 +1343,7 @@ public:
return replace(pos1, n1, string_view_type(str).substr(pos2, n2)); return replace(pos1, n1, string_view_type(str).substr(pos2, n2));
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -1319,7 +1361,9 @@ public:
string_view_type sv = t; string_view_type sv = t;
return replace(pos1, n1, sv.data(), sv.size()); return replace(pos1, n1, sv.data(), sv.size());
} }
#endif
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -1339,6 +1383,7 @@ public:
string_view_type sv = t; string_view_type sv = t;
return replace(pos1, n1, sv.substr(pos2, n2)); return replace(pos1, n1, sv.substr(pos2, n2));
} }
#endif
fixed_string& fixed_string&
replace( replace(
@ -1372,6 +1417,7 @@ public:
return replace(i1, i2, string_view_type(str)); return replace(i1, i2, string_view_type(str));
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<typename T> template<typename T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
fixed_string& fixed_string&
@ -1389,6 +1435,7 @@ public:
string_view_type sv = t; string_view_type sv = t;
return replace(i1 - begin(), i2 - i1, sv.data(), sv.size()); return replace(i1 - begin(), i2 - i1, sv.data(), sv.size());
} }
#endif
fixed_string& fixed_string&
replace( replace(
@ -1457,6 +1504,7 @@ public:
`T` is convertible to `string_view` and `T` is not `T` is convertible to `string_view` and `T` is not
convertible to `CharT const*`. convertible to `CharT const*`.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<class T> template<class T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
size_type size_type
@ -1473,31 +1521,25 @@ public:
return string_view_type( return string_view_type(
*this).find( *this).find(
t, pos); t, pos);
} }
#endif
// overload for later use template<std::size_t N>
/*template<std::size_t N>
size_type size_type
find( find(
const fixed_string<N, CharT, Traits>& str, const fixed_string<N, CharT, Traits>& str,
size_type pos = 0) const noexcept size_type pos = 0) const noexcept
{ {
return string_view_type( return find(str.data(), pos, str.size());
*this).find( }
str, pos);
}*/
// Finds the first substring equal to the range `[s, s + count)`. This range may contain null characters. // Finds the first substring equal to the range `[s, s + count)`. This range may contain null characters.
size_type size_type
find( find(
const CharT* s, const CharT* s,
size_type pos, size_type pos,
size_type n) const size_type n) const;
{
return string_view_type(
*this).find(
s, pos, n);
}
/** Finds the first substring equal to the character /** Finds the first substring equal to the character
string pointed to by `s`. string pointed to by `s`.
@ -1510,9 +1552,7 @@ public:
const CharT* s, const CharT* s,
size_type pos = 0) const size_type pos = 0) const
{ {
return string_view_type( return find(s, pos, Traits::length(s));
*this).find(
s, pos);
} }
// Finds the first character `c` // Finds the first character `c`
@ -1521,9 +1561,7 @@ public:
CharT c, CharT c,
size_type pos = 0) const noexcept size_type pos = 0) const noexcept
{ {
return string_view_type( return find(&c, pos, 1);
*this).find(
c, pos);
} }
@ -1533,6 +1571,7 @@ public:
`T` is convertible to `string_view` and `T` is not `T` is convertible to `string_view` and `T` is not
convertible to `CharT const*`. convertible to `CharT const*`.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<class T> template<class T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
size_type size_type
@ -1550,30 +1589,23 @@ public:
*this).rfind( *this).rfind(
t, pos); t, pos);
} }
#endif
// overload for later use template<std::size_t N>
/*template<std::size_t N>
size_type size_type
rfind( rfind(
const fixed_string<N, CharT, Traits>& str, const fixed_string<N, CharT, Traits>& str,
size_type pos = npos) const noexcept size_type pos = npos) const noexcept
{ {
return string_view_type( return rfind(str.data(), pos, str.size());
*this).rfind( }
str, pos);
}*/
// Finds the last substring equal to the range `[s, s + count)`. This range may contain null characters. // Finds the last substring equal to the range `[s, s + count)`. This range may contain null characters.
size_type size_type
rfind( rfind(
const CharT* s, const CharT* s,
size_type pos, size_type pos,
size_type n) const size_type n) const;
{
return string_view_type(
*this).rfind(
s, pos, n);
}
/** Finds the last substring equal to the character /** Finds the last substring equal to the character
string pointed to by `s`. string pointed to by `s`.
@ -1586,9 +1618,7 @@ public:
const CharT* s, const CharT* s,
size_type pos = npos) const size_type pos = npos) const
{ {
return string_view_type( return rfind(s, pos, Traits::length(s));
*this).rfind(
s, pos);
} }
// Finds the last character `c` // Finds the last character `c`
@ -1597,9 +1627,7 @@ public:
CharT c, CharT c,
size_type pos = npos) const noexcept size_type pos = npos) const noexcept
{ {
return string_view_type( return rfind(&c, pos, 1);
*this).rfind(
c, pos);
} }
/** Finds the first character equal to one of the characters in `t`. /** Finds the first character equal to one of the characters in `t`.
@ -1608,6 +1636,7 @@ public:
`T` is convertible to `string_view` and `T` is not `T` is convertible to `string_view` and `T` is not
convertible to `CharT const*`. convertible to `CharT const*`.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<class T> template<class T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
size_type size_type
@ -1625,30 +1654,23 @@ public:
*this).find_first_of( *this).find_first_of(
t, pos); t, pos);
} }
#endif
// overload for later use template<std::size_t N>
/*template<std::size_t N>
size_type size_type
find_first_of( find_first_of(
const fixed_string<N, CharT, Traits>& str, const fixed_string<N, CharT, Traits>& str,
size_type pos = 0) const noexcept size_type pos = 0) const noexcept
{ {
return string_view_type( return find_first_of(str.data(), pos, str.size());
*this).find_first_of( }
str, pos);
}*/
// Finds the first character equal to one of the characters in the range `[s, s + count)`. This range can include null characters. // Finds the first character equal to one of the characters in the range `[s, s + count)`. This range can include null characters.
size_type size_type
find_first_of( find_first_of(
const CharT* s, const CharT* s,
size_type pos, size_type pos,
size_type n) const size_type n) const;
{
return string_view_type(
*this).find_first_of(
s, pos, n);
}
/** Finds the first character equal to one of the characters /** Finds the first character equal to one of the characters
in character string pointed to by `s`. in character string pointed to by `s`.
@ -1661,9 +1683,7 @@ public:
const CharT* s, const CharT* s,
size_type pos = 0) const size_type pos = 0) const
{ {
return string_view_type( return find_first_of(s, pos, Traits::length(s));
*this).find_first_of(
s, pos);
} }
// Finds the first character equal to `c`. // Finds the first character equal to `c`.
@ -1672,9 +1692,7 @@ public:
CharT c, CharT c,
size_type pos = 0) const noexcept size_type pos = 0) const noexcept
{ {
return string_view_type( return find_first_of(&c, pos, 1);
*this).find_first_of(
c, pos);
} }
/** Finds the last character equal to one of the characters in `t`. /** Finds the last character equal to one of the characters in `t`.
@ -1683,6 +1701,7 @@ public:
`T` is convertible to `string_view` and `T` is not `T` is convertible to `string_view` and `T` is not
convertible to `CharT const*`. convertible to `CharT const*`.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<class T> template<class T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
size_type size_type
@ -1700,30 +1719,23 @@ public:
*this).find_last_of( *this).find_last_of(
t, pos); t, pos);
} }
#endif
// overload for later use template<std::size_t N>
/*template<std::size_t N>
size_type size_type
find_last_of( find_last_of(
const fixed_string<N, CharT, Traits>& str, const fixed_string<N, CharT, Traits>& str,
size_type pos = npos) const noexcept size_type pos = npos) const noexcept
{ {
return string_view_type( return find_last_of(str.data(), pos, str.size());
*this).find_last_of( }
str, pos);
}*/
// Finds the last character equal to one of the characters in the range `[s, s + count)`. This range can include null characters. // Finds the last character equal to one of the characters in the range `[s, s + count)`. This range can include null characters.
size_type size_type
find_last_of( find_last_of(
const CharT* s, const CharT* s,
size_type pos, size_type pos,
size_type n) const size_type n) const;
{
return string_view_type(
*this).find_last_of(
s, pos, n);
}
/** Finds the last character equal to one of the characters /** Finds the last character equal to one of the characters
in character string pointed to by `s`. in character string pointed to by `s`.
@ -1736,9 +1748,7 @@ public:
const CharT* s, const CharT* s,
size_type pos = npos) const size_type pos = npos) const
{ {
return string_view_type( return find_last_of(s, pos, Traits::length(s));
*this).find_last_of(
s, pos);
} }
// Finds the last character equal to `c`. // Finds the last character equal to `c`.
@ -1747,9 +1757,7 @@ public:
CharT c, CharT c,
size_type pos = npos) const noexcept size_type pos = npos) const noexcept
{ {
return string_view_type( return find_last_of(&c, pos, 1);
*this).find_last_of(
c, pos);
} }
/** Finds the first character equal to none of characters in `t`. /** Finds the first character equal to none of characters in `t`.
@ -1758,6 +1766,7 @@ public:
`T` is convertible to `string_view` and `T` is not `T` is convertible to `string_view` and `T` is not
convertible to `CharT const*`. convertible to `CharT const*`.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<class T> template<class T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
size_type size_type
@ -1775,30 +1784,23 @@ public:
*this).find_first_not_of( *this).find_first_not_of(
t, pos); t, pos);
} }
#endif
// overload for later use template<std::size_t N>
/*template<std::size_t N>
size_type size_type
find_first_not_of( find_first_not_of(
const fixed_string<N, CharT, Traits>& str, const fixed_string<N, CharT, Traits>& str,
size_type pos = 0) const noexcept size_type pos = 0) const noexcept
{ {
return string_view_type( return find_first_not_of(str.data(), pos, str.size());
*this).find_first_not_of( }
str, pos);
}*/
// Finds the first character equal to none of characters in range `[s, s + count)`. This range can include null characters. // Finds the first character equal to none of characters in range `[s, s + count)`. This range can include null characters.
size_type size_type
find_first_not_of( find_first_not_of(
const CharT* s, const CharT* s,
size_type pos, size_type pos,
size_type n) const size_type n) const;
{
return string_view_type(
*this).find_first_not_of(
s, pos, n);
}
/** Finds the first character equal to none of characters in /** Finds the first character equal to none of characters in
character string pointed to by `s`. character string pointed to by `s`.
@ -1811,9 +1813,7 @@ public:
const CharT* s, const CharT* s,
size_type pos = 0) const size_type pos = 0) const
{ {
return string_view_type( return find_first_not_of(s, pos, Traits::length(s));
*this).find_first_not_of(
s, pos);
} }
// Finds the first character not equal to `c`. // Finds the first character not equal to `c`.
@ -1822,9 +1822,7 @@ public:
CharT c, CharT c,
size_type pos = 0) const noexcept size_type pos = 0) const noexcept
{ {
return string_view_type( return find_first_not_of(&c, pos, 1);
*this).find_first_not_of(
c, pos);
} }
/** Finds the last character equal to none of characters in `t`. /** Finds the last character equal to none of characters in `t`.
@ -1833,6 +1831,7 @@ public:
`T` is convertible to `string_view` and `T` is not `T` is convertible to `string_view` and `T` is not
convertible to `CharT const*`. convertible to `CharT const*`.
*/ */
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<class T> template<class T>
#if GENERATING_DOCUMENTATION #if GENERATING_DOCUMENTATION
size_type size_type
@ -1850,30 +1849,23 @@ public:
*this).find_last_not_of( *this).find_last_not_of(
t, pos); t, pos);
} }
#endif
// overload for later use template<size_t N>
/*template<size_t N>
size_type size_type
find_last_not_of( find_last_not_of(
const fixed_string<N, CharT, Traits>& str, const fixed_string<N, CharT, Traits>& str,
size_type pos = npos) const noexcept size_type pos = npos) const noexcept
{ {
return string_view_type( return find_last_not_of(str.data(), pos, str.size());
*this).find_last_not_of( }
str, pos);
}*/
// Finds the last character equal to none of characters in range `[s, s + count)`. This range can include null characters. // Finds the last character equal to none of characters in range `[s, s + count)`. This range can include null characters.
size_type size_type
find_last_not_of( find_last_not_of(
const CharT* s, const CharT* s,
size_type pos, size_type pos,
size_type n) const size_type n) const;
{
return string_view_type(
*this).find_last_not_of(
s, pos, n);
}
/** Finds the last character equal to none of characters in /** Finds the last character equal to none of characters in
@ -1887,9 +1879,7 @@ public:
const CharT* s, const CharT* s,
size_type pos = npos) const size_type pos = npos) const
{ {
return string_view_type( return find_last_not_of(s, pos, Traits::length(s));
*this).find_last_not_of(
s, pos);
} }
// Finds the last character not equal to `c`. // Finds the last character not equal to `c`.
@ -1898,17 +1888,17 @@ public:
CharT c, CharT c,
size_type pos = npos) const noexcept size_type pos = npos) const noexcept
{ {
return string_view_type( return find_last_not_of(&c, pos, 1);
*this).find_last_not_of(
c, pos);
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
bool bool
starts_with( starts_with(
string_view_type s) const noexcept string_view_type s) const noexcept
{ {
return string_view_type(*this).starts_with(s); return string_view_type(*this).starts_with(s);
} }
#endif
bool bool
starts_with( starts_with(
@ -1924,12 +1914,14 @@ public:
return string_view_type(*this).starts_with(s); return string_view_type(*this).starts_with(s);
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
bool bool
ends_with( ends_with(
string_view_type s) const noexcept string_view_type s) const noexcept
{ {
return string_view_type(*this).ends_with(s); return string_view_type(*this).ends_with(s);
} }
#endif
bool bool
ends_with( ends_with(
@ -2236,7 +2228,7 @@ operator<<(std::basic_ostream<CharT, Traits>& os,
fixed_string<N, CharT, Traits> const& s) fixed_string<N, CharT, Traits> const& s)
{ {
return os << static_cast< return os << static_cast<
basic_string_view<CharT, Traits>>(s); string_view>(s);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -2270,7 +2262,7 @@ to_fixed_string(Integer x);
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if __cplusplus >= 201703L #ifdef BOOST_FIXED_STRING_CPP17
template<std::size_t N, typename CharT> template<std::size_t N, typename CharT>
fixed_string(CharT(&)[N]) -> fixed_string(CharT(&)[N]) ->
fixed_string<N, CharT, std::char_traits<CharT>>; fixed_string<N, CharT, std::char_traits<CharT>>;

View File

@ -10,6 +10,7 @@
#ifndef BOOST_FIXED_STRING_IMPL_FIXED_STRING_HPP #ifndef BOOST_FIXED_STRING_IMPL_FIXED_STRING_HPP
#define BOOST_FIXED_STRING_IMPL_FIXED_STRING_HPP #define BOOST_FIXED_STRING_IMPL_FIXED_STRING_HPP
#include <boost/fixed_string/config.hpp>
#include <boost/fixed_string/detail/fixed_string.hpp> #include <boost/fixed_string/detail/fixed_string.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
@ -72,7 +73,7 @@ fixed_string(CharT const* s)
{ {
auto const count = Traits::length(s); auto const count = Traits::length(s);
if(count > max_size()) if(count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"count > max_size()"}); "count > max_size()"});
n_ = count; n_ = count;
Traits::copy(&s_[0], s, n_ + 1); Traits::copy(&s_[0], s, n_ + 1);
@ -115,12 +116,14 @@ fixed_string(std::initializer_list<CharT> init)
assign(init.begin(), init.end()); assign(init.begin(), init.end());
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
fixed_string<N, CharT, Traits>:: fixed_string<N, CharT, Traits>::
fixed_string(string_view_type sv) fixed_string(string_view_type sv)
{ {
assign(sv); assign(sv);
} }
#endif
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
template<class T, class> template<class T, class>
@ -145,7 +148,7 @@ assign(
fixed_string& fixed_string&
{ {
if(count > max_size()) if(count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"count > max_size()"}); "count > max_size()"});
n_ = count; n_ = count;
Traits::assign(&s_[0], n_, ch); Traits::assign(&s_[0], n_, ch);
@ -193,7 +196,7 @@ assign(
fixed_string& fixed_string&
{ {
if(count > max_size()) if(count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"count > max_size()"}); "count > max_size()"});
n_ = count; n_ = count;
Traits::copy(&s_[0], s, n_); Traits::copy(&s_[0], s, n_);
@ -214,7 +217,7 @@ assign(
{ {
std::size_t const n = std::distance(first, last); std::size_t const n = std::distance(first, last);
if(n > max_size()) if(n > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"n > max_size()"}); "n > max_size()"});
n_ = n; n_ = n;
for(auto it = &s_[0]; first != last; ++it, ++first) for(auto it = &s_[0]; first != last; ++it, ++first)
@ -236,7 +239,7 @@ at(size_type pos) ->
reference reference
{ {
if(pos >= size()) if(pos >= size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"pos >= size()"}); "pos >= size()"});
return s_[pos]; return s_[pos];
} }
@ -248,7 +251,7 @@ at(size_type pos) const ->
const_reference const_reference
{ {
if(pos >= size()) if(pos >= size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"pos >= size()"}); "pos >= size()"});
return s_[pos]; return s_[pos];
} }
@ -265,7 +268,7 @@ fixed_string<N, CharT, Traits>::
reserve(std::size_t n) reserve(std::size_t n)
{ {
if(n > max_size()) if(n > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"n > max_size()"}); "n > max_size()"});
} }
@ -296,7 +299,7 @@ insert(
fixed_string& fixed_string&
{ {
if(index > size()) if(index > size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"index > size()"}); "index > size()"});
insert(begin() + index, count, ch); insert(begin() + index, count, ch);
return *this; return *this;
@ -312,10 +315,10 @@ insert(
fixed_string& fixed_string&
{ {
if(index > size()) if(index > size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"index > size()"}); "index > size()"});
if(size() + count > max_size()) if(size() + count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() + count > max_size()"}); "size() + count > max_size()"});
const bool inside = s <= &s_[size()] && s >= &s_[0]; const bool inside = s <= &s_[size()] && s >= &s_[0];
if (!inside || (inside && (&s[count - 1] < &s_[index]))) if (!inside || (inside && (&s[count - 1] < &s_[index])))
@ -352,7 +355,7 @@ insert(
iterator iterator
{ {
if(size() + count > max_size()) if(size() + count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() + count() > max_size()"}); "size() + count() > max_size()"});
auto const index = pos - &s_[0]; auto const index = pos - &s_[0];
Traits::move( Traits::move(
@ -377,7 +380,7 @@ insert(
{ {
std::size_t const count = std::distance(first, last); std::size_t const count = std::distance(first, last);
if(size() + count > max_size()) if(size() + count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() + count > max_size()"}); "size() + count > max_size()"});
std::size_t const index = pos - begin(); std::size_t const index = pos - begin();
if (&*first <= &s_[size()] && &*first >= &s_[0]) if (&*first <= &s_[size()] && &*first >= &s_[0])
@ -391,6 +394,7 @@ insert(
return begin() + index; return begin() + index;
} }
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
template<class T> template<class T>
auto auto
@ -407,7 +411,9 @@ insert(
{ {
return insert(index, t, 0, npos); return insert(index, t, 0, npos);
} }
#endif
#ifdef BOOST_FIXED_STRING_STRING_VIEW
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
template<class T> template<class T>
auto auto
@ -428,6 +434,7 @@ insert(
string_view_type(t).substr(index_str, count); string_view_type(t).substr(index_str, count);
return insert(index, s.data(), s.size()); return insert(index, s.data(), s.size());
} }
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -440,7 +447,7 @@ erase(
fixed_string& fixed_string&
{ {
if(index > size()) if(index > size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"index > size()"}); "index > size()"});
auto const n = (std::min)(count, size() - index); auto const n = (std::min)(count, size() - index);
Traits::move( Traits::move(
@ -480,7 +487,7 @@ push_back(
CharT ch) CharT ch)
{ {
if(size() >= max_size()) if(size() >= max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() >= max_size()"}); "size() >= max_size()"});
Traits::assign(s_[n_++], ch); Traits::assign(s_[n_++], ch);
term(); term();
@ -495,7 +502,7 @@ append(
fixed_string& fixed_string&
{ {
if(size() + count > max_size()) if(size() + count > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() + count > max_size()"}); "size() + count > max_size()"});
Traits::move( Traits::move(
&s_[n_ + count], &s_[n_], size() - n_); &s_[n_ + count], &s_[n_], size() - n_);
@ -509,12 +516,12 @@ template<std::size_t N, typename CharT, typename Traits>
auto auto
fixed_string<N, CharT, Traits>:: fixed_string<N, CharT, Traits>::
substr(size_type pos, size_type count) const -> substr(size_type pos, size_type count) const ->
string_view_type fixed_string<N, CharT, Traits>
{ {
if(pos > size()) if(pos > size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"pos > size()"}); "pos > size()"});
return{&s_[pos], (std::min)(count, size() - pos)}; return {&s_[pos], (std::min)(count, size() - pos)};
} }
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
@ -534,7 +541,7 @@ fixed_string<N, CharT, Traits>::
resize(std::size_t n) resize(std::size_t n)
{ {
if(n > max_size()) if(n > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"n > max_size()"}); "n > max_size()"});
if(n > n_) if(n > n_)
Traits::assign(&s_[n_], n - n_, CharT{}); Traits::assign(&s_[n_], n - n_, CharT{});
@ -548,7 +555,7 @@ fixed_string<N, CharT, Traits>::
resize(std::size_t n, CharT c) resize(std::size_t n, CharT c)
{ {
if(n > max_size()) if(n > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"n > max_size()"}); "n > max_size()"});
if(n > n_) if(n > n_)
Traits::assign(&s_[n_], n - n_, c); Traits::assign(&s_[n_], n - n_, c);
@ -575,10 +582,10 @@ fixed_string<N, CharT, Traits>::
swap(fixed_string<M, CharT, Traits>& s) swap(fixed_string<M, CharT, Traits>& s)
{ {
if(size() > s.max_size()) if(size() > s.max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() > s.max_size()"}); "size() > s.max_size()"});
if(s.size() > max_size()) if(s.size() > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"s.size() > max_size()"}); "s.size() > max_size()"});
fixed_string tmp(s); fixed_string tmp(s);
s.n_ = n_; s.n_ = n_;
@ -597,10 +604,10 @@ replace(
size_type n2) -> fixed_string<N, CharT, Traits>& size_type n2) -> fixed_string<N, CharT, Traits>&
{ {
if (pos > size()) if (pos > size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"pos > size()"}); "pos > size()"});
if ((size() - n1 + n2) > max_size()) if ((size() - n1 + n2) > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"size() - n1 + n2 > max_size()"}); "size() - n1 + n2 > max_size()"});
const bool inside = s <= &s_[size()] && s >= &s_[0]; const bool inside = s <= &s_[size()] && s >= &s_[0];
if (inside && (s - &s_[0]) == pos && n1 == n2) if (inside && (s - &s_[0]) == pos && n1 == n2)
@ -640,10 +647,10 @@ replace(
CharT c) -> fixed_string<N, CharT, Traits> & CharT c) -> fixed_string<N, CharT, Traits> &
{ {
if (pos > size()) if (pos > size())
BOOST_THROW_EXCEPTION(std::out_of_range{ BOOST_FIXED_STRING_THROW(std::out_of_range{
"pos > size()"}); "pos > size()"});
if ((size() - n1 + n2) > max_size()) if ((size() - n1 + n2) > max_size())
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"replaced string exceeds max_size()"}); "replaced string exceeds max_size()"});
Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1); Traits::move(&s_[pos + n2], &s_[pos + n1], size() - pos - n1 + 1);
Traits::assign(&s_[pos], n2, c); Traits::assign(&s_[pos], n2, c);
@ -651,6 +658,114 @@ replace(
return *this; return *this;
} }
template<std::size_t N, typename CharT, typename Traits>
auto
fixed_string<N, CharT, Traits>::
find(
const CharT* s,
size_type pos,
size_type n) const ->
size_type
{
if (pos > n_)
return npos;
if (!n)
return pos;
if (n > n_ - pos)
return npos;
const auto res = std::search(&s_[pos], &s_[n_], s, &s[n], Traits::eq);
return res == end() ? npos : std::distance(s_, res);
}
template<std::size_t N, typename CharT, typename Traits>
auto
fixed_string<N, CharT, Traits>::
rfind(
const CharT* s,
size_type pos,
size_type n) const ->
size_type
{
if (n > n_)
return npos;
if (n == 0)
return pos;
if (pos > n_ - n)
pos = n_ - n;
for (auto sub = &s_[pos]; sub >= s_; --sub)
if (!Traits::compare(sub, s, n))
return std::distance(s_, sub);
return npos;
}
template<std::size_t N, typename CharT, typename Traits>
auto
fixed_string<N, CharT, Traits>::
find_first_of(
const CharT* s,
size_type pos,
size_type n) const ->
size_type
{
if (pos >= n_ || !n)
return npos;
const auto res = std::find_first_of(&s_[pos], &s_[n_], s, &s[n], Traits::eq);
return res == end() ? npos : std::distance(s_, res);
}
template<std::size_t N, typename CharT, typename Traits>
auto
fixed_string<N, CharT, Traits>::
find_last_of(
const CharT* s,
size_type pos,
size_type n) const ->
size_type
{
if (!n)
return npos;
if (pos >= n_)
pos = 0;
else
pos = n_ - (pos + 1);
const auto res = std::find_first_of(rbegin() + pos, rend(), s, &s[n], Traits::eq);
return res == rend() ? npos : n_ - 1 - std::distance(rbegin(), res);
}
template<std::size_t N, typename CharT, typename Traits>
auto
fixed_string<N, CharT, Traits>::
find_first_not_of(
const CharT* s,
size_type pos,
size_type n) const ->
size_type
{
if (pos >= n_)
return npos;
if (!n)
return pos;
const auto res = detail::find_not_of<Traits>(&s_[pos], &s_[n_], s, n);
return res == end() ? npos : std::distance(s_, res);
}
template<std::size_t N, typename CharT, typename Traits>
auto
fixed_string<N, CharT, Traits>::
find_last_not_of(
const CharT* s,
size_type pos,
size_type n) const ->
size_type
{
if (pos >= n_)
pos = n_ - 1;
if (!n)
return pos;
pos = n_ - (pos + 1);
const auto res = detail::find_not_of<Traits>(rbegin() + pos, rend(), s, n);
return res == rend() ? npos : n_ - 1 - std::distance(rbegin(), res);
}
template<std::size_t N, typename CharT, typename Traits> template<std::size_t N, typename CharT, typename Traits>
auto auto
@ -670,7 +785,7 @@ fixed_string<N, CharT, Traits>::
assign_char(CharT, std::false_type) -> assign_char(CharT, std::false_type) ->
fixed_string& fixed_string&
{ {
BOOST_THROW_EXCEPTION(std::length_error{ BOOST_FIXED_STRING_THROW(std::length_error{
"max_size() == 0"}); "max_size() == 0"});
} }