Update basic_string with missing C++11 and C++17 interfaces:

- Default npos arguments in append, insert, compare
- Initializer list support
- Non-const data()
This commit is contained in:
Ion Gaztañaga
2017-02-21 23:08:11 +01:00
parent 865c69bab7
commit 08cce5ebe5
2 changed files with 101 additions and 13 deletions

View File

@@ -37,15 +37,18 @@
#include <boost/container/detail/next_capacity.hpp> #include <boost/container/detail/next_capacity.hpp>
#include <boost/container/detail/to_raw_pointer.hpp> #include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/version_type.hpp> #include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/minimal_char_traits_header.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/move/adl_move_swap.hpp> #include <boost/move/adl_move_swap.hpp>
#include <boost/static_assert.hpp> #include <boost/move/traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container/detail/minimal_char_traits_header.hpp>
#include <boost/functional/hash.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/functional/hash.hpp>
#include <algorithm> #include <algorithm>
#include <functional> //bind2nd, etc. #include <functional> //bind2nd, etc.
@@ -56,8 +59,12 @@
#include <locale> #include <locale>
#include <cstddef> #include <cstddef>
#include <climits> #include <climits>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/traits.hpp> //std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list> //for std::initializer_list
#endif
namespace boost { namespace boost {
namespace container { namespace container {
@@ -791,6 +798,17 @@ class basic_string
this->assign(f, l); this->assign(f, l);
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Same as basic_string(il.begin(), il.end(), a).
//!
basic_string(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
: base_t(a)
{
this->priv_terminate_string();
this->assign(il.begin(), il.end());
}
#endif
//! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated. //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
@@ -867,7 +885,7 @@ class basic_string
basic_string& operator=(const CharT* s) basic_string& operator=(const CharT* s)
{ return this->assign(s, s + Traits::length(s)); } { return this->assign(s, s + Traits::length(s)); }
//! <b>Effects</b>: Returns: *this = basic_string(1, c). //! <b>Effects</b>: Returns *this = basic_string(1, c).
//! //!
basic_string& operator=(CharT c) basic_string& operator=(CharT c)
{ return this->assign(static_cast<size_type>(1), c); } { return this->assign(static_cast<size_type>(1), c); }
@@ -878,6 +896,15 @@ class basic_string
basic_string& operator=(BasicStringView<CharT, Traits> sv) basic_string& operator=(BasicStringView<CharT, Traits> sv)
{ return this->assign(sv.data(), sv.size()); } { return this->assign(sv.data(), sv.size()); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Returns *this = basic_string(il);
//!
basic_string& operator=(std::initializer_list<CharT> il)
{
return this->assign(il.begin(), il.end());
}
#endif
//! <b>Effects</b>: Returns a copy of the internal allocator. //! <b>Effects</b>: Returns a copy of the internal allocator.
//! //!
//! <b>Throws</b>: If allocator's copy constructor throws. //! <b>Throws</b>: If allocator's copy constructor throws.
@@ -1295,6 +1322,15 @@ class basic_string
basic_string& operator+=(CharT c) basic_string& operator+=(CharT c)
{ this->push_back(c); return *this; } { this->push_back(c); return *this; }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Returns append(il)
//!
basic_string& operator+=(std::initializer_list<CharT> il)
{
return this->append(il);
}
#endif
//! <b>Effects</b>: Calls append(str.data(), str.size()). //! <b>Effects</b>: Calls append(str.data(), str.size()).
//! //!
//! <b>Returns</b>: *this //! <b>Returns</b>: *this
@@ -1315,7 +1351,7 @@ class basic_string
//! <b>Throws</b>: If memory allocation throws and out_of_range if pos > str.size() //! <b>Throws</b>: If memory allocation throws and out_of_range if pos > str.size()
//! //!
//! <b>Returns</b>: *this //! <b>Returns</b>: *this
basic_string& append(const basic_string& s, size_type pos, size_type n) basic_string& append(const basic_string& s, size_type pos, size_type n = npos)
{ {
if (pos > s.size()) if (pos > s.size())
throw_out_of_range("basic_string::append out of range position"); throw_out_of_range("basic_string::append out of range position");
@@ -1359,6 +1395,15 @@ class basic_string
basic_string& append(InputIter first, InputIter last) basic_string& append(InputIter first, InputIter last)
{ this->insert(this->end(), first, last); return *this; } { 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()).
//!
basic_string& append(std::initializer_list<CharT> il)
{
return this->append(il.begin(), il.size());
}
#endif
//! <b>Effects</b>: Equivalent to append(static_cast<size_type>(1), c). //! <b>Effects</b>: Equivalent to append(static_cast<size_type>(1), c).
//! //!
void push_back(CharT c) void push_back(CharT c)
@@ -1481,6 +1526,15 @@ class basic_string
return *this; return *this;
} }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Returns assign(il.begin(), il.size()).
//!
basic_string& assign(std::initializer_list<CharT> il)
{
return this->assign(il.begin(), il.size());
}
#endif
//! <b>Requires</b>: pos <= size(). //! <b>Requires</b>: pos <= size().
//! //!
//! <b>Effects</b>: Calls insert(pos, str.data(), str.size()). //! <b>Effects</b>: Calls insert(pos, str.data(), str.size()).
@@ -1507,7 +1561,7 @@ class basic_string
//! <b>Throws</b>: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size(). //! <b>Throws</b>: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size().
//! //!
//! <b>Returns</b>: *this //! <b>Returns</b>: *this
basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n) basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n = npos)
{ {
const size_type sz = this->size(); const size_type sz = this->size();
const size_type str_size = s.size(); const size_type str_size = s.size();
@@ -1741,6 +1795,17 @@ class basic_string
} }
#endif #endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: As if by insert(p, il.begin(), il.end()).
//!
//! <b>Returns</b>: An iterator which refers to the copy of the first inserted
//! character, or p if i1 is empty.
iterator insert(const_iterator p, std::initializer_list<CharT> il)
{
return this->insert(p, il.begin(), il.end());
}
#endif
//! <b>Effects</b>: Removes the last element from the container. //! <b>Effects</b>: Removes the last element from the container.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
@@ -2071,6 +2136,19 @@ class basic_string
, static_cast<size_type>(i2 - i1), sv); , static_cast<size_type>(i2 - i1), sv);
} }
#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()).
//!
//! <bReturns</b>: *this.
basic_string& replace(const_iterator i1, const_iterator i2, std::initializer_list<CharT> il)
{
return this->replace( static_cast<size_type>(i1 - begin())
, static_cast<size_type>(i2 - i1), il.begin(), il.size());
}
#endif
//! <b>Requires</b>: pos <= size() //! <b>Requires</b>: pos <= size()
//! //!
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as the //! <b>Effects</b>: Determines the effective length rlen of the string to copy as the
@@ -2126,6 +2204,12 @@ class basic_string
const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->priv_addr()); } { return container_detail::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.
CharT* data() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->priv_addr()); }
#ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN #ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
//! <b>Returns</b>: a string_view to the characters in the string. //! <b>Returns</b>: a string_view to the characters in the string.
//! //!
@@ -2624,7 +2708,7 @@ class basic_string
//! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size() //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size()
//! //!
//! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)). //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2) const int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const
{ {
if (pos1 > this->size() || pos2 > str.size()) if (pos1 > this->size() || pos2 > str.size())
throw_out_of_range("basic_string::compare out of range position"); throw_out_of_range("basic_string::compare out of range position");

View File

@@ -183,6 +183,10 @@ int string_test()
stdStringVect->push_back(auxStdString); stdStringVect->push_back(auxStdString);
} }
if(auxBoostString.data() != const_cast<const BoostString&>(auxBoostString).data() &&
auxBoostString.data() != &auxBoostString[0])
return 1;
if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ if(!CheckEqualStringVector(boostStringVect, stdStringVect)){
return 1; return 1;
} }