From 5caff414f153f50aad00f1bc0d793776676e492b Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 11 Sep 2015 12:02:14 +0100 Subject: [PATCH] Implement N4258 noexcept for std::basic_string. PR libstdc++/58265 * doc/xml/manual/intro.xml: Document LWG 2063 and 2064 resolutions. * doc/html/manual/bugs.html: Regenerate. * include/bits/basic_string.h (basic_string): Implement N4258. Add correct exception-specifications and propagate allocators correctly. * include/bits/basic_string.tcc (basic_string::swap): Propagate allocators correctly. * include/debug/string (__gnu_debug::basic_string): Add correct exceptions-specifications and allcoator-extended constructors. * testsuite/21_strings/basic_string/allocator/char/copy.cc: New. * testsuite/21_strings/basic_string/allocator/char/copy_assign.cc: New. * testsuite/21_strings/basic_string/allocator/char/minimal.cc: New. * testsuite/21_strings/basic_string/allocator/char/move.cc: New. * testsuite/21_strings/basic_string/allocator/char/move_assign.cc: New. * testsuite/21_strings/basic_string/allocator/char/noexcept.cc: New. * testsuite/21_strings/basic_string/allocator/char/swap.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/move.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc: New. * testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc: New. * testsuite/util/testsuite_allocator.h (tracker_allocator): Define defaulted assignment operators. From-SVN: r227681 --- libstdc++-v3/ChangeLog | 30 ++++ libstdc++-v3/doc/html/manual/bugs.html | 6 + libstdc++-v3/doc/xml/manual/intro.xml | 12 ++ libstdc++-v3/include/bits/basic_string.h | 101 +++++++++-- libstdc++-v3/include/bits/basic_string.tcc | 10 +- libstdc++-v3/include/debug/string | 50 ++++-- .../basic_string/allocator/char/copy.cc | 97 +++++++++++ .../allocator/char/copy_assign.cc | 114 +++++++++++++ .../basic_string/allocator/char/minimal.cc | 49 ++++++ .../basic_string/allocator/char/move.cc | 66 ++++++++ .../allocator/char/move_assign.cc | 160 ++++++++++++++++++ .../basic_string/allocator/char/noexcept.cc | 61 +++++++ .../basic_string/allocator/char/swap.cc | 89 ++++++++++ .../basic_string/allocator/wchar_t/copy.cc | 97 +++++++++++ .../allocator/wchar_t/copy_assign.cc | 114 +++++++++++++ .../basic_string/allocator/wchar_t/minimal.cc | 49 ++++++ .../basic_string/allocator/wchar_t/move.cc | 66 ++++++++ .../allocator/wchar_t/move_assign.cc | 160 ++++++++++++++++++ .../allocator/wchar_t/noexcept.cc | 61 +++++++ .../basic_string/allocator/wchar_t/swap.cc | 89 ++++++++++ .../testsuite/util/testsuite_allocator.h | 2 + 21 files changed, 1450 insertions(+), 33 deletions(-) create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/noexcept.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/swap.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/noexcept.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/swap.cc 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 + 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 @@

2059: C++0x ambiguity problem with map::erase

Add additional overloads. +

2063: + Contradictory requirements for string move assignment +

Respect propagation trait for move assignment. +

2064: + More noexcept issues in basic_string +

Add noexcept to the comparison operators.

2067: packaged_task should have deleted copy c'tor with const parameter

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. Add additional overloads. + 2063: + Contradictory requirements for string move assignment + + Respect propagation trait for move assignment. + + + 2064: + More noexcept issues in basic_string + + Add noexcept to the comparison operators. + + 2067: packaged_task should have deleted copy c'tor with const parameter 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 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::_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 _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 _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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include +#include + +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::SimpleAllocator; + +template class std::basic_string>; + +void test01() +{ +#if _GLIBCXX_USE_CXX11_ABI + typedef SimpleAllocator alloc_type; + typedef std::allocator_traits traits_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef uneq_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + typedef std::allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +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&, + const propagating_allocator&) +{ + return true; +} + +bool +operator!=(const propagating_allocator&, + const propagating_allocator&) +{ + return false; +} + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include +#include + +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::SimpleAllocator; + +template class std::basic_string>; + +void test01() +{ +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) + typedef SimpleAllocator alloc_type; + typedef std::allocator_traits traits_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef uneq_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +using __gnu_test::propagating_allocator; + +void test01() +{ + typedef std::allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = char; +const C c = 'a'; +using traits = std::char_traits; + +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&, + const propagating_allocator&) +{ + return true; +} + +bool +operator!=(const propagating_allocator&, + const propagating_allocator&) +{ + return false; +} + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::basic_string 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 alloc_type; + typedef std::basic_string 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 -- 2.30.2