Implement N4258 noexcept for std::basic_string.

PR libstdc++/58265
	* doc/xml/manual/intro.xml: Document LWG 2063 and 2064 resolutions.
	* doc/html/manual/bugs.html: Regenerate.
	* include/bits/basic_string.h (basic_string): Implement N4258. Add
	correct exception-specifications and propagate allocators correctly.
	* include/bits/basic_string.tcc (basic_string::swap): Propagate
	allocators correctly.
	* include/debug/string (__gnu_debug::basic_string): Add correct
	exceptions-specifications and allcoator-extended constructors.
	* testsuite/21_strings/basic_string/allocator/char/copy.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/char/minimal.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/move.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/char/noexcept.cc: New.
	* testsuite/21_strings/basic_string/allocator/char/swap.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
	New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc: New.
	* testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc: New.
	* testsuite/util/testsuite_allocator.h (tracker_allocator): Define
	defaulted assignment operators.

From-SVN: r227681
This commit is contained in:
Jonathan Wakely 2015-09-11 12:02:14 +01:00 committed by Jonathan Wakely
parent 997ed914e2
commit 5caff414f1
21 changed files with 1450 additions and 33 deletions

View File

@ -1,5 +1,35 @@
2015-09-11 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/58265
* doc/xml/manual/intro.xml: Document LWG 2063 and 2064 resolutions.
* doc/html/manual/bugs.html: Regenerate.
* include/bits/basic_string.h (basic_string): Implement N4258. Add
correct exception-specifications and propagate allocators correctly.
* include/bits/basic_string.tcc (basic_string::swap): Propagate
allocators correctly.
* include/debug/string (__gnu_debug::basic_string): Add correct
exceptions-specifications and allcoator-extended constructors.
* testsuite/21_strings/basic_string/allocator/char/copy.cc: New.
* testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
New.
* testsuite/21_strings/basic_string/allocator/char/minimal.cc: New.
* testsuite/21_strings/basic_string/allocator/char/move.cc: New.
* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
New.
* testsuite/21_strings/basic_string/allocator/char/noexcept.cc: New.
* testsuite/21_strings/basic_string/allocator/char/swap.cc: New.
* testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc: New.
* testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
New.
* testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc: New.
* testsuite/21_strings/basic_string/allocator/wchar_t/move.cc: New.
* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
New.
* testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc: New.
* testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc: New.
* testsuite/util/testsuite_allocator.h (tracker_allocator): Define
defaulted assignment operators.
PR libstdc++/65092
* include/bits/stl_queue.h (queue, priority_queue): Add
allocator-extended constructors.

View File

@ -366,6 +366,12 @@
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2059" target="_top">2059</a>:
<span class="emphasis"><em>C++0x ambiguity problem with map::erase</em></span>
</span></dt><dd><p>Add additional overloads.
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2063" target="_top">2063</a>:
<span class="emphasis"><em>Contradictory requirements for string move assignment</em></span>
</span></dt><dd><p>Respect propagation trait for move assignment.
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2064" target="_top">2064</a>:
<span class="emphasis"><em>More noexcept issues in basic_string</em></span>
</span></dt><dd><p>Add noexcept to the comparison operators.
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2067" target="_top">2067</a>:
<span class="emphasis"><em>packaged_task should have deleted copy c'tor with const parameter</em></span>
</span></dt><dd><p>Fix signatures.

View File

@ -850,6 +850,18 @@ requirements of the license of GCC.
<listitem><para>Add additional overloads.
</para></listitem></varlistentry>
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2063">2063</link>:
<emphasis>Contradictory requirements for string move assignment</emphasis>
</term>
<listitem><para>Respect propagation trait for move assignment.
</para></listitem></varlistentry>
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2064">2064</link>:
<emphasis>More noexcept issues in basic_string</emphasis>
</term>
<listitem><para>Add noexcept to the comparison operators.
</para></listitem></varlistentry>
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2067">2067</link>:
<emphasis>packaged_task should have deleted copy c'tor with const parameter</emphasis>
</term>

View File

@ -379,9 +379,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @brief Default constructor creates an empty string.
*/
basic_string()
#if __cplusplus >= 201103L
noexcept(is_nothrow_default_constructible<_Alloc>::value)
#endif
_GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)
: _M_dataplus(_M_local_data())
{ _M_set_length(0); }
@ -389,7 +387,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @brief Construct an empty string using allocator @a a.
*/
explicit
basic_string(const _Alloc& __a)
basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT
: _M_dataplus(_M_local_data(), __a)
{ _M_set_length(0); }
@ -398,7 +396,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* @param __str Source string.
*/
basic_string(const basic_string& __str)
: _M_dataplus(_M_local_data(), __str._M_get_allocator()) // TODO A traits
: _M_dataplus(_M_local_data(),
_Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
{ _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
/**
@ -511,10 +510,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ _M_construct(__str.begin(), __str.end()); }
basic_string(basic_string&& __str, const _Alloc& __a)
noexcept(_Alloc_traits::_S_always_equal())
: _M_dataplus(_M_local_data(), __a)
{
if (__str.get_allocator() == __a)
*this = std::move(__str);
if (__str._M_is_local())
{
traits_type::copy(_M_local_buf, __str._M_local_buf,
_S_local_capacity + 1);
_M_length(__str.length());
__str._M_set_length(0);
}
else if (_Alloc_traits::_S_always_equal()
|| __str.get_allocator() == __a)
{
_M_data(__str._M_data());
_M_length(__str.length());
_M_capacity(__str._M_allocated_capacity);
__str._M_data(__str._M_local_buf);
__str._M_set_length(0);
}
else
_M_construct(__str.begin(), __str.end());
}
@ -550,7 +564,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
basic_string&
operator=(const basic_string& __str)
{ return this->assign(__str); }
{
#if __cplusplus >= 201103L
if (_Alloc_traits::_S_propagate_on_copy_assign())
{
if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
&& _M_get_allocator() != __str._M_get_allocator())
{
// replacement allocator cannot free existing storage
_M_destroy(_M_allocated_capacity);
_M_data(_M_local_data());
_M_set_length(0);
}
std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
}
#endif
return this->assign(__str);
}
/**
* @brief Copy contents of @a s into this string.
@ -587,8 +617,51 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// 2063. Contradictory requirements for string move assignment
basic_string&
operator=(basic_string&& __str)
noexcept(_Alloc_traits::_S_nothrow_move())
{
this->swap(__str);
if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
&& !_Alloc_traits::_S_always_equal()
&& _M_get_allocator() != __str._M_get_allocator())
{
// Destroy existing storage before replacing allocator.
_M_destroy(_M_allocated_capacity);
_M_data(_M_local_data());
_M_set_length(0);
}
// Replace allocator if POCMA is true.
std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator());
if (!__str._M_is_local()
&& (_Alloc_traits::_S_propagate_on_move_assign()
|| _Alloc_traits::_S_always_equal()))
{
pointer __data = nullptr;
size_type __capacity;
if (!_M_is_local())
{
if (_Alloc_traits::_S_always_equal())
{
__data = _M_data();
__capacity = _M_allocated_capacity;
}
else
_M_destroy(_M_allocated_capacity);
}
_M_data(__str._M_data());
_M_length(__str.length());
_M_capacity(__str._M_allocated_capacity);
if (__data)
{
__str._M_data(__data);
__str._M_capacity(__capacity);
}
else
__str._M_data(__str._M_local_buf);
}
else
assign(__str);
__str.clear();
return *this;
}
@ -1119,6 +1192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
basic_string&
assign(basic_string&& __str)
noexcept(_Alloc_traits::_S_nothrow_move())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2063. Contradictory requirements for string move assignment
@ -4961,13 +5035,14 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline bool
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) == 0; }
template<typename _CharT>
inline
typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
operator==(const basic_string<_CharT>& __lhs,
const basic_string<_CharT>& __rhs)
const basic_string<_CharT>& __rhs) _GLIBCXX_NOEXCEPT
{ return (__lhs.size() == __rhs.size()
&& !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
__lhs.size())); }
@ -5007,6 +5082,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline bool
operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT
{ return !(__lhs == __rhs); }
/**
@ -5044,6 +5120,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline bool
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) < 0; }
/**
@ -5081,6 +5158,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline bool
operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) > 0; }
/**
@ -5118,6 +5196,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline bool
operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) <= 0; }
/**
@ -5155,6 +5234,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline bool
operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) >= 0; }
/**
@ -5192,6 +5272,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
inline void
swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
basic_string<_CharT, _Traits, _Alloc>& __rhs)
_GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
{ __lhs.swap(__rhs); }

View File

@ -61,11 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this == &__s)
return;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 431. Swapping containers with unequal allocators.
// TODO propagation traits
std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(),
__s._M_get_allocator());
_Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator());
if (_M_is_local())
if (__s._M_is_local())
@ -404,7 +400,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__new_size <= this->capacity())
{
_CharT* __p = this->_M_data() + __pos1;
pointer __p = this->_M_data() + __pos1;
const size_type __how_much = __old_size - __pos1 - __n1;
if (__how_much && __n1 != __n2)
@ -433,7 +429,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__new_size <= this->capacity())
{
_CharT* __p = this->_M_data() + __pos;
pointer __p = this->_M_data() + __pos;
const size_type __how_much = __old_size - __pos - __len1;
if (_M_disjunct(__s))

View File

@ -36,19 +36,19 @@
namespace __gnu_debug
{
/// Class std::basic_string with safety/checking/debug instrumentation.
template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
typename _Allocator = std::allocator<_CharT> >
class basic_string
: public __gnu_debug::_Safe_container<
basic_string<_CharT, _Traits, _Allocator>,
_Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
public std::basic_string<_CharT, _Traits, _Allocator>
{
typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
_Safe;
/// Class std::basic_string with safety/checking/debug instrumentation.
template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
typename _Allocator = std::allocator<_CharT> >
class basic_string
: public __gnu_debug::_Safe_container<
basic_string<_CharT, _Traits, _Allocator>,
_Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
public std::basic_string<_CharT, _Traits, _Allocator>
{
typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
_Safe;
public:
// types:
@ -72,9 +72,13 @@ namespace __gnu_debug
using _Base::npos;
basic_string()
_GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value)
: _Base() { }
// 21.3.1 construct/copy/destroy:
explicit basic_string(const _Allocator& __a = _Allocator())
// _GLIBCXX_NOEXCEPT
explicit
basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT
: _Base(__a) { }
#if __cplusplus < 201103L
@ -91,7 +95,19 @@ namespace __gnu_debug
: _Base(__l, __a)
{ }
#if _GLIBCXX_USE_CXX11_ABI
basic_string(const basic_string& __s, const _Allocator& __a)
: _Base(__s, __a) { }
basic_string(basic_string&& __s, const _Allocator& __a)
: _Base(std::move(__s), __a) { }
#endif
~basic_string() = default;
// Provides conversion from a normal-mode string to a debug-mode string
basic_string(_Base&& __base) noexcept
: _Base(std::move(__base)) { }
#endif // C++11
// Provides conversion from a normal-mode string to a debug-mode string
@ -278,7 +294,7 @@ namespace __gnu_debug
reference
operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
{
#ifdef _GLIBCXX_DEBUG_PEDANTIC
#if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
__glibcxx_check_subscript(__pos);
#else
// as an extension v3 allows s[s.size()] when s is non-const.
@ -413,6 +429,7 @@ namespace __gnu_debug
#if __cplusplus >= 201103L
basic_string&
assign(basic_string&& __x)
noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
{
_Base::assign(std::move(__x));
this->_M_invalidate_all();
@ -729,6 +746,7 @@ namespace __gnu_debug
void
swap(basic_string& __x)
_GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
{
_Safe::_M_swap(__x);
_Base::swap(__x);

View File

@ -0,0 +1,97 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(0 == v2.get_allocator().get_personality());
v1.assign(100, c);
test_type v3(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(0 == v3.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
v1.assign(100, c);
test_type v3(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v3.get_allocator().get_personality());
}
void test03()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(v1, alloc_type(2));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
v1.assign(100, c);
test_type v3(v1, alloc_type(3));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(3 == v3.get_allocator().get_personality());
}
int main()
{
test01();
test02();
test03();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,114 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
v1.assign(1, c);
test_type v3(alloc_type(3));
v3.assign(100, c);
v3 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(3 == v3.get_allocator().get_personality());
v1.assign(100, c);
test_type v4(alloc_type(4));
v4.assign(1, c);
v4 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(4 == v4.get_allocator().get_personality());
v1.assign(100, c);
test_type v5(alloc_type(5));
v5.assign(100, c);
v5 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(5 == v5.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
v1.assign(1, c);
test_type v3(alloc_type(3));
v3.assign(100, c);
v3 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v3.get_allocator().get_personality());
v1.assign(100, c);
test_type v4(alloc_type(4));
v4.assign(1, c);
v4 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v4.get_allocator().get_personality());
v1.assign(100, c);
test_type v5(alloc_type(5));
v5.assign(100, c);
v5 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v5.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::SimpleAllocator;
template class std::basic_string<C,traits, SimpleAllocator<C>>;
void test01()
{
#if _GLIBCXX_USE_CXX11_ABI
typedef SimpleAllocator<C> alloc_type;
typedef std::allocator_traits<alloc_type> traits_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v(alloc_type{});
v.assign(1, c);
v.assign(100, c);
#endif
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,66 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<C> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<C> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(std::move(v1), alloc_type(2));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,160 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
test_type v3(alloc_type(3));
v3.assign(1, c);
test_type v4(alloc_type(4));
v4.assign(100, c);
v4 = std::move(v3);
VERIFY(3 == v3.get_allocator().get_personality());
VERIFY(4 == v4.get_allocator().get_personality());
test_type v5(alloc_type(5));
v5.assign(100, c);
test_type v6(alloc_type(6));
v6.assign(1, c);
v6 = std::move(v5);
VERIFY(5 == v5.get_allocator().get_personality());
VERIFY(6 == v6.get_allocator().get_personality());
test_type v7(alloc_type(7));
v7.assign(100, c);
test_type v8(alloc_type(8));
v8.assign(100, c);
v8 = std::move(v7);
VERIFY(7 == v7.get_allocator().get_personality());
VERIFY(8 == v8.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
test_type v3(alloc_type(3));
v3.assign(1, c);
test_type v4(alloc_type(4));
v4.assign(100, c);
v4 = std::move(v3);
VERIFY(0 == v3.get_allocator().get_personality());
VERIFY(3 == v4.get_allocator().get_personality());
test_type v5(alloc_type(5));
v5.assign(100, c);
test_type v6(alloc_type(6));
v6.assign(1, c);
v6 = std::move(v5);
VERIFY(0 == v5.get_allocator().get_personality());
VERIFY(5 == v6.get_allocator().get_personality());
test_type v7(alloc_type(7));
v7.assign(100, c);
test_type v8(alloc_type(8));
v8.assign(100, c);
v8 = std::move(v7);
VERIFY(0 == v7.get_allocator().get_personality());
VERIFY(7 == v8.get_allocator().get_personality());
}
void test03()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(1));
v2.assign(1, c);
v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
test_type v3(alloc_type(3));
v3.assign(1, c);
test_type v4(alloc_type(3));
v4.assign(100, c);
v4 = std::move(v3);
VERIFY(3 == v3.get_allocator().get_personality());
VERIFY(3 == v4.get_allocator().get_personality());
test_type v5(alloc_type(5));
v5.assign(100, c);
test_type v6(alloc_type(5));
v6.assign(1, c);
v6 = std::move(v5);
VERIFY(5 == v5.get_allocator().get_personality());
VERIFY(5 == v6.get_allocator().get_personality());
test_type v7(alloc_type(7));
v7.assign(100, c);
test_type v8(alloc_type(7));
v8.assign(100, c);
v8 = std::move(v7);
VERIFY(7 == v7.get_allocator().get_personality());
VERIFY(7 == v8.get_allocator().get_personality());
}
int main()
{
test01();
test02();
test03();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,61 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
typedef std::allocator<C> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1;
test_type v2;
// this is a GNU extension for std::allocator
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
void test02()
{
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
test_type v2(alloc_type(2));
static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
void test03()
{
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
test_type v2(alloc_type(2));
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
#endif

View File

@ -0,0 +1,89 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
// It is undefined behaviour to swap() containers wth unequal allocators
// if the allocator doesn't propagate, so ensure the allocators compare
// equal, while still being able to test propagation via get_personality().
bool
operator==(const propagating_allocator<C, false>&,
const propagating_allocator<C, false>&)
{
return true;
}
bool
operator!=(const propagating_allocator<C, false>&,
const propagating_allocator<C, false>&)
{
return false;
}
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(C());
test_type v2(alloc_type(2));
v2.push_back(C());
std::swap(v1, v2);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
// swap back so assertions in uneq_allocator::deallocate don't fail
std::swap(v1, v2);
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(C());
test_type v2(alloc_type(2));
v2.push_back(C());
std::swap(v1, v2);
VERIFY(2 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,97 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(0 == v2.get_allocator().get_personality());
v1.assign(100, c);
test_type v3(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(0 == v3.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
v1.assign(100, c);
test_type v3(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v3.get_allocator().get_personality());
}
void test03()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(v1, alloc_type(2));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
v1.assign(100, c);
test_type v3(v1, alloc_type(3));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(3 == v3.get_allocator().get_personality());
}
int main()
{
test01();
test02();
test03();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,114 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
v1.assign(1, c);
test_type v3(alloc_type(3));
v3.assign(100, c);
v3 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(3 == v3.get_allocator().get_personality());
v1.assign(100, c);
test_type v4(alloc_type(4));
v4.assign(1, c);
v4 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(4 == v4.get_allocator().get_personality());
v1.assign(100, c);
test_type v5(alloc_type(5));
v5.assign(100, c);
v5 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(5 == v5.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
v1.assign(1, c);
test_type v3(alloc_type(3));
v3.assign(100, c);
v3 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v3.get_allocator().get_personality());
v1.assign(100, c);
test_type v4(alloc_type(4));
v4.assign(1, c);
v4 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v4.get_allocator().get_personality());
v1.assign(100, c);
test_type v5(alloc_type(5));
v5.assign(100, c);
v5 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v5.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,49 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::SimpleAllocator;
template class std::basic_string<C,traits, SimpleAllocator<C>>;
void test01()
{
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
typedef SimpleAllocator<C> alloc_type;
typedef std::allocator_traits<alloc_type> traits_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v(alloc_type{});
v.assign(1, c);
v.assign(100, c);
#endif
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,66 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<C> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<C> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(std::move(v1), alloc_type(2));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,160 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
test_type v3(alloc_type(3));
v3.assign(1, c);
test_type v4(alloc_type(4));
v4.assign(100, c);
v4 = std::move(v3);
VERIFY(3 == v3.get_allocator().get_personality());
VERIFY(4 == v4.get_allocator().get_personality());
test_type v5(alloc_type(5));
v5.assign(100, c);
test_type v6(alloc_type(6));
v6.assign(1, c);
v6 = std::move(v5);
VERIFY(5 == v5.get_allocator().get_personality());
VERIFY(6 == v6.get_allocator().get_personality());
test_type v7(alloc_type(7));
v7.assign(100, c);
test_type v8(alloc_type(8));
v8.assign(100, c);
v8 = std::move(v7);
VERIFY(7 == v7.get_allocator().get_personality());
VERIFY(8 == v8.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(2));
v2.assign(1, c);
v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
test_type v3(alloc_type(3));
v3.assign(1, c);
test_type v4(alloc_type(4));
v4.assign(100, c);
v4 = std::move(v3);
VERIFY(0 == v3.get_allocator().get_personality());
VERIFY(3 == v4.get_allocator().get_personality());
test_type v5(alloc_type(5));
v5.assign(100, c);
test_type v6(alloc_type(6));
v6.assign(1, c);
v6 = std::move(v5);
VERIFY(0 == v5.get_allocator().get_personality());
VERIFY(5 == v6.get_allocator().get_personality());
test_type v7(alloc_type(7));
v7.assign(100, c);
test_type v8(alloc_type(8));
v8.assign(100, c);
v8 = std::move(v7);
VERIFY(0 == v7.get_allocator().get_personality());
VERIFY(7 == v8.get_allocator().get_personality());
}
void test03()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.assign(1, c);
test_type v2(alloc_type(1));
v2.assign(1, c);
v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
test_type v3(alloc_type(3));
v3.assign(1, c);
test_type v4(alloc_type(3));
v4.assign(100, c);
v4 = std::move(v3);
VERIFY(3 == v3.get_allocator().get_personality());
VERIFY(3 == v4.get_allocator().get_personality());
test_type v5(alloc_type(5));
v5.assign(100, c);
test_type v6(alloc_type(5));
v6.assign(1, c);
v6 = std::move(v5);
VERIFY(5 == v5.get_allocator().get_personality());
VERIFY(5 == v6.get_allocator().get_personality());
test_type v7(alloc_type(7));
v7.assign(100, c);
test_type v8(alloc_type(7));
v8.assign(100, c);
v8 = std::move(v7);
VERIFY(7 == v7.get_allocator().get_personality());
VERIFY(7 == v8.get_allocator().get_personality());
}
int main()
{
test01();
test02();
test03();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -0,0 +1,61 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
void test01()
{
typedef std::allocator<C> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1;
test_type v2;
// this is a GNU extension for std::allocator
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
void test02()
{
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
test_type v2(alloc_type(2));
static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
void test03()
{
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
test_type v2(alloc_type(2));
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
#endif

View File

@ -0,0 +1,89 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <string>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T)
using C = char;
const C c = 'a';
using traits = std::char_traits<C>;
using __gnu_test::propagating_allocator;
// It is undefined behaviour to swap() containers wth unequal allocators
// if the allocator doesn't propagate, so ensure the allocators compare
// equal, while still being able to test propagation via get_personality().
bool
operator==(const propagating_allocator<C, false>&,
const propagating_allocator<C, false>&)
{
return true;
}
bool
operator!=(const propagating_allocator<C, false>&,
const propagating_allocator<C, false>&)
{
return false;
}
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, false> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(C());
test_type v2(alloc_type(2));
v2.push_back(C());
std::swap(v1, v2);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
// swap back so assertions in uneq_allocator::deallocate don't fail
std::swap(v1, v2);
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<C, true> alloc_type;
typedef std::basic_string<C, traits, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(C());
test_type v2(alloc_type(2));
v2.push_back(C());
std::swap(v1, v2);
VERIFY(2 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
#else
int main()
{
// COW strings don't support C++11 allocators
}
#endif

View File

@ -119,6 +119,8 @@ namespace __gnu_test
tracker_allocator() = default;
tracker_allocator(const tracker_allocator&) = default;
tracker_allocator(tracker_allocator&&) = default;
tracker_allocator& operator=(const tracker_allocator&) = default;
tracker_allocator& operator=(tracker_allocator&&) = default;
// Perfect forwarding constructor.
template<typename... _Args>