mirror of
https://github.com/boostorg/container.git
synced 2026-02-23 03:32:14 +00:00
Rollback clang's _NonNull attribute, too many warnings in older compilers. Replaced with BOOST_ASSERT null checks and added some corner cases to the test-suite.
This commit is contained in:
@@ -1462,7 +1462,8 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
* Updated `basic_string`:
|
||||
* Added missing `string_view` members and updated `operator[]` to be able to return the terminating null.
|
||||
* Added C++20 `starts_with`/`ends_with` and C++23 `contains` overloads.
|
||||
* Added Clang `nullability` checks for `basic_string` methods.
|
||||
* Added null pointer checks for `basic_string` methods taking `const CharT*` parameters.
|
||||
* Deleted constructor from `std::nullptr_t`.
|
||||
* Fixed bugs/issues:
|
||||
* [@https://github.com/boostorg/container/issues/323 GitHub #323: ['"flat_tree::try_emplace UB"]].
|
||||
* [@https://github.com/boostorg/container/issues/328 GitHub #328: ['"boost::container::deque stores a redundant copy of the allocator, increasing size"]].
|
||||
|
||||
@@ -252,18 +252,4 @@ namespace boost {
|
||||
#define BOOST_CONTAINER_NOVTABLE
|
||||
#endif
|
||||
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(nullability)
|
||||
# define BOOST_CONTAINER_NONNULL_SUPPORTED
|
||||
# define BOOST_CONTAINER_NONNULL _Nonnull
|
||||
# define BOOST_CONTAINER_NULLABLE _Nullable
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CONTAINER_NONNULL_SUPPORTED)
|
||||
# define BOOST_CONTAINER_NONNULL
|
||||
# define BOOST_CONTAINER_NULLABLE
|
||||
# undef BOOST_CONTAINER_NONNULL_SUPPORTED
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
@@ -240,16 +240,16 @@ class basic_string_base
|
||||
: allocator_type(boost::forward<AllocatorConvertible>(a))
|
||||
{ this->init(); }
|
||||
|
||||
inline const short_t * BOOST_CONTAINER_NONNULL pshort_repr() const
|
||||
inline const short_t * pshort_repr() const
|
||||
{ return move_detail::launder_cast<const short_t*>(&m_repr); }
|
||||
|
||||
inline const long_t * BOOST_CONTAINER_NONNULL plong_repr() const
|
||||
inline const long_t * plong_repr() const
|
||||
{ return move_detail::launder_cast<const long_t*>(&m_repr); }
|
||||
|
||||
inline short_t *BOOST_CONTAINER_NONNULL pshort_repr()
|
||||
inline short_t * pshort_repr()
|
||||
{ return move_detail::launder_cast<short_t*>(&m_repr); }
|
||||
|
||||
inline long_t *BOOST_CONTAINER_NONNULL plong_repr()
|
||||
inline long_t * plong_repr()
|
||||
{ return move_detail::launder_cast<long_t*>(&m_repr); }
|
||||
|
||||
repr_t m_repr;
|
||||
@@ -278,7 +278,7 @@ class basic_string_base
|
||||
return hdr.is_short != 0;
|
||||
}
|
||||
|
||||
inline short_t *BOOST_CONTAINER_NONNULL construct_short()
|
||||
inline short_t * construct_short()
|
||||
{
|
||||
short_t *ps = ::new(&this->members_.m_repr) short_t;
|
||||
ps->h.is_short = 1;
|
||||
@@ -291,7 +291,7 @@ class basic_string_base
|
||||
this->members_.pshort_repr()->~short_t();
|
||||
}
|
||||
|
||||
short_t *BOOST_CONTAINER_NONNULL assure_short()
|
||||
short_t * assure_short()
|
||||
{
|
||||
if (!this->is_short()){
|
||||
this->destroy_long();
|
||||
@@ -300,7 +300,7 @@ class basic_string_base
|
||||
return this->members_.pshort_repr();
|
||||
}
|
||||
|
||||
inline long_t *BOOST_CONTAINER_NONNULL construct_long()
|
||||
inline long_t * construct_long()
|
||||
{
|
||||
long_t *pl = ::new(&this->members_.m_repr) long_t;
|
||||
//is_short flag is written in the constructor
|
||||
@@ -313,7 +313,7 @@ class basic_string_base
|
||||
this->members_.plong_repr()->~long_t();
|
||||
}
|
||||
|
||||
long_t *BOOST_CONTAINER_NONNULL assure_long()
|
||||
long_t * assure_long()
|
||||
{
|
||||
if (this->is_short()){
|
||||
this->destroy_short();
|
||||
@@ -590,10 +590,10 @@ class basic_string
|
||||
typedef bool result_type;
|
||||
|
||||
typedef const typename Tr::char_type* Pointer;
|
||||
const Pointer BOOST_CONTAINER_NONNULL m_first;
|
||||
const Pointer BOOST_CONTAINER_NONNULL m_last;
|
||||
const Pointer m_first;
|
||||
const Pointer m_last;
|
||||
|
||||
Not_within_traits(Pointer BOOST_CONTAINER_NONNULL f, Pointer BOOST_CONTAINER_NONNULL l)
|
||||
Not_within_traits(Pointer f, Pointer l)
|
||||
: m_first(f), m_last(l) {}
|
||||
|
||||
bool operator()(const typename Tr::char_type& x) const
|
||||
@@ -655,6 +655,10 @@ class basic_string
|
||||
, n + 1)
|
||||
{ this->priv_terminate_string(); }
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
BOOST_DELETED_FUNCTION(basic_string( decltype(nullptr) ))
|
||||
#endif //!defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Effects</b>: Default constructs a basic_string.
|
||||
@@ -769,36 +773,38 @@ class basic_string
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking a default-constructed allocator,
|
||||
//! and is initialized by a specific number of characters of the s c-string.
|
||||
basic_string(const CharT* BOOST_CONTAINER_NONNULL s, size_type n)
|
||||
basic_string(const CharT* s, size_type n)
|
||||
: base_t()
|
||||
{
|
||||
this->priv_terminate_string();
|
||||
this->assign(s, s + difference_type(n));
|
||||
this->assign(s, n); // assign checks for s != 0
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and is initialized by a specific number of characters of the s c-string.
|
||||
basic_string(const CharT* BOOST_CONTAINER_NONNULL s, size_type n, const allocator_type& a)
|
||||
basic_string(const CharT* s, size_type n, const allocator_type& a)
|
||||
: base_t(a)
|
||||
{
|
||||
this->priv_terminate_string();
|
||||
this->assign(s, s + difference_type(n));
|
||||
this->assign(s, n); // assign checks for s != 0
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string with a default-constructed allocator,
|
||||
//! and is initialized by the null-terminated s c-string.
|
||||
basic_string(const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
basic_string(const CharT* s)
|
||||
: base_t()
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
this->priv_terminate_string();
|
||||
this->assign(s, s + Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and is initialized by the null-terminated s c-string.
|
||||
basic_string(const CharT* BOOST_CONTAINER_NONNULL s, const allocator_type& a)
|
||||
basic_string(const CharT* s, const allocator_type& a)
|
||||
: base_t(a)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
this->priv_terminate_string();
|
||||
this->assign(s, s + Traits::length(s));
|
||||
}
|
||||
@@ -931,8 +937,10 @@ class basic_string
|
||||
|
||||
//! <b>Effects</b>: Assignment from a null-terminated c-string.
|
||||
//!
|
||||
basic_string& operator=(const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{ return this->assign(s, s + Traits::length(s)); }
|
||||
basic_string& operator=(const CharT* s)
|
||||
{
|
||||
return this->assign(s); // assign checks for s != 0
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns *this = basic_string(1, c).
|
||||
//!
|
||||
@@ -1391,8 +1399,10 @@ class basic_string
|
||||
//! <b>Effects</b>: Calls append(s).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& operator+=(const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{ return this->append(s); }
|
||||
basic_string& operator+=(const CharT* s)
|
||||
{
|
||||
return this->append(s); //append checks for s != 0
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Calls append(1, c).
|
||||
//!
|
||||
@@ -1464,16 +1474,22 @@ class basic_string
|
||||
//! <b>Throws</b>: If memory allocation throws length_error if size() + n > max_size().
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& append(const CharT* BOOST_CONTAINER_NONNULL s, size_type n)
|
||||
{ return this->append(s, s + difference_type(n)); }
|
||||
basic_string& append(const CharT* s, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->append(s, s + difference_type(n));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
|
||||
//!
|
||||
//! <b>Effects</b>: Calls append(s, traits::length(s)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& append(const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{ return this->append(s, s + Traits::length(s)); }
|
||||
basic_string& append(const CharT* s)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->append(s, s + Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Equivalent to append(basic_string(n, c)).
|
||||
//!
|
||||
@@ -1491,11 +1507,11 @@ class basic_string
|
||||
{ this->insert(this->end(), first, last); return *this; }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: Returns append(il.begin(), il.size()).
|
||||
//! <b>Effects</b>: Returns append(il.begin(), il.end()).
|
||||
//!
|
||||
basic_string& append(std::initializer_list<CharT> il)
|
||||
{
|
||||
return this->append(il.begin(), il.size());
|
||||
return this->append(il.begin(), il.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1576,16 +1592,22 @@ class basic_string
|
||||
//! <b>Throws</b>: If memory allocation throws or length_error if n > max_size().
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& assign(const CharT* BOOST_CONTAINER_NONNULL s, size_type n)
|
||||
{ return this->assign(s, s + difference_type(n)); }
|
||||
basic_string& assign(const CharT* s, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->assign(s, s + difference_type(n));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
|
||||
//!
|
||||
//! <b>Effects</b>: Calls assign(s, traits::length(s)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& assign(const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{ return this->assign(s, s + Traits::length(s)); }
|
||||
basic_string& assign(const CharT* s)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->assign(s, s + Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Equivalent to assign(basic_string(n, c)).
|
||||
//!
|
||||
@@ -1596,11 +1618,11 @@ class basic_string
|
||||
//! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& assign(const CharT* BOOST_CONTAINER_NULLABLE first, const CharT* BOOST_CONTAINER_NULLABLE last)
|
||||
basic_string& assign(const CharT* first, const CharT* last)
|
||||
{
|
||||
size_type n = static_cast<size_type>(last - first);
|
||||
this->reserve(n);
|
||||
CharT* BOOST_CONTAINER_NONNULL ptr = boost::movelib::to_raw_pointer(this->priv_addr());
|
||||
CharT* const ptr = boost::movelib::to_raw_pointer(this->priv_addr());
|
||||
Traits::copy(ptr, first, n);
|
||||
this->priv_construct_null(ptr + difference_type(n));
|
||||
this->priv_size(n);
|
||||
@@ -1613,7 +1635,7 @@ class basic_string
|
||||
template <class InputIter>
|
||||
basic_string& assign(InputIter first, InputIter last
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
, typename dtl::disable_if_convertible<InputIter, size_type>::type * BOOST_CONTAINER_NULLABLE = 0
|
||||
, typename dtl::disable_if_convertible<InputIter, size_type>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -1635,11 +1657,11 @@ class basic_string
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Effects</b>: Returns assign(il.begin(), il.size()).
|
||||
//! <b>Effects</b>: Returns assign(il.begin(), il.end()).
|
||||
//!
|
||||
basic_string& assign(std::initializer_list<CharT> il)
|
||||
{
|
||||
return this->assign(il.begin(), il.size());
|
||||
return this->assign(il.begin(), il.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1695,8 +1717,9 @@ class basic_string
|
||||
//! length_error if size() + n > max_size().
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& insert(size_type pos, const CharT* BOOST_CONTAINER_NONNULL s, size_type n)
|
||||
basic_string& insert(size_type pos, const CharT* s, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos > this->size())
|
||||
throw_out_of_range("basic_string::insert out of range position");
|
||||
if (this->size() > this->max_size() - n)
|
||||
@@ -1713,8 +1736,9 @@ class basic_string
|
||||
//! length_error if size() > max_size() - Traits::length(s)
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& insert(size_type pos, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
basic_string& insert(size_type pos, const CharT* s)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos > this->size())
|
||||
throw_out_of_range("basic_string::insert out of range position");
|
||||
size_type len = Traits::length(s);
|
||||
@@ -1803,7 +1827,7 @@ class basic_string
|
||||
< void
|
||||
, dtl::is_convertible<InputIter, size_type>
|
||||
, dtl::is_not_input_iterator<InputIter>
|
||||
>::type * BOOST_CONTAINER_NULLABLE = 0
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -1821,7 +1845,7 @@ class basic_string
|
||||
< void
|
||||
, dtl::is_convertible<ForwardIter, size_type>
|
||||
, dtl::is_input_iterator<ForwardIter>
|
||||
>::type * BOOST_CONTAINER_NULLABLE = 0
|
||||
>::type * = 0
|
||||
)
|
||||
{
|
||||
const size_type n_pos = size_type(p - this->cbegin());
|
||||
@@ -2106,8 +2130,9 @@ class basic_string
|
||||
//! if the length of the resulting string would exceed max_size()
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
basic_string& replace(size_type pos1, size_type n1, const CharT* BOOST_CONTAINER_NONNULL s, size_type n2)
|
||||
basic_string& replace(size_type pos1, size_type n1, const CharT* s, size_type n2)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos1 > this->size())
|
||||
throw_out_of_range("basic_string::replace out of range position");
|
||||
const size_type len = dtl::min_value(n1, this->size() - pos1);
|
||||
@@ -2132,8 +2157,9 @@ class basic_string
|
||||
//! if the length of the resulting string would exceed max_size()
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
inline basic_string& replace(size_type pos, size_type n1, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
inline basic_string& replace(size_type pos, size_type n1, const CharT* s)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->replace(pos, n1, s, Traits::length(s));
|
||||
}
|
||||
|
||||
@@ -2174,8 +2200,11 @@ class basic_string
|
||||
//! <b>Throws</b>: if memory allocation throws
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
inline basic_string& replace(const_iterator i1, const_iterator i2, const CharT* BOOST_CONTAINER_NONNULL s, size_type n)
|
||||
{ return this->replace(i1, i2, s, s + difference_type(n)); }
|
||||
inline basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->replace(i1, i2, s, s + difference_type(n));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and s points to an
|
||||
//! array of at least traits::length(s) + 1 elements of CharT.
|
||||
@@ -2185,8 +2214,11 @@ class basic_string
|
||||
//! <b>Throws</b>: if memory allocation throws
|
||||
//!
|
||||
//! <b>Returns</b>: *this
|
||||
inline basic_string& replace(const_iterator i1, const_iterator i2, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{ return this->replace(i1, i2, s, s + Traits::length(s)); }
|
||||
inline basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->replace(i1, i2, s, s + Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
|
||||
//!
|
||||
@@ -2223,7 +2255,7 @@ class basic_string
|
||||
< void
|
||||
, dtl::is_convertible<InputIter, size_type>
|
||||
, dtl::is_input_iterator<InputIter>
|
||||
>::type * BOOST_CONTAINER_NULLABLE = 0
|
||||
>::type * = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -2245,7 +2277,7 @@ class basic_string
|
||||
< void
|
||||
, dtl::is_convertible<ForwardIter, size_type>
|
||||
, dtl::is_not_input_iterator<ForwardIter>
|
||||
>::type * BOOST_CONTAINER_NULLABLE = 0
|
||||
>::type * = 0
|
||||
)
|
||||
{
|
||||
difference_type n = boost::container::iterator_distance(j1, j2);
|
||||
@@ -2279,14 +2311,12 @@ class basic_string
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
//! <b>Requires</b>: [begin(), i1) and [i1, i2) are valid ranges.
|
||||
//!
|
||||
//! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, il.begin(), il.size()).
|
||||
//! <b>Effects</b>: Calls replace(i1, i2, il.begin(), il.end()).
|
||||
//!
|
||||
//! <b>Returns</b>: *this.
|
||||
inline basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il)
|
||||
{
|
||||
return this->replace( static_cast<size_type>(i1 - this->cbegin())
|
||||
, static_cast<size_type>(i2 - i1)
|
||||
, il.begin(), il.size());
|
||||
return this->replace(i1, i2, il.begin(), il.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2301,8 +2331,9 @@ class basic_string
|
||||
//! <b>Throws</b>: if memory allocation throws, out_of_range if pos > size().
|
||||
//!
|
||||
//! <b>Returns</b>: rlen
|
||||
size_type copy(CharT* BOOST_CONTAINER_NONNULL s, size_type n, size_type pos = 0) const
|
||||
size_type copy(CharT* s, size_type n, size_type pos = 0) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos > this->size())
|
||||
throw_out_of_range("basic_string::copy out of range position");
|
||||
const size_type len = dtl::min_value(n, this->size() - pos);
|
||||
@@ -2335,7 +2366,7 @@ class basic_string
|
||||
//!
|
||||
//! <b>Complexity</b>: constant time.
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
const CharT* BOOST_CONTAINER_NONNULL c_str() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return boost::movelib::to_raw_pointer(this->priv_addr()); }
|
||||
|
||||
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
|
||||
@@ -2344,14 +2375,14 @@ class basic_string
|
||||
//!
|
||||
//! <b>Complexity</b>: constant time.
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
const CharT* BOOST_CONTAINER_NONNULL data() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return boost::movelib::to_raw_pointer(this->priv_addr()); }
|
||||
|
||||
//! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
|
||||
//!
|
||||
//! <b>Complexity</b>: constant time.
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
CharT* BOOST_CONTAINER_NONNULL data() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
CharT* data() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return boost::movelib::to_raw_pointer(this->priv_addr()); }
|
||||
|
||||
#ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
|
||||
@@ -2411,8 +2442,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find(basic_string<CharT,traits,allocator_type>(s,n),pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos, size_type n) const
|
||||
size_type find(const CharT* s, size_type pos, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos + n > this->size())
|
||||
return npos;
|
||||
else {
|
||||
@@ -2432,8 +2464,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find(basic_string(s), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos = 0) const
|
||||
{ return this->find(s, pos, Traits::length(s)); }
|
||||
size_type find(const CharT* s, size_type pos = 0) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->find(s, pos, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
@@ -2485,8 +2520,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: rfind(basic_string(s, n), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type rfind(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos, size_type n) const
|
||||
size_type rfind(const CharT* s, size_type pos, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
const size_type len = this->size();
|
||||
|
||||
if (n > len)
|
||||
@@ -2508,8 +2544,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: rfind(basic_string(s), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type rfind(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos = npos) const
|
||||
{ return this->rfind(s, pos, Traits::length(s)); }
|
||||
size_type rfind(const CharT* s, size_type pos = npos) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->rfind(s, pos, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
@@ -2559,8 +2598,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_first_of(basic_string(s, n), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_first_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos, size_type n) const
|
||||
size_type find_first_of(const CharT* s, size_type pos, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
const size_type sz = this->size();
|
||||
if (pos >= sz)
|
||||
return npos;
|
||||
@@ -2579,8 +2619,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_first_of(basic_string(s), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_first_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos = 0) const
|
||||
{ return this->find_first_of(s, pos, Traits::length(s)); }
|
||||
size_type find_first_of(const CharT* s, size_type pos = 0) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->find_first_of(s, pos, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
|
||||
//!
|
||||
@@ -2620,8 +2663,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_last_of(basic_string(s, n), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_last_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos, size_type n) const
|
||||
size_type find_last_of(const CharT* s, size_type pos, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
const size_type len = this->size();
|
||||
|
||||
if (len < 1)
|
||||
@@ -2642,8 +2686,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_last_of(basic_string<CharT,traits,allocator_type>(1,c),pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_last_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos = npos) const
|
||||
{ return this->find_last_of(s, pos, Traits::length(s)); }
|
||||
size_type find_last_of(const CharT* s, size_type pos = npos) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->find_last_of(s, pos, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
@@ -2683,8 +2730,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_first_not_of(basic_string(s, n), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_first_not_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos, size_type n) const
|
||||
size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos > this->size())
|
||||
return npos;
|
||||
else {
|
||||
@@ -2702,8 +2750,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_first_not_of(basic_string(s), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_first_not_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos = 0) const
|
||||
{ return this->find_first_not_of(s, pos, Traits::length(s)); }
|
||||
size_type find_first_not_of(const CharT* s, size_type pos = 0) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->find_first_not_of(s, pos, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
@@ -2752,8 +2803,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_last_not_of(basic_string(s, n), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_last_not_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos, size_type n) const
|
||||
size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
const size_type len = this->size();
|
||||
|
||||
if (len < 1)
|
||||
@@ -2773,8 +2825,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: find_last_not_of(basic_string(s), pos).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
size_type find_last_not_of(const CharT* BOOST_CONTAINER_NONNULL s, size_type pos = npos) const
|
||||
{ return this->find_last_not_of(s, pos, Traits::length(s)); }
|
||||
size_type find_last_not_of(const CharT* s, size_type pos = npos) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->find_last_not_of(s, pos, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Throws</b>: Nothing
|
||||
//!
|
||||
@@ -2874,7 +2929,7 @@ class basic_string
|
||||
if (pos1 > this->size())
|
||||
throw_out_of_range("basic_string::compare out of range position");
|
||||
const pointer addr = this->priv_addr() + pos1;
|
||||
const CharT* BOOST_CONTAINER_NONNULL str_addr = sv.data();
|
||||
const CharT* const str_addr = sv.data();
|
||||
return this->s_compare(addr, addr + difference_type(dtl::min_value(n1, this->size() - pos1)),
|
||||
str_addr, str_addr + sv.size());
|
||||
}
|
||||
@@ -2922,9 +2977,10 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: compare(basic_string(s)).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
int compare(const CharT* BOOST_CONTAINER_NONNULL s) const
|
||||
int compare(const CharT* s) const
|
||||
{
|
||||
const pointer addr = this->priv_addr();
|
||||
BOOST_ASSERT(s != 0);
|
||||
const_pointer const addr = this->priv_addr();
|
||||
return this->s_compare(addr, addr + difference_type(this->priv_size()), s, s + Traits::length(s));
|
||||
}
|
||||
|
||||
@@ -2934,8 +2990,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
int compare(size_type pos1, size_type n1, const CharT* BOOST_CONTAINER_NONNULL s, size_type n2) const
|
||||
int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
if (pos1 > this->size())
|
||||
throw_out_of_range("basic_string::compare out of range position");
|
||||
const pointer addr = this->priv_addr();
|
||||
@@ -2950,8 +3007,11 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
int compare(size_type pos1, size_type n1, const CharT* BOOST_CONTAINER_NONNULL s) const
|
||||
{ return this->compare(pos1, n1, s, Traits::length(s)); }
|
||||
int compare(size_type pos1, size_type n1, const CharT* s) const
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
return this->compare(pos1, n1, s, Traits::length(s));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Equivalent to find(sv) != npos
|
||||
//!
|
||||
@@ -2978,8 +3038,10 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: true if the string contains the provided substring, false otherwise.
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
bool contains(const CharT* BOOST_CONTAINER_NONNULL s) const BOOST_NOEXCEPT
|
||||
{ return this->find(s) != npos; }
|
||||
bool contains(const CharT* s) const BOOST_NOEXCEPT
|
||||
{
|
||||
return this->find(s) != npos; //find checks s != 0
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Checks if the string begins with the given prefix
|
||||
//!
|
||||
@@ -3010,8 +3072,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: true if the string begins with the provided prefix, false otherwise.
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
bool starts_with(const CharT* BOOST_CONTAINER_NONNULL s) const BOOST_NOEXCEPT
|
||||
bool starts_with(const CharT* s) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
const std::size_t s_sz = Traits::length(s);
|
||||
const std::size_t t_sz = this->size();
|
||||
return t_sz >= s_sz && Traits::compare(this->data(), s, s_sz) == 0;
|
||||
@@ -3046,8 +3109,9 @@ class basic_string
|
||||
//!
|
||||
//! <b>Returns</b>: true if the string begins with the provided suffix, false otherwise.
|
||||
BOOST_CONTAINER_NODISCARD inline
|
||||
bool ends_with(const CharT* BOOST_CONTAINER_NONNULL s) const BOOST_NOEXCEPT
|
||||
bool ends_with(const CharT* s) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
const std::size_t s_sz = Traits::length(s);
|
||||
const std::size_t t_sz = this->size();
|
||||
return t_sz >= s_sz && Traits::compare(this->data() + std::ptrdiff_t(t_sz - s_sz), s, s_sz) == 0;
|
||||
@@ -3125,7 +3189,7 @@ class basic_string
|
||||
template<class AllocVersion>
|
||||
void priv_shrink_to_fit_dynamic_buffer
|
||||
( AllocVersion
|
||||
, typename dtl::enable_if<dtl::is_same<AllocVersion, version_1> >::type* BOOST_CONTAINER_NULLABLE = 0)
|
||||
, typename dtl::enable_if<dtl::is_same<AllocVersion, version_1> >::type* = 0)
|
||||
{
|
||||
//Allocate a new buffer.
|
||||
size_type real_cap = 0;
|
||||
@@ -3155,7 +3219,7 @@ class basic_string
|
||||
template<class AllocVersion>
|
||||
void priv_shrink_to_fit_dynamic_buffer
|
||||
( AllocVersion
|
||||
, typename dtl::enable_if<dtl::is_same<AllocVersion, version_2> >::type* BOOST_CONTAINER_NULLABLE = 0)
|
||||
, typename dtl::enable_if<dtl::is_same<AllocVersion, version_2> >::type* = 0)
|
||||
{
|
||||
size_type received_size = this->priv_long_size()+1;
|
||||
pointer hint = this->priv_long_addr();
|
||||
@@ -3192,9 +3256,7 @@ class basic_string
|
||||
Traits::assign(*result, *first);
|
||||
}
|
||||
|
||||
static inline void priv_copy( const CharT* BOOST_CONTAINER_NULLABLE first
|
||||
, const CharT* BOOST_CONTAINER_NULLABLE last
|
||||
, CharT* BOOST_CONTAINER_NONNULL result)
|
||||
static inline void priv_copy( const CharT* first, const CharT* last, CharT* result)
|
||||
{ Traits::copy(result, first, std::size_t(last - first)); }
|
||||
|
||||
template <class Integer>
|
||||
@@ -3313,17 +3375,18 @@ template <class CharT, class Traits, class Allocator> inline
|
||||
|
||||
template <class CharT, class Traits, class Allocator> inline
|
||||
basic_string<CharT, Traits, Allocator> operator+
|
||||
(const CharT* BOOST_CONTAINER_NONNULL s, basic_string<CharT, Traits, Allocator> y)
|
||||
(const CharT* s, basic_string<CharT, Traits, Allocator> y)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
y.insert(y.begin(), s, s + Traits::length(s));
|
||||
return y;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Allocator> inline
|
||||
basic_string<CharT,Traits,Allocator> operator+
|
||||
(basic_string<CharT,Traits,Allocator> x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
(basic_string<CharT,Traits,Allocator> x, const CharT* s)
|
||||
{
|
||||
x += s;
|
||||
x += s; //operator+= checks s != 0
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -3355,16 +3418,18 @@ operator==(const basic_string<CharT,Traits,Allocator>& x, const basic_string<Cha
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator==(const CharT* BOOST_CONTAINER_NONNULL s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
operator==(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
|
||||
return n == y.size() && Traits::compare(s, y.data(), n) == 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
|
||||
{
|
||||
BOOST_ASSERT(s != 0);
|
||||
typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
|
||||
return x.size() == n && Traits::compare(x.data(), s, n) == 0;
|
||||
}
|
||||
@@ -3398,14 +3463,17 @@ operator!=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<Cha
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator!=(const CharT* BOOST_CONTAINER_NONNULL s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{ return !(s == y); }
|
||||
operator!=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{
|
||||
return !(s == y);
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{ return !(x == s); }
|
||||
|
||||
operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
|
||||
{
|
||||
return !(x == s);
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
|
||||
inline
|
||||
@@ -3433,14 +3501,14 @@ operator<(const basic_string<CharT,Traits,Allocator>& x, const basic_string<Char
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator<(const CharT* BOOST_CONTAINER_NONNULL s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
operator<(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{
|
||||
return y.compare(s) > 0;
|
||||
}
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator<(const basic_string<CharT,Traits,Allocator>& x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
operator<(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
|
||||
{
|
||||
return x.compare(s) < 0;
|
||||
}
|
||||
@@ -3463,22 +3531,18 @@ operator<( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator>(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y) {
|
||||
return y < x;
|
||||
}
|
||||
operator>(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator>(const CharT* BOOST_CONTAINER_NONNULL s, const basic_string<CharT,Traits,Allocator>& y) {
|
||||
return y < s;
|
||||
}
|
||||
operator>(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{ return y < s; }
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
{
|
||||
return s < x;
|
||||
}
|
||||
operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
|
||||
{ return s < x; }
|
||||
|
||||
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
|
||||
inline
|
||||
@@ -3505,12 +3569,12 @@ operator<=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<Cha
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator<=(const CharT* BOOST_CONTAINER_NONNULL s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
operator<=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{ return !(y < s); }
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
|
||||
{ return !(s < x); }
|
||||
|
||||
|
||||
@@ -3538,12 +3602,12 @@ operator>=(const basic_string<CharT,Traits,Allocator>& x,
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator>=(const CharT* BOOST_CONTAINER_NONNULL s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
operator>=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
|
||||
{ return !(s < y); }
|
||||
|
||||
template <class CharT, class Traits, class Allocator>
|
||||
inline bool
|
||||
operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* BOOST_CONTAINER_NONNULL s)
|
||||
operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
|
||||
{ return !(x < s); }
|
||||
|
||||
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
|
||||
@@ -3575,7 +3639,7 @@ namespace dtl {
|
||||
template <class CharT, class Traits>
|
||||
inline bool
|
||||
string_fill(std::basic_ostream<CharT, Traits>& os,
|
||||
std::basic_streambuf<CharT, Traits>* BOOST_CONTAINER_NONNULL buf,
|
||||
std::basic_streambuf<CharT, Traits>* buf,
|
||||
std::size_t n)
|
||||
{
|
||||
CharT f = os.fill();
|
||||
|
||||
@@ -1291,6 +1291,9 @@ void test_insert_initializer_list()
|
||||
|
||||
s.insert(s.end(), {'d', 'e', 'f'});
|
||||
BOOST_TEST(s == "abcdef");
|
||||
|
||||
s.insert(s.end(), {});
|
||||
BOOST_TEST(s == "abcdef");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1412,6 +1415,9 @@ void test_append_initializer_list()
|
||||
|
||||
s.append({',', ' ', 'W', 'o', 'r', 'l', 'd', '!'});
|
||||
BOOST_TEST(s == "Hello, World!");
|
||||
|
||||
s.append({});
|
||||
BOOST_TEST(s == "Hello, World!");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1435,6 +1441,8 @@ void test_operator_plus_equals()
|
||||
// += initializer_list
|
||||
s += {'!', '!'};
|
||||
BOOST_TEST(s == "Hello, World!!!");
|
||||
s += {};
|
||||
BOOST_TEST(s == "Hello, World!!!");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1587,6 +1595,8 @@ void test_replace_iterator()
|
||||
s = "Hello, World!";
|
||||
s.replace(s.begin() + 7, s.begin() + 12, {'S', 'u', 'n'});
|
||||
BOOST_TEST(s == "Hello, Sun!");
|
||||
s.replace(s.begin() + 5, s.begin() + 10, {});
|
||||
BOOST_TEST(s == "Hello!");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user