summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-11 11:02:14 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-11 11:02:14 +0000
commitb7aaabf0829d9d3633e7e7a821885173aa0849c0 (patch)
tree7f874e1b19838f08d31b01a85708c48602ae8eb8 /libstdc++-v3
parentc5dc0aa226609b20f70539d8eeb733e9ccdbc399 (diff)
downloadgcc-b7aaabf0829d9d3633e7e7a821885173aa0849c0.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227681 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog30
-rw-r--r--libstdc++-v3/doc/html/manual/bugs.html6
-rw-r--r--libstdc++-v3/doc/xml/manual/intro.xml12
-rw-r--r--libstdc++-v3/include/bits/basic_string.h101
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc10
-rw-r--r--libstdc++-v3/include/debug/string50
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc97
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc114
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc49
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc66
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc160
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc61
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc89
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc97
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc114
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc49
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc66
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc160
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc61
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc89
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h2
21 files changed, 1450 insertions, 33 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c4505fd05f0..3bd33ba504c 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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.
diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html
index 1ea5fffab6c..65ffc01a45b 100644
--- a/libstdc++-v3/doc/html/manual/bugs.html
+++ b/libstdc++-v3/doc/html/manual/bugs.html
@@ -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.
diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml
index 1cc183e2dc3..2aa9ba7a896 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -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>
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 3226617fec8..e6e7bb525ba 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -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); }
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index b9da93bf174..56af86471e5 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -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))
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index 72ae88e5495..d1f4a565aa2 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -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);
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc
new file mode 100644
index 00000000000..d02e9b93eca
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
new file mode 100644
index 00000000000..94e07961168
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc
new file mode 100644
index 00000000000..4bfd4cabe42
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc
new file mode 100644
index 00000000000..113df8fe9e5
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
new file mode 100644
index 00000000000..153ffd2810d
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc
new file mode 100644
index 00000000000..8733ea186cf
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc
new file mode 100644
index 00000000000..21003eb392d
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc
new file mode 100644
index 00000000000..c95e2eff599
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
new file mode 100644
index 00000000000..f69dff74eff
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc
new file mode 100644
index 00000000000..bfba87cc76b
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc
new file mode 100644
index 00000000000..88927a63124
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc
new file mode 100644
index 00000000000..45283a71c70
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc
new file mode 100644
index 00000000000..5fb3c1bd8a5
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc
new file mode 100644
index 00000000000..5490f9e7d03
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc
@@ -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
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index ebe7de0981e..2fa6a963037 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -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>