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.
</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.
<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>
* @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); }
* @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); }
* @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()); }
/**
{ _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());
}
*/
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.
// 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;
}
*/
basic_string&
assign(basic_string&& __str)
+ noexcept(_Alloc_traits::_S_nothrow_move())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2063. Contradictory requirements for string move assignment
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())); }
inline bool
operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return !(__lhs == __rhs); }
/**
inline bool
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) < 0; }
/**
inline bool
operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) > 0; }
/**
inline bool
operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) <= 0; }
/**
inline bool
operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
+ _GLIBCXX_NOEXCEPT
{ return __lhs.compare(__rhs) >= 0; }
/**
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); }
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())
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)
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))
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:
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
: _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
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.
#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();
void
swap(basic_string& __x)
+ _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
{
_Safe::_M_swap(__x);
_Base::swap(__x);
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
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>