I've had a request to backport the allocator propagation support for std::__cxx11::string to the gcc-5-branch. That was done for 6cc-6 by this patch: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00784.html
The patch also fixed the fact that moving strings was not noexcept. Does anyone see any problem with doing that backport to complete the std::__cxx11::string implementation in gcc-5? I've already done it locally and confirmed all the tests pass, of course. The patch for the branch is attached.
commit d4691e319e31386c218304a59e80a1d5ad3cee1e Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri Sep 11 11:02:14 2015 +0000 Implement N4258 noexcept for std::basic_string. Backport from mainline 2015-10-02 Jonathan Wakely <jwak...@redhat.com> * testsuite/21_strings/basic_string/allocator/char/minimal.cc: Guard explicit instantiation with check for new ABI. * testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc: Likewise. Use wchar_t as char_type. Backport from mainline 2015-09-11 Jonathan Wakely <jwak...@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. diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index 8dccb02..02963ee 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -363,6 +363,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 2169905..1deb413 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -840,6 +840,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 9ef5be9..4020dcb 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -387,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); } @@ -396,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()); } /** @@ -509,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()); } @@ -548,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. @@ -585,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; } @@ -1107,6 +1182,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 @@ -4903,13 +4979,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())); } @@ -4949,6 +5026,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); } /** @@ -4986,6 +5064,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; } /** @@ -5023,6 +5102,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; } /** @@ -5060,6 +5140,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; } /** @@ -5097,6 +5178,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; } /** @@ -5134,6 +5216,9 @@ _GLIBCXX_END_NAMESPACE_CXX11 inline void swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, basic_string<_CharT, _Traits, _Alloc>& __rhs) +#if __cplusplus >= 201103L + noexcept(noexcept(__lhs.swap(__rhs))) +#endif { __lhs.swap(__rhs); } diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index b9da93b..56af864 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 3793a35..6e07e9f 100644 --- a/libstdc++-v3/include/debug/string +++ b/libstdc++-v3/include/debug/string @@ -36,18 +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, false>, - 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, false> _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: @@ -71,9 +72,15 @@ namespace __gnu_debug using _Base::npos; + basic_string() +#if __cplusplus >= 201103L + noexcept(std::is_nothrow_default_constructible<_Base>::value) +#endif + : _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 @@ -90,7 +97,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 @@ -277,7 +296,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. @@ -406,6 +425,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(); @@ -701,6 +721,9 @@ namespace __gnu_debug void swap(basic_string& __x) +#if _GLIBCXX_USE_CXX11_ABI + _GLIBCXX_NOEXCEPT +#endif { _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 0000000..d02e9b9 --- /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 0000000..94e0796 --- /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 0000000..d8dbb00 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/minimal.cc @@ -0,0 +1,51 @@ +// 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> + +#if _GLIBCXX_USE_CXX11_ABI +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() +{ + 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); +} +#else +void test01() { } +#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 0000000..113df8f --- /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 0000000..153ffd2 --- /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 0000000..8733ea1 --- /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 0000000..21003eb --- /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 0000000..c95e2ef --- /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 0000000..f69dff7 --- /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 0000000..b97a58a --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/minimal.cc @@ -0,0 +1,51 @@ +// 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> + +#if _GLIBCXX_USE_CXX11_ABI && defined(_GLIBCXX_USE_WCHAR_T) +using C = wchar_t; +const C c = L'a'; +using traits = std::char_traits<C>; + +using __gnu_test::SimpleAllocator; + +template class std::basic_string<C, traits, SimpleAllocator<C>>; + +void test01() +{ + 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); +} +#else +void test01() { } +#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 0000000..88927a6 --- /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 0000000..45283a7 --- /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 0000000..5fb3c1b --- /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 0000000..5490f9e --- /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 642cef4..f94dd70 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>