mirror of git://gcc.gnu.org/git/gcc.git
PR libstdc++/58265 implement LWG 2063 for COW strings
For COW strings the default constructor does not allocate when _GLIBCXX_FULLY_DYNAMIC_STRING == 0, so can be noexcept. The move constructor and swap do not allocate when the allocators are equal, so add conditional noexcept using allocator_traits::is_always_equal. PR libstdc++/58265 * include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI] [_GLIBCXX_FULLY_DYNAMIC_STRING==0] (basic_string::basic_string()): Add GLIBCXX_NOEXCEPT. (basic_string::operator=(basic_string&&)): Add _GLIBCXX_NOEXCEPT_IF to depend on the allocator's is_always_equal property (LWG 2063). (basic_string::swap(basic_string&)): Likewise. * include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI] (basic_string::swap(basic_string&)): Likewise. * testsuite/21_strings/basic_string/allocator/char/move_assign.cc: Check is_nothrow_move_assignable. * testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc: Check is_nothrow_move_assignable. * testsuite/21_strings/basic_string/cons/char/ noexcept_move_construct.cc: Likewise. * testsuite/21_strings/basic_string/cons/wchar_t/ noexcept_move_construct.cc: Likewise. From-SVN: r262443
This commit is contained in:
parent
245471c67f
commit
d8d9b83b33
|
|
@ -1,3 +1,23 @@
|
||||||
|
2018-07-05 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/58265
|
||||||
|
* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
|
||||||
|
[_GLIBCXX_FULLY_DYNAMIC_STRING==0] (basic_string::basic_string()):
|
||||||
|
Add GLIBCXX_NOEXCEPT.
|
||||||
|
(basic_string::operator=(basic_string&&)): Add _GLIBCXX_NOEXCEPT_IF
|
||||||
|
to depend on the allocator's is_always_equal property (LWG 2063).
|
||||||
|
(basic_string::swap(basic_string&)): Likewise.
|
||||||
|
* include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]
|
||||||
|
(basic_string::swap(basic_string&)): Likewise.
|
||||||
|
* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
|
||||||
|
Check is_nothrow_move_assignable.
|
||||||
|
* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
|
||||||
|
Check is_nothrow_move_assignable.
|
||||||
|
* testsuite/21_strings/basic_string/cons/char/
|
||||||
|
noexcept_move_construct.cc: Likewise.
|
||||||
|
* testsuite/21_strings/basic_string/cons/wchar_t/
|
||||||
|
noexcept_move_construct.cc: Likewise.
|
||||||
|
|
||||||
2018-07-04 Jonathan Wakely <jwakely@redhat.com>
|
2018-07-04 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
P0646R1 Improving the Return Value of Erase-Like Algorithms I
|
P0646R1 Improving the Return Value of Erase-Like Algorithms I
|
||||||
|
|
|
||||||
|
|
@ -3486,6 +3486,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
|
||||||
*/
|
*/
|
||||||
basic_string()
|
basic_string()
|
||||||
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
|
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
|
||||||
|
_GLIBCXX_NOEXCEPT
|
||||||
: _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
|
: _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
|
||||||
#else
|
#else
|
||||||
: _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()){ }
|
: _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()){ }
|
||||||
|
|
@ -3675,9 +3676,9 @@ _GLIBCXX_END_NAMESPACE_CXX11
|
||||||
* The contents of @a str are moved into this string (without copying).
|
* The contents of @a str are moved into this string (without copying).
|
||||||
* @a str is a valid, but unspecified string.
|
* @a str is a valid, but unspecified string.
|
||||||
**/
|
**/
|
||||||
// PR 58265, this should be noexcept.
|
|
||||||
basic_string&
|
basic_string&
|
||||||
operator=(basic_string&& __str)
|
operator=(basic_string&& __str)
|
||||||
|
_GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)
|
||||||
{
|
{
|
||||||
// NB: DR 1204.
|
// NB: DR 1204.
|
||||||
this->swap(__str);
|
this->swap(__str);
|
||||||
|
|
@ -5111,9 +5112,9 @@ _GLIBCXX_END_NAMESPACE_CXX11
|
||||||
* Exchanges the contents of this string with that of @a __s in constant
|
* Exchanges the contents of this string with that of @a __s in constant
|
||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
// PR 58265, this should be noexcept.
|
|
||||||
void
|
void
|
||||||
swap(basic_string& __s);
|
swap(basic_string& __s)
|
||||||
|
_GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value);
|
||||||
|
|
||||||
// String operations:
|
// String operations:
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -967,6 +967,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
void
|
void
|
||||||
basic_string<_CharT, _Traits, _Alloc>::
|
basic_string<_CharT, _Traits, _Alloc>::
|
||||||
swap(basic_string& __s)
|
swap(basic_string& __s)
|
||||||
|
_GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)
|
||||||
{
|
{
|
||||||
if (_M_rep()->_M_is_leaked())
|
if (_M_rep()->_M_is_leaked())
|
||||||
_M_rep()->_M_set_sharable();
|
_M_rep()->_M_set_sharable();
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ void test01()
|
||||||
typedef propagating_allocator<C, false> alloc_type;
|
typedef propagating_allocator<C, false> alloc_type;
|
||||||
typedef std::basic_string<C, traits, alloc_type> test_type;
|
typedef std::basic_string<C, traits, alloc_type> test_type;
|
||||||
|
|
||||||
|
static_assert(std::is_move_assignable<test_type>::value, "");
|
||||||
|
static_assert(!std::is_nothrow_move_assignable<test_type>::value, "");
|
||||||
|
|
||||||
test_type v1(alloc_type(1));
|
test_type v1(alloc_type(1));
|
||||||
v1.assign(1, c);
|
v1.assign(1, c);
|
||||||
test_type v2(alloc_type(2));
|
test_type v2(alloc_type(2));
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ void test01()
|
||||||
typedef propagating_allocator<C, false> alloc_type;
|
typedef propagating_allocator<C, false> alloc_type;
|
||||||
typedef std::basic_string<C, traits, alloc_type> test_type;
|
typedef std::basic_string<C, traits, alloc_type> test_type;
|
||||||
|
|
||||||
|
static_assert(std::is_move_assignable<test_type>::value, "");
|
||||||
|
static_assert(!std::is_nothrow_move_assignable<test_type>::value, "");
|
||||||
|
|
||||||
test_type v1(alloc_type(1));
|
test_type v1(alloc_type(1));
|
||||||
v1.assign(1, c);
|
v1.assign(1, c);
|
||||||
test_type v2(alloc_type(2));
|
test_type v2(alloc_type(2));
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,8 @@
|
||||||
|
|
||||||
typedef std::string stype;
|
typedef std::string stype;
|
||||||
|
|
||||||
|
// True except for COW strings with _GLIBCXX_FULLY_DYNAMIC_STRING:
|
||||||
static_assert(std::is_nothrow_move_constructible<stype>::value, "Error");
|
static_assert(std::is_nothrow_move_constructible<stype>::value, "Error");
|
||||||
|
|
||||||
|
// True for std::allocator because is_always_equal, but not true in general:
|
||||||
|
static_assert(std::is_nothrow_move_assignable<stype>::value, "lwg 2063");
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,8 @@
|
||||||
|
|
||||||
typedef std::wstring wstype;
|
typedef std::wstring wstype;
|
||||||
|
|
||||||
|
// True except for COW strings with _GLIBCXX_FULLY_DYNAMIC_STRING:
|
||||||
static_assert(std::is_nothrow_move_constructible<wstype>::value, "Error");
|
static_assert(std::is_nothrow_move_constructible<wstype>::value, "Error");
|
||||||
|
|
||||||
|
// True for std::allocator because is_always_equal, but not true in general:
|
||||||
|
static_assert(std::is_nothrow_move_assignable<wstype>::value, "lwg 2063");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue