forked from boostorg/static_string
Refactor
This commit is contained in:
@ -23,6 +23,10 @@ template<typename CharT, typename Traits>
|
|||||||
using basic_string_view =
|
using basic_string_view =
|
||||||
boost::basic_string_view<CharT, Traits>;
|
boost::basic_string_view<CharT, Traits>;
|
||||||
|
|
||||||
|
#ifndef BOOST_NODISCARD
|
||||||
|
#define BOOST_NODISCARD
|
||||||
|
#endif
|
||||||
|
|
||||||
} // fixed_string
|
} // fixed_string
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,15 +11,18 @@
|
|||||||
#define BOOST_FIXED_STRING_IMPL_FIXED_STRING_HPP
|
#define BOOST_FIXED_STRING_IMPL_FIXED_STRING_HPP
|
||||||
|
|
||||||
#include <boost/fixed_string/detail/fixed_string.hpp>
|
#include <boost/fixed_string/detail/fixed_string.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace fixed_string {
|
namespace fixed_string {
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// (constructor)
|
// Construction
|
||||||
//
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
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>::
|
||||||
@ -127,30 +130,19 @@ fixed_string(T const& t, size_type pos, size_type n)
|
|||||||
assign(t, pos, n);
|
assign(t, pos, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// (assignment)
|
// Assignment
|
||||||
//
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
operator=(CharT const* s) ->
|
assign(
|
||||||
fixed_string&
|
size_type count,
|
||||||
{
|
CharT ch) ->
|
||||||
auto const count = Traits::length(s);
|
fixed_string&
|
||||||
if(count > max_size())
|
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
|
||||||
"count > max_size()"});
|
|
||||||
n_ = count;
|
|
||||||
Traits::copy(&s_[0], s, n_ + 1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
|
||||||
auto
|
|
||||||
fixed_string<N, CharT, Traits>::
|
|
||||||
assign(size_type count, CharT ch) ->
|
|
||||||
fixed_string&
|
|
||||||
{
|
{
|
||||||
if(count > max_size())
|
if(count > max_size())
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
@ -164,12 +156,15 @@ assign(size_type count, CharT ch) ->
|
|||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
assign(fixed_string const& s) ->
|
assign(
|
||||||
fixed_string&
|
fixed_string const& s) noexcept ->
|
||||||
|
fixed_string&
|
||||||
{
|
{
|
||||||
|
if(this == &s)
|
||||||
|
return *this;
|
||||||
n_ = s.n_;
|
n_ = s.n_;
|
||||||
auto const n = n_ + 1;
|
auto const n = n_ + 1;
|
||||||
// VFALCO I can't remember the thinking behind this
|
// VFALCO This informs the static analyzer
|
||||||
//BOOST_BEAST_ASSUME(n != 0);
|
//BOOST_BEAST_ASSUME(n != 0);
|
||||||
Traits::copy(&s_[0], &s.s_[0], n);
|
Traits::copy(&s_[0], &s.s_[0], n);
|
||||||
return *this;
|
return *this;
|
||||||
@ -179,8 +174,10 @@ template<std::size_t N, typename CharT, typename Traits>
|
|||||||
template<std::size_t M>
|
template<std::size_t M>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
assign(fixed_string<M, CharT, Traits> const& s,
|
assign(
|
||||||
size_type pos, size_type count) ->
|
fixed_string<M, CharT, Traits> const& s,
|
||||||
|
size_type pos,
|
||||||
|
size_type count) ->
|
||||||
fixed_string&
|
fixed_string&
|
||||||
{
|
{
|
||||||
auto const ss = s.substr(pos, count);
|
auto const ss = s.substr(pos, count);
|
||||||
@ -190,8 +187,10 @@ assign(fixed_string<M, CharT, Traits> const& s,
|
|||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
assign(CharT const* s, size_type count) ->
|
assign(
|
||||||
fixed_string&
|
CharT const* s,
|
||||||
|
size_type count) ->
|
||||||
|
fixed_string&
|
||||||
{
|
{
|
||||||
if(count > max_size())
|
if(count > max_size())
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
@ -206,10 +205,12 @@ template<std::size_t N, typename CharT, typename Traits>
|
|||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
assign(InputIt first, InputIt last) ->
|
assign(
|
||||||
typename std::enable_if<
|
InputIt first,
|
||||||
detail::is_input_iterator<InputIt>::value,
|
InputIt last) ->
|
||||||
fixed_string&>::type
|
typename std::enable_if<
|
||||||
|
detail::is_input_iterator<InputIt>::value,
|
||||||
|
fixed_string&>::type
|
||||||
{
|
{
|
||||||
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())
|
||||||
@ -222,27 +223,11 @@ assign(InputIt first, InputIt last) ->
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
//------------------------------------------------------------------------------
|
||||||
template<class T>
|
|
||||||
auto
|
|
||||||
fixed_string<N, CharT, Traits>::
|
|
||||||
assign(T const& t, size_type pos, size_type count) ->
|
|
||||||
typename std::enable_if<std::is_convertible<T,
|
|
||||||
string_view_type>::value, fixed_string&>::type
|
|
||||||
{
|
|
||||||
auto const sv = string_view_type(t).substr(pos, count);
|
|
||||||
if(sv.size() > max_size())
|
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
|
||||||
"sv.size() > max_size()"});
|
|
||||||
n_ = sv.size();
|
|
||||||
Traits::copy(&s_[0], &sv[0], n_);
|
|
||||||
term();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Element access
|
// Element access
|
||||||
//
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
@ -268,9 +253,11 @@ at(size_type pos) const ->
|
|||||||
return s_[pos];
|
return s_[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Capacity
|
// Capacity
|
||||||
//
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
void
|
void
|
||||||
@ -282,9 +269,11 @@ reserve(std::size_t n)
|
|||||||
"n > max_size()"});
|
"n > max_size()"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Operations
|
// Operations
|
||||||
//
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
void
|
void
|
||||||
@ -295,11 +284,16 @@ clear()
|
|||||||
term();
|
term();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
insert(size_type index, size_type count, CharT ch) ->
|
insert(
|
||||||
fixed_string&
|
size_type index,
|
||||||
|
size_type count,
|
||||||
|
CharT ch) ->
|
||||||
|
fixed_string&
|
||||||
{
|
{
|
||||||
if(index > size())
|
if(index > size())
|
||||||
BOOST_THROW_EXCEPTION(std::out_of_range{
|
BOOST_THROW_EXCEPTION(std::out_of_range{
|
||||||
@ -311,8 +305,11 @@ insert(size_type index, size_type count, CharT ch) ->
|
|||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
insert(size_type index, CharT const* s, size_type count) ->
|
insert(
|
||||||
fixed_string&
|
size_type index,
|
||||||
|
CharT const* s,
|
||||||
|
size_type count) ->
|
||||||
|
fixed_string&
|
||||||
{
|
{
|
||||||
if(index > size())
|
if(index > size())
|
||||||
BOOST_THROW_EXCEPTION(std::out_of_range{
|
BOOST_THROW_EXCEPTION(std::out_of_range{
|
||||||
@ -329,23 +326,13 @@ insert(size_type index, CharT const* s, size_type count) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
template<std::size_t M>
|
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
insert(size_type index,
|
insert(
|
||||||
fixed_string<M, CharT, Traits> const& s,
|
const_iterator pos,
|
||||||
size_type index_str, size_type count) ->
|
size_type count,
|
||||||
fixed_string&
|
CharT ch) ->
|
||||||
{
|
iterator
|
||||||
auto const ss = s.substr(index_str, count);
|
|
||||||
return insert(index, ss.data(), ss.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
|
||||||
auto
|
|
||||||
fixed_string<N, CharT, Traits>::
|
|
||||||
insert(const_iterator pos, size_type count, CharT ch) ->
|
|
||||||
iterator
|
|
||||||
{
|
{
|
||||||
if(size() + count > max_size())
|
if(size() + count > max_size())
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
@ -363,10 +350,13 @@ template<std::size_t N, typename CharT, typename Traits>
|
|||||||
template<class InputIt>
|
template<class InputIt>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
insert(const_iterator pos, InputIt first, InputIt last) ->
|
insert(
|
||||||
typename std::enable_if<
|
const_iterator pos,
|
||||||
detail::is_input_iterator<InputIt>::value,
|
InputIt first,
|
||||||
iterator>::type
|
InputIt last) ->
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::is_input_iterator<
|
||||||
|
InputIt>::value, iterator>::type
|
||||||
{
|
{
|
||||||
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())
|
||||||
@ -387,23 +377,49 @@ template<std::size_t N, typename CharT, typename Traits>
|
|||||||
template<class T>
|
template<class T>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
insert(size_type index, const T& t,
|
insert(
|
||||||
size_type index_str, size_type count) ->
|
size_type index,
|
||||||
typename std::enable_if<std::is_convertible<
|
T const & t) ->
|
||||||
T const&, string_view_type>::value &&
|
typename std::enable_if<
|
||||||
! std::is_convertible<T const&, CharT const*>::value,
|
std::is_convertible<
|
||||||
fixed_string&>::type
|
T const&, string_view_type>::value &&
|
||||||
|
! std::is_convertible<
|
||||||
|
T const&, CharT const*>::value, fixed_string&
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
return insert(index, t, 0, npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
|
template<class T>
|
||||||
|
auto
|
||||||
|
fixed_string<N, CharT, Traits>::
|
||||||
|
insert(
|
||||||
|
size_type index,
|
||||||
|
T const & t,
|
||||||
|
size_type index_str,
|
||||||
|
size_type count) ->
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_convertible<
|
||||||
|
T const&, string_view_type>::value &&
|
||||||
|
! std::is_convertible<
|
||||||
|
T const&, CharT const*>::value, fixed_string&
|
||||||
|
>::type
|
||||||
{
|
{
|
||||||
auto const s =
|
auto const s =
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
erase(size_type index, size_type count) ->
|
erase(
|
||||||
fixed_string&
|
size_type index,
|
||||||
|
size_type count) ->
|
||||||
|
fixed_string&
|
||||||
{
|
{
|
||||||
if(index > size())
|
if(index > size())
|
||||||
BOOST_THROW_EXCEPTION(std::out_of_range{
|
BOOST_THROW_EXCEPTION(std::out_of_range{
|
||||||
@ -418,8 +434,9 @@ erase(size_type index, size_type count) ->
|
|||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
erase(const_iterator pos) ->
|
erase(
|
||||||
iterator
|
const_iterator pos) ->
|
||||||
|
iterator
|
||||||
{
|
{
|
||||||
erase(pos - begin(), 1);
|
erase(pos - begin(), 1);
|
||||||
return begin() + (pos - begin());
|
return begin() + (pos - begin());
|
||||||
@ -428,8 +445,10 @@ erase(const_iterator pos) ->
|
|||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
erase(const_iterator first, const_iterator last) ->
|
erase(
|
||||||
iterator
|
const_iterator first,
|
||||||
|
const_iterator last) ->
|
||||||
|
iterator
|
||||||
{
|
{
|
||||||
erase(first - begin(),
|
erase(first - begin(),
|
||||||
std::distance(first, last));
|
std::distance(first, last));
|
||||||
@ -439,7 +458,8 @@ erase(const_iterator first, const_iterator last) ->
|
|||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
void
|
void
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
push_back(CharT ch)
|
push_back(
|
||||||
|
CharT ch)
|
||||||
{
|
{
|
||||||
if(size() >= max_size())
|
if(size() >= max_size())
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
@ -449,20 +469,21 @@ push_back(CharT ch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t N, typename CharT, typename Traits>
|
template<std::size_t N, typename CharT, typename Traits>
|
||||||
template<std::size_t M>
|
|
||||||
auto
|
auto
|
||||||
fixed_string<N, CharT, Traits>::
|
fixed_string<N, CharT, Traits>::
|
||||||
append(fixed_string<M, CharT, Traits> const& s,
|
append(
|
||||||
size_type pos, size_type count) ->
|
CharT const* s,
|
||||||
fixed_string&
|
size_type count) ->
|
||||||
|
fixed_string&
|
||||||
{
|
{
|
||||||
// Valid range is [0, size)
|
if(size() + count > max_size())
|
||||||
if(pos >= s.size())
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
BOOST_THROW_EXCEPTION(std::out_of_range{
|
"size() + count > max_size()"});
|
||||||
"pos > s.size()"});
|
Traits::move(
|
||||||
string_view_type const ss{&s.s_[pos],
|
&s_[n_ + count], &s_[n_], size() - n_);
|
||||||
(std::min)(count, s.size() - pos)};
|
Traits::copy(&s_[n_], s, count);
|
||||||
insert(size(), ss.data(), ss.size());
|
n_ += count;
|
||||||
|
term();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace fixed_string {
|
namespace fixed_string {
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
testConstruct()
|
testConstruct()
|
||||||
{
|
{
|
||||||
@ -117,9 +118,93 @@ testConstruct()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
testAssign()
|
testAssignment()
|
||||||
{
|
{
|
||||||
|
// assign(size_type count, CharT ch)
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign(1, '*') == "*");
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign(3, '*') == "***");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.assign(3, '*') == "***");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<1>{"a"}.assign(2, '*'), std::length_error);
|
||||||
|
|
||||||
|
// assign(fixed_string const& s) noexcept
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign(fixed_string<3>{"abc"}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign(fixed_string<3>{"abc"}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"***"}.assign(fixed_string<3>{"abc"}) == "abc");
|
||||||
|
|
||||||
|
// assign(fixed_string<M, CharT, Traits> const& s)
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign(fixed_string<5>{"abc"}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign(fixed_string<5>{"abc"}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"***"}.assign(fixed_string<5>{"abc"}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{}.assign(fixed_string<5>{"abcde"}), std::length_error);
|
||||||
|
|
||||||
|
// assign(fixed_string<M, CharT, Traits> const& s, size_type pos, size_type count = npos)
|
||||||
|
BOOST_TEST(fixed_string<4>{}.assign(fixed_string<5>{"abcde"}, 1) == "bcde");
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign(fixed_string<5>{"abcde"}, 1, 3) == "bcd");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign(fixed_string<5>{"abcde"}, 1, 3) == "bcd");
|
||||||
|
BOOST_TEST(fixed_string<3>{"***"}.assign(fixed_string<5>{"abcde"}, 1, 3) == "bcd");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{}.assign(fixed_string<5>{"abcde"}, 0), std::length_error);
|
||||||
|
|
||||||
|
// assign(CharT const* s, size_type count)
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign("abc", 3) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign("abc", 3) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<1>{}.assign("abc", 3), std::length_error);
|
||||||
|
|
||||||
|
// assign(CharT const* s)
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign("abc") == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign("abc") == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<1>{}.assign("abc"), std::length_error);
|
||||||
|
|
||||||
|
// assign(InputIt first, InputIt last)
|
||||||
|
{
|
||||||
|
fixed_string<4> const cs{"abcd"};
|
||||||
|
fixed_string<4> s{"ad"};
|
||||||
|
BOOST_TEST(fixed_string<4>{}.assign(cs.begin(), cs.end()) == "abcd");
|
||||||
|
BOOST_TEST(fixed_string<4>{"*"}.assign(cs.begin(), cs.end()) == "abcd");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<2>{"*"}.assign(cs.begin(), cs.end()), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign(std::initializer_list<CharT> ilist)
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign({'a', 'b', 'c'}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign({'a', 'b', 'c'}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"***"}.assign({'a', 'b', 'c'}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<1>{}.assign({'a', 'b', 'c'}), std::length_error);
|
||||||
|
|
||||||
|
// assign(T const& t)
|
||||||
|
{
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
operator string_view() const noexcept
|
||||||
|
{
|
||||||
|
return "abc";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BOOST_TEST(fixed_string<3>{}.assign(T{}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"*"}.assign(T{}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"***"}.assign(T{}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<2>{"**"}.assign(T{}), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign(T const& t, size_type pos, size_type count = npos)
|
||||||
|
{
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
operator string_view() const noexcept
|
||||||
|
{
|
||||||
|
return "abcde";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BOOST_TEST(fixed_string<5>{}.assign(T{}, 0) == "abcde");
|
||||||
|
BOOST_TEST(fixed_string<5>{}.assign(T{}, 0, 5) == "abcde");
|
||||||
|
BOOST_TEST(fixed_string<5>{}.assign(T{}, 1, 3) == "bcd");
|
||||||
|
BOOST_TEST(fixed_string<5>{"*"}.assign(T{}, 1) == "bcde");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<2>{"**"}.assign(T{}, 6, 3), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<2>{"**"}.assign(T{}, 1, 3), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<3> s1("123");
|
fixed_string<3> s1("123");
|
||||||
fixed_string<3> s2;
|
fixed_string<3> s2;
|
||||||
@ -291,9 +376,59 @@ testAssign()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
testAccess()
|
testElements()
|
||||||
{
|
{
|
||||||
|
using cfs3 = fixed_string<3> const;
|
||||||
|
|
||||||
|
// at(size_type pos)
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.at(0) == 'a');
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.at(2) == 'c');
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{""}.at(0), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.at(4), std::out_of_range);
|
||||||
|
|
||||||
|
// at(size_type pos) const
|
||||||
|
BOOST_TEST(cfs3{"abc"}.at(0) == 'a');
|
||||||
|
BOOST_TEST(cfs3{"abc"}.at(2) == 'c');
|
||||||
|
BOOST_TEST_THROWS(cfs3{""}.at(0), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(cfs3{"abc"}.at(4), std::out_of_range);
|
||||||
|
|
||||||
|
// operator[](size_type pos)
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}[0] == 'a');
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}[2] == 'c');
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}[3] == 0);
|
||||||
|
BOOST_TEST(fixed_string<3>{""}[0] == 0);
|
||||||
|
|
||||||
|
// operator[](size_type pos) const
|
||||||
|
BOOST_TEST(cfs3{"abc"}[0] == 'a');
|
||||||
|
BOOST_TEST(cfs3{"abc"}[2] == 'c');
|
||||||
|
BOOST_TEST(cfs3{"abc"}[3] == 0);
|
||||||
|
BOOST_TEST(cfs3{""}[0] == 0);
|
||||||
|
|
||||||
|
// front()
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.front() == 'a');
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.front() == 'a');
|
||||||
|
|
||||||
|
// front() const
|
||||||
|
BOOST_TEST(cfs3{"a"}.front() == 'a');
|
||||||
|
BOOST_TEST(cfs3{"abc"}.front() == 'a');
|
||||||
|
|
||||||
|
// back()
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.back() == 'a');
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.back() == 'c');
|
||||||
|
|
||||||
|
// back() const
|
||||||
|
BOOST_TEST(cfs3{"a"}.back() == 'a');
|
||||||
|
BOOST_TEST(cfs3{"abc"}.back() == 'c');
|
||||||
|
|
||||||
|
// data() noexcept
|
||||||
|
// data() const noexcept
|
||||||
|
// c_str() const noexcept
|
||||||
|
// operator string_view_type() const noexcept
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<5> s("12345");
|
fixed_string<5> s("12345");
|
||||||
BOOST_TEST(s.at(1) == '2');
|
BOOST_TEST(s.at(1) == '2');
|
||||||
@ -359,37 +494,74 @@ testAccess()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
testIterators()
|
testIterators()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
fixed_string<3> s;
|
fixed_string<3> s;
|
||||||
BOOST_TEST(std::distance(
|
BOOST_TEST(std::distance(s.begin(), s.end()) == 0);
|
||||||
s.begin(), s.end()) == 0);
|
BOOST_TEST(std::distance(s.rbegin(), s.rend()) == 0);
|
||||||
BOOST_TEST(std::distance(
|
|
||||||
s.rbegin(), s.rend()) == 0);
|
|
||||||
s = "123";
|
s = "123";
|
||||||
BOOST_TEST(std::distance(
|
BOOST_TEST(std::distance(s.begin(), s.end()) == 3);
|
||||||
s.begin(), s.end()) == 3);
|
BOOST_TEST(std::distance(s.rbegin(), s.rend()) == 3);
|
||||||
BOOST_TEST(std::distance(
|
|
||||||
s.rbegin(), s.rend()) == 3);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
fixed_string<3> const s("123");
|
fixed_string<3> const s("123");
|
||||||
BOOST_TEST(std::distance(
|
BOOST_TEST(std::distance(s.begin(), s.end()) == 3);
|
||||||
s.begin(), s.end()) == 3);
|
BOOST_TEST(std::distance(s.cbegin(), s.cend()) == 3);
|
||||||
BOOST_TEST(std::distance(
|
BOOST_TEST(std::distance(s.rbegin(), s.rend()) == 3);
|
||||||
s.cbegin(), s.cend()) == 3);
|
BOOST_TEST(std::distance(s.crbegin(), s.crend()) == 3);
|
||||||
BOOST_TEST(std::distance(
|
|
||||||
s.rbegin(), s.rend()) == 3);
|
|
||||||
BOOST_TEST(std::distance(
|
|
||||||
s.crbegin(), s.crend()) == 3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
testCapacity()
|
testCapacity()
|
||||||
{
|
{
|
||||||
|
// empty()
|
||||||
|
BOOST_TEST(fixed_string<0>{}.empty());
|
||||||
|
BOOST_TEST(fixed_string<1>{}.empty());
|
||||||
|
BOOST_TEST(! fixed_string<1>{"a"}.empty());
|
||||||
|
BOOST_TEST(! fixed_string<3>{"abc"}.empty());
|
||||||
|
|
||||||
|
// size()
|
||||||
|
BOOST_TEST(fixed_string<0>{}.size() == 0);
|
||||||
|
BOOST_TEST(fixed_string<1>{}.size() == 0);
|
||||||
|
BOOST_TEST(fixed_string<1>{"a"}.size() == 1);
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.size() == 3);
|
||||||
|
BOOST_TEST(fixed_string<5>{"abc"}.size() == 3);
|
||||||
|
|
||||||
|
// length()
|
||||||
|
BOOST_TEST(fixed_string<0>{}.length() == 0);
|
||||||
|
BOOST_TEST(fixed_string<1>{}.length() == 0);
|
||||||
|
BOOST_TEST(fixed_string<1>{"a"}.length() == 1);
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.length() == 3);
|
||||||
|
BOOST_TEST(fixed_string<5>{"abc"}.length() == 3);
|
||||||
|
|
||||||
|
// max_size()
|
||||||
|
BOOST_TEST(fixed_string<0>{}.max_size() == 0);
|
||||||
|
BOOST_TEST(fixed_string<1>{}.max_size() == 1);
|
||||||
|
BOOST_TEST(fixed_string<1>{"a"}.max_size() == 1);
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.max_size() == 3);
|
||||||
|
BOOST_TEST(fixed_string<5>{"abc"}.max_size() == 5);
|
||||||
|
|
||||||
|
// reserve(std::size_t n)
|
||||||
|
fixed_string<3>{}.reserve(0);
|
||||||
|
fixed_string<3>{}.reserve(1);
|
||||||
|
fixed_string<3>{}.reserve(3);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<0>{}.reserve(1), std::length_error);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{}.reserve(4), std::length_error);
|
||||||
|
|
||||||
|
// capacity()
|
||||||
|
BOOST_TEST(fixed_string<0>{}.capacity() == 0);
|
||||||
|
BOOST_TEST(fixed_string<1>{}.capacity() == 1);
|
||||||
|
BOOST_TEST(fixed_string<1>{"a"}.capacity() == 1);
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.capacity() == 3);
|
||||||
|
BOOST_TEST(fixed_string<5>{"abc"}.capacity() == 5);
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
fixed_string<3> s;
|
fixed_string<3> s;
|
||||||
BOOST_TEST(s.empty());
|
BOOST_TEST(s.empty());
|
||||||
BOOST_TEST(s.size() == 0);
|
BOOST_TEST(s.size() == 0);
|
||||||
@ -412,23 +584,117 @@ testCapacity()
|
|||||||
BOOST_TEST(*s.end() == 0);
|
BOOST_TEST(*s.end() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void
|
void
|
||||||
testOperations()
|
testClear()
|
||||||
{
|
{
|
||||||
//
|
// clear()
|
||||||
// clear
|
fixed_string<3> s("123");
|
||||||
//
|
s.clear();
|
||||||
|
BOOST_TEST(s.empty());
|
||||||
|
BOOST_TEST(*s.end() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
testInsert()
|
||||||
|
{
|
||||||
|
using sv = string_view;
|
||||||
|
|
||||||
|
// insert(size_type index, size_type count, CharT ch)
|
||||||
|
// The overload resolution is ambiguous
|
||||||
|
// here because 0 is also a pointer type
|
||||||
|
//BOOST_TEST(fixed_string<3>{"bc"}.insert(0, 1, 'a') == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"bc"}.insert(std::size_t(0), 1, 'a') == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"ac"}.insert(1, 1, 'b') == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"ab"}.insert(2, 1, 'c') == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.insert(4, 1, '*'), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.insert(1, 1, '*'), std::length_error);
|
||||||
|
|
||||||
|
// insert(size_type index, CharT const* s)
|
||||||
|
BOOST_TEST(fixed_string<3>{"bc"}.insert(0, "a") == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.insert(4, "*"), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.insert(1, "*"), std::length_error);
|
||||||
|
|
||||||
|
// insert(size_type index, CharT const* s, size_type count)
|
||||||
|
BOOST_TEST(fixed_string<4>{"ad"}.insert(1, "bcd", 2) == "abcd");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.insert(4, "*"), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.insert(1, "*"), std::length_error);
|
||||||
|
|
||||||
|
// insert(size_type index, string_view_type sv)
|
||||||
|
BOOST_TEST(fixed_string<3>{"ac"}.insert(1, sv{"b"}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.insert(4, sv{"*"}), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.insert(1, sv{"*"}), std::length_error);
|
||||||
|
|
||||||
|
// insert(size_type index, string_view_type sv, size_type index_str, size_type count = npos)
|
||||||
|
BOOST_TEST(fixed_string<4>{"ad"}.insert(1, sv{"abcd"}, 1, 2) == "abcd");
|
||||||
|
BOOST_TEST(fixed_string<4>{"ad"}.insert(1, sv{"abc"}, 1) == "abcd");
|
||||||
|
BOOST_TEST_THROWS((fixed_string<4>{"ad"}.insert(1, sv{"bc"}, 3, 0)), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS((fixed_string<3>{"ad"}.insert(1, sv{"bc"}, 0, 2)), std::length_error);
|
||||||
|
|
||||||
|
// insert(const_iterator pos, CharT ch)
|
||||||
{
|
{
|
||||||
fixed_string<3> s("123");
|
fixed_string<3> s{"ac"};
|
||||||
s.clear();
|
BOOST_TEST(s.insert(s.begin() + 1, 'b') == s.begin() + 1);
|
||||||
BOOST_TEST(s.empty());
|
BOOST_TEST(s == "abc");
|
||||||
BOOST_TEST(*s.end() == 0);
|
BOOST_TEST_THROWS(s.insert(s.begin() + 1, '*'), std::length_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// insert(const_iterator pos, size_type count, CharT ch)
|
||||||
// insert
|
{
|
||||||
//
|
fixed_string<4> s{"ac"};
|
||||||
|
BOOST_TEST(s.insert(s.begin() + 1, 2, 'b') == s.begin() + 1);
|
||||||
|
BOOST_TEST(s == "abbc");
|
||||||
|
BOOST_TEST_THROWS(s.insert(s.begin() + 1, 2, '*'), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert(const_iterator pos, InputIt first, InputIt last)
|
||||||
|
{
|
||||||
|
fixed_string<4> const cs{"abcd"};
|
||||||
|
fixed_string<4> s{"ad"};
|
||||||
|
BOOST_TEST(s.insert(s.begin() + 1, cs.begin() + 1, cs.begin() + 3) == s.begin() + 1);
|
||||||
|
BOOST_TEST(s == "abcd");
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert(const_iterator pos, std::initializer_list<CharT> ilist)
|
||||||
|
{
|
||||||
|
fixed_string<4> s{"ad"};
|
||||||
|
BOOST_TEST(s.insert(s.begin() + 1, {'b', 'c'}) == s.begin() + 1);
|
||||||
|
BOOST_TEST(s == "abcd");
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert(size_type index, T const& t)
|
||||||
|
{
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
operator string_view() const noexcept
|
||||||
|
{
|
||||||
|
return "b";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BOOST_TEST(fixed_string<3>{"ac"}.insert(1, T{}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.insert(4, T{}), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.insert(1, T{}), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert(size_type index, T const& t, size_type index_str, size_type count = npos)
|
||||||
|
{
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
operator string_view() const noexcept
|
||||||
|
{
|
||||||
|
return "abcd";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BOOST_TEST(fixed_string<6>{"ae"}.insert(1, T{}, 1) == "abcde");
|
||||||
|
BOOST_TEST(fixed_string<6>{"abe"}.insert(2, T{}, 2) == "abcde");
|
||||||
|
BOOST_TEST(fixed_string<4>{"ac"}.insert(1, T{}, 1, 1) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<4>{"ad"}.insert(1, T{}, 1, 2) == "abcd");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.insert(4, T{}), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.insert(1, T{}), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
// Using 7 as the size causes a miscompile in MSVC14.2 x64 Release
|
// Using 7 as the size causes a miscompile in MSVC14.2 x64 Release
|
||||||
@ -571,10 +837,42 @@ testOperations()
|
|||||||
(s1.insert(4, std::string("PQR"), 1, 1)),
|
(s1.insert(4, std::string("PQR"), 1, 1)),
|
||||||
std::length_error);
|
std::length_error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
static
|
||||||
// erase
|
void
|
||||||
//
|
testErase()
|
||||||
|
{
|
||||||
|
// erase(size_type index = 0, size_type count = npos)
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase() == "");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase(1) == "a");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase(2) == "ab");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase(1, 1) == "ac");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase(0, 2) == "c");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase(3, 0) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"abc"}.erase(3, 4) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.erase(4, 0), std::out_of_range);
|
||||||
|
|
||||||
|
// erase(const_iterator pos)
|
||||||
|
{
|
||||||
|
fixed_string<3> s{"abc"};
|
||||||
|
BOOST_TEST(s.erase(s.begin() + 1) == s.begin() + 1);
|
||||||
|
BOOST_TEST(s == "ac");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
fixed_string<3> s{"abc"};
|
||||||
|
BOOST_TEST(s.erase(s.begin() + 3) == s.end());
|
||||||
|
BOOST_TEST(s == "abc");
|
||||||
|
}
|
||||||
|
|
||||||
|
// erase(const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
fixed_string<4> s{"abcd"};
|
||||||
|
BOOST_TEST(s.erase(s.begin() + 1, s.begin() + 3) == s.begin() + 1);
|
||||||
|
BOOST_TEST(s == "ad");
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<9> s1("123456789");
|
fixed_string<9> s1("123456789");
|
||||||
@ -601,10 +899,23 @@ testOperations()
|
|||||||
BOOST_TEST(s1 == "1234589");
|
BOOST_TEST(s1 == "1234589");
|
||||||
BOOST_TEST(*s1.end() == 0);
|
BOOST_TEST(*s1.end() == 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
static
|
||||||
// push_back
|
void
|
||||||
//
|
testPushBack()
|
||||||
|
{
|
||||||
|
// push_back(CharT ch);
|
||||||
|
{
|
||||||
|
fixed_string<2> s;
|
||||||
|
s.push_back('a');
|
||||||
|
BOOST_TEST(s == "a");
|
||||||
|
s.push_back('b');
|
||||||
|
BOOST_TEST(s == "ab");
|
||||||
|
BOOST_TEST_THROWS(s.push_back('c'), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<3> s1("12");
|
fixed_string<3> s1("12");
|
||||||
@ -618,10 +929,28 @@ testOperations()
|
|||||||
s2.push_back('_'),
|
s2.push_back('_'),
|
||||||
std::length_error);
|
std::length_error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
static
|
||||||
// pop_back
|
void
|
||||||
//
|
testPopBack()
|
||||||
|
{
|
||||||
|
// pop_back()
|
||||||
|
{
|
||||||
|
fixed_string<3> s{"abc"};
|
||||||
|
BOOST_TEST(*s.end() == 0);
|
||||||
|
s.pop_back();
|
||||||
|
BOOST_TEST(s == "ab");
|
||||||
|
BOOST_TEST(*s.end() == 0);
|
||||||
|
s.pop_back();
|
||||||
|
BOOST_TEST(s == "a");
|
||||||
|
BOOST_TEST(*s.end() == 0);
|
||||||
|
s.pop_back();
|
||||||
|
BOOST_TEST(s.empty());
|
||||||
|
BOOST_TEST(*s.end() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<3> s1("123");
|
fixed_string<3> s1("123");
|
||||||
@ -635,10 +964,83 @@ testOperations()
|
|||||||
BOOST_TEST(s1.empty());
|
BOOST_TEST(s1.empty());
|
||||||
BOOST_TEST(*s1.end() == 0);
|
BOOST_TEST(*s1.end() == 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
static
|
||||||
// append
|
void
|
||||||
//
|
testAppend()
|
||||||
|
{
|
||||||
|
using sv = string_view;
|
||||||
|
|
||||||
|
// append(size_type count, CharT ch)
|
||||||
|
BOOST_TEST(fixed_string<1>{}.append(1, 'a') == "a");
|
||||||
|
BOOST_TEST(fixed_string<2>{}.append(2, 'a') == "aa");
|
||||||
|
BOOST_TEST(fixed_string<2>{"a"}.append(1, 'b') == "ab");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<2>{"ab"}.append(1, 'c'), std::length_error);
|
||||||
|
|
||||||
|
// append(string_view_type sv)
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append(sv{"bc"}) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"ab"}.append(sv{"c"}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append(sv{"*"}), std::length_error);
|
||||||
|
|
||||||
|
// append(string_view_type sv, size_type pos, size_type count = npos)
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append(sv{"abc"}, 1) == "abc");
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append(sv{"abc"}, 1, 2) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append(sv{"a"}, 2, 1), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append(sv{"abcd"}, 1, 2), std::length_error);
|
||||||
|
|
||||||
|
// append(CharT const* s, size_type count)
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append("bc", 0) == "a");
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append("bc", 2) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append("bc", 2), std::length_error);
|
||||||
|
|
||||||
|
// append(CharT const* s)
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append("bc") == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append("bc"), std::length_error);
|
||||||
|
|
||||||
|
// append(InputIt first, InputIt last)
|
||||||
|
{
|
||||||
|
fixed_string<4> const cs{"abcd"};
|
||||||
|
fixed_string<4> s{"ad"};
|
||||||
|
BOOST_TEST(fixed_string<4>{"ab"}.append(
|
||||||
|
cs.begin() + 2, cs.begin() + 4) == "abcd");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<2>{"ab"}.append(
|
||||||
|
cs.begin() + 2, cs.begin() + 4), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// append(std::initializer_list<CharT> ilist)
|
||||||
|
BOOST_TEST(fixed_string<4>{"ab"}.append({'c', 'd'}) == "abcd");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"ab"}.append({'c', 'd'}), std::length_error);
|
||||||
|
|
||||||
|
// append(T const& t)
|
||||||
|
{
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
operator string_view() const noexcept
|
||||||
|
{
|
||||||
|
return "c";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BOOST_TEST(fixed_string<3>{"ab"}.append(T{}) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append(T{}), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// append(T const& t, size_type pos, size_type count = npos)
|
||||||
|
{
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
operator string_view() const noexcept
|
||||||
|
{
|
||||||
|
return "abcd";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BOOST_TEST(fixed_string<4>{"ab"}.append(T{}, 2) == "abcd");
|
||||||
|
BOOST_TEST(fixed_string<3>{"a"}.append(T{}, 1, 2) == "abc");
|
||||||
|
BOOST_TEST_THROWS(fixed_string<4>{"abc"}.append(T{}, 5), std::out_of_range);
|
||||||
|
BOOST_TEST_THROWS(fixed_string<3>{"abc"}.append(T{}, 3, 1), std::length_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<3> s1("1");
|
fixed_string<3> s1("1");
|
||||||
@ -673,7 +1075,7 @@ testOperations()
|
|||||||
BOOST_TEST(*s3.end() == 0);
|
BOOST_TEST(*s3.end() == 0);
|
||||||
fixed_string<3> s4("12");
|
fixed_string<3> s4("12");
|
||||||
BOOST_TEST_THROWS(
|
BOOST_TEST_THROWS(
|
||||||
(s4.append(s1, 3)),
|
(s4.append(s1, 4)),
|
||||||
std::out_of_range);
|
std::out_of_range);
|
||||||
fixed_string<3> s5("12");
|
fixed_string<3> s5("12");
|
||||||
BOOST_TEST_THROWS(
|
BOOST_TEST_THROWS(
|
||||||
@ -745,10 +1147,31 @@ testOperations()
|
|||||||
(s2.append(std::string("PQR"), 1, 1)),
|
(s2.append(std::string("PQR"), 1, 1)),
|
||||||
std::length_error);
|
std::length_error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
static
|
||||||
// operator+=
|
void
|
||||||
//
|
testPlusEquals()
|
||||||
|
{
|
||||||
|
using sv = string_view;
|
||||||
|
|
||||||
|
// operator+=(CharT ch)
|
||||||
|
BOOST_TEST((fixed_string<3>{"ab"} += 'c') == "abc");
|
||||||
|
BOOST_TEST_THROWS((fixed_string<3>{"abc"} += '*'), std::length_error);
|
||||||
|
|
||||||
|
// operator+=(CharT const* s)
|
||||||
|
BOOST_TEST((fixed_string<3>{"a"} += "bc") == "abc");
|
||||||
|
BOOST_TEST_THROWS((fixed_string<3>{"abc"} += "*"), std::length_error);
|
||||||
|
|
||||||
|
// operator+=(std::initializer_list<CharT> init)
|
||||||
|
BOOST_TEST((fixed_string<3>{"a"} += {'b', 'c'}) == "abc");
|
||||||
|
BOOST_TEST_THROWS((fixed_string<3>{"abc"} += {'*', '*'}), std::length_error);
|
||||||
|
|
||||||
|
// operator+=(string_view_type const& s)
|
||||||
|
BOOST_TEST((fixed_string<3>{"a"} += sv{"bc"}) == "abc");
|
||||||
|
BOOST_TEST_THROWS((fixed_string<3>{"abc"} += sv{"*"}), std::length_error);
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_string<2> s1("__");
|
fixed_string<2> s1("__");
|
||||||
@ -1075,11 +1498,23 @@ int
|
|||||||
runTests()
|
runTests()
|
||||||
{
|
{
|
||||||
testConstruct();
|
testConstruct();
|
||||||
testAssign();
|
|
||||||
testAccess();
|
testAssignment();
|
||||||
|
|
||||||
|
testElements();
|
||||||
|
|
||||||
testIterators();
|
testIterators();
|
||||||
|
|
||||||
testCapacity();
|
testCapacity();
|
||||||
testOperations();
|
|
||||||
|
testClear();
|
||||||
|
testInsert();
|
||||||
|
testErase();
|
||||||
|
testPushBack();
|
||||||
|
testPopBack();
|
||||||
|
testAppend();
|
||||||
|
testPlusEquals();
|
||||||
|
|
||||||
testCompare();
|
testCompare();
|
||||||
testSwap();
|
testSwap();
|
||||||
testGeneral();
|
testGeneral();
|
||||||
|
Reference in New Issue
Block a user