From ccd615e3fdf2d2b80577d27e884884e9f758e8ea Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 31 Oct 2014 20:49:40 +0000 Subject: [PATCH] Make std::vector meet C++11 allocator requirements. * include/bits/stl_bvector.h (_Bvector_base): Use allocator_traits. (_Bvector_base::_Bvector_impl): Use allocator's pointer type. (_Bvector_base::_M_end_addr()): Convert to raw pointer. (vector): Use allocator_traits and _M_end_addr. Add allocator extended constructors. * include/bits/vector.tcc (vector): Use allocator_traits and _M_end_addr. * testsuite/23_containers/vector/bool/allocator/copy.cc: New. * testsuite/23_containers/vector/bool/allocator/minimal.cc: New. * testsuite/23_containers/vector/bool/allocator/noexcept.cc: New. * testsuite/23_containers/vector/bool/allocator/copy_assign.cc: New. * testsuite/23_containers/vector/bool/allocator/move.cc: New. * testsuite/23_containers/vector/bool/allocator/swap.cc: New. * testsuite/23_containers/vector/bool/allocator/ext_ptr.cc: New. * testsuite/23_containers/vector/bool/allocator/move_assign.cc: New. From-SVN: r216988 --- libstdc++-v3/ChangeLog | 18 +++ libstdc++-v3/include/bits/stl_bvector.h | 153 +++++++++++++----- libstdc++-v3/include/bits/vector.tcc | 34 ++-- .../vector/bool/allocator/copy.cc | 70 ++++++++ .../vector/bool/allocator/copy_assign.cc | 61 +++++++ .../vector/bool/allocator/ext_ptr.cc | 44 +++++ .../vector/bool/allocator/minimal.cc | 38 +++++ .../vector/bool/allocator/move.cc | 59 +++++++ .../vector/bool/allocator/move_assign.cc | 80 +++++++++ .../vector/bool/allocator/noexcept.cc | 66 ++++++++ .../vector/bool/allocator/swap.cc | 80 +++++++++ 11 files changed, 650 insertions(+), 53 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy_assign.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/ext_ptr.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/minimal.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move_assign.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/noexcept.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/swap.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4e01b1042ae..d24f3a3e9a5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,21 @@ +2014-10-31 Jonathan Wakely + + * include/bits/stl_bvector.h (_Bvector_base): Use allocator_traits. + (_Bvector_base::_Bvector_impl): Use allocator's pointer type. + (_Bvector_base::_M_end_addr()): Convert to raw pointer. + (vector): Use allocator_traits and _M_end_addr. Add allocator + extended constructors. + * include/bits/vector.tcc (vector): Use allocator_traits and + _M_end_addr. + * testsuite/23_containers/vector/bool/allocator/copy.cc: New. + * testsuite/23_containers/vector/bool/allocator/minimal.cc: New. + * testsuite/23_containers/vector/bool/allocator/noexcept.cc: New. + * testsuite/23_containers/vector/bool/allocator/copy_assign.cc: New. + * testsuite/23_containers/vector/bool/allocator/move.cc: New. + * testsuite/23_containers/vector/bool/allocator/swap.cc: New. + * testsuite/23_containers/vector/bool/allocator/ext_ptr.cc: New. + * testsuite/23_containers/vector/bool/allocator/move_assign.cc: New. + 2014-10-30 David Edelsohn * configure.host (aix5+): New stanza. diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 996eb1a8d73..c93b96c864f 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -410,30 +410,41 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template struct _Bvector_base { - typedef typename _Alloc::template rebind<_Bit_type>::other - _Bit_alloc_type; - + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template + rebind<_Bit_type>::other _Bit_alloc_type; + typedef typename __gnu_cxx::__alloc_traits<_Bit_alloc_type> + _Bit_alloc_traits; + typedef typename _Bit_alloc_traits::pointer _Bit_pointer; + struct _Bvector_impl : public _Bit_alloc_type { _Bit_iterator _M_start; _Bit_iterator _M_finish; - _Bit_type* _M_end_of_storage; + _Bit_pointer _M_end_of_storage; _Bvector_impl() - : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0) + : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage() { } _Bvector_impl(const _Bit_alloc_type& __a) - : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) + : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage() { } #if __cplusplus >= 201103L _Bvector_impl(_Bit_alloc_type&& __a) : _Bit_alloc_type(std::move(__a)), _M_start(), _M_finish(), - _M_end_of_storage(0) + _M_end_of_storage() { } #endif + + _Bit_type* + _M_end_addr() const _GLIBCXX_NOEXCEPT + { + if (_M_end_of_storage) + return std::__addressof(_M_end_of_storage[-1]) + 1; + return 0; + } }; public: @@ -466,7 +477,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; __x._M_impl._M_start = _Bit_iterator(); __x._M_impl._M_finish = _Bit_iterator(); - __x._M_impl._M_end_of_storage = 0; + __x._M_impl._M_end_of_storage = nullptr; } #endif @@ -476,16 +487,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER protected: _Bvector_impl _M_impl; - _Bit_type* + _Bit_pointer _M_allocate(size_t __n) - { return _M_impl.allocate(_S_nword(__n)); } + { return _Bit_alloc_traits::allocate(_M_impl, _S_nword(__n)); } void _M_deallocate() { if (_M_impl._M_start._M_p) - _M_impl.deallocate(_M_impl._M_start._M_p, - _M_impl._M_end_of_storage - _M_impl._M_start._M_p); + { + const size_t __n = _M_impl._M_end_addr() - _M_impl._M_start._M_p; + _Bit_alloc_traits::deallocate(_M_impl, + _M_impl._M_end_of_storage - __n, + __n); + } } static size_t @@ -526,6 +541,8 @@ template class vector : protected _Bvector_base<_Alloc> { typedef _Bvector_base<_Alloc> _Base; + typedef typename _Base::_Bit_pointer _Bit_pointer; + typedef typename _Base::_Bit_alloc_traits _Bit_alloc_traits; #if __cplusplus >= 201103L template friend struct hash; @@ -573,7 +590,7 @@ template : _Base(__a) { _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(), __value ? ~0 : 0); } #else @@ -583,13 +600,13 @@ template : _Base(__a) { _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(), __value ? ~0 : 0); } #endif vector(const vector& __x) - : _Base(__x._M_get_Bit_allocator()) + : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator())) { _M_initialize(__x.size()); _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); @@ -599,6 +616,34 @@ template vector(vector&& __x) noexcept : _Base(std::move(__x)) { } + vector(vector&& __x, const allocator_type& __a) + noexcept(_Bit_alloc_traits::_S_always_equal()) + : _Base(__a) + { + if (__x.get_allocator() == __a) + { + this->_M_impl._M_start = __x._M_impl._M_start; + this->_M_impl._M_finish = __x._M_impl._M_finish; + this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; + __x._M_impl._M_start = _Bit_iterator(); + __x._M_impl._M_finish = _Bit_iterator(); + __x._M_impl._M_end_of_storage = nullptr; + } + else + { + _M_initialize(__x.size()); + _M_copy_aligned(__x.begin(), __x.end(), begin()); + __x.clear(); + } + } + + vector(const vector& __x, const allocator_type& __a) + : _Base(__a) + { + _M_initialize(__x.size()); + _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); + } + vector(initializer_list __l, const allocator_type& __a = allocator_type()) : _Base(__a) @@ -633,6 +678,21 @@ template { if (&__x == this) return *this; +#if __cplusplus >= 201103L + if (_Bit_alloc_traits::_S_propagate_on_copy_assign()) + { + if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator()) + { + this->_M_deallocate(); + std::__alloc_on_copy(_M_get_Bit_allocator(), + __x._M_get_Bit_allocator()); + _M_initialize(__x.size()); + } + else + std::__alloc_on_copy(_M_get_Bit_allocator(), + __x._M_get_Bit_allocator()); + } +#endif if (__x.size() > capacity()) { this->_M_deallocate(); @@ -645,12 +705,32 @@ template #if __cplusplus >= 201103L vector& - operator=(vector&& __x) + operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move()) { - // NB: DR 1204. - // NB: DR 675. - this->clear(); - this->swap(__x); + if (_Bit_alloc_traits::_S_propagate_on_move_assign() + || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator()) + { + this->_M_deallocate(); + this->_M_impl._M_start = __x._M_impl._M_start; + this->_M_impl._M_finish = __x._M_impl._M_finish; + this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; + __x._M_impl._M_start = _Bit_iterator(); + __x._M_impl._M_finish = _Bit_iterator(); + __x._M_impl._M_end_of_storage = nullptr; + std::__alloc_on_move(_M_get_Bit_allocator(), + __x._M_get_Bit_allocator()); + } + else + { + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), + begin()); + __x.clear(); + } return *this; } @@ -752,14 +832,15 @@ template const size_type __isize = __gnu_cxx::__numeric_traits::__max - int(_S_word_bit) + 1; - const size_type __asize = _M_get_Bit_allocator().max_size(); + const size_type __asize + = _Bit_alloc_traits::max_size(_M_get_Bit_allocator()); return (__asize <= __isize / int(_S_word_bit) ? __asize * int(_S_word_bit) : __isize); } size_type capacity() const _GLIBCXX_NOEXCEPT - { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) + { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0) - begin()); } bool @@ -836,7 +917,7 @@ template void push_back(bool __x) { - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()) *this->_M_impl._M_finish++ = __x; else _M_insert_aux(end(), __x); @@ -844,16 +925,16 @@ template void swap(vector& __x) +#if __cplusplus >= 201103L + noexcept(_Bit_alloc_traits::_S_nothrow_swap()) +#endif { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); - - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 431. Swapping containers with unequal allocators. - std::__alloc_swap:: - _S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); + _Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(), + __x._M_get_Bit_allocator()); } // [23.2.5]/1, third-to-last entry in synopsis listing @@ -873,7 +954,7 @@ template #endif { const difference_type __n = __position - begin(); - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr() && __position == end()) *this->_M_impl._M_finish++ = __x; else @@ -962,8 +1043,8 @@ template void flip() _GLIBCXX_NOEXCEPT { - for (_Bit_type * __p = this->_M_impl._M_start._M_p; - __p != this->_M_impl._M_end_of_storage; ++__p) + _Bit_type * const __end = this->_M_impl._M_end_addr(); + for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != __end; ++__p) *__p = ~*__p; } @@ -997,9 +1078,9 @@ template void _M_initialize(size_type __n) { - _Bit_type* __q = this->_M_allocate(__n); + _Bit_pointer __q = this->_M_allocate(__n); this->_M_impl._M_end_of_storage = __q + _S_nword(__n); - this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_start = iterator(std::__addressof(*__q), 0); this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); } @@ -1021,7 +1102,7 @@ template { _M_initialize(static_cast(__n)); std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + this->_M_impl._M_end_addr(), __x ? ~0 : 0); } template @@ -1069,14 +1150,14 @@ template if (__n > size()) { std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + this->_M_impl._M_end_addr(), __x ? ~0 : 0); insert(end(), __n - size(), __x); } else { _M_erase_at_end(begin() + __n); std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + this->_M_impl._M_end_addr(), __x ? ~0 : 0); } } diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 19784c0ac2e..229fa6d6822 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -699,11 +699,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector:: _M_reallocate(size_type __n) { - _Bit_type* __q = this->_M_allocate(__n); - this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), - iterator(__q, 0)); + _Bit_pointer __q = this->_M_allocate(__n); + iterator __start(std::__addressof(*__q), 0); + this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), __start); this->_M_deallocate(); - this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_start = __start; this->_M_impl._M_end_of_storage = __q + _S_nword(__n); } @@ -725,15 +725,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { const size_type __len = _M_check_len(__n, "vector::_M_fill_insert"); - _Bit_type * __q = this->_M_allocate(__len); - iterator __i = _M_copy_aligned(begin(), __position, - iterator(__q, 0)); + _Bit_pointer __q = this->_M_allocate(__len); + iterator __start(std::__addressof(*__q), 0); + iterator __i = _M_copy_aligned(begin(), __position, __start); std::fill(__i, __i + difference_type(__n), __x); this->_M_impl._M_finish = std::copy(__position, end(), __i + difference_type(__n)); this->_M_deallocate(); this->_M_impl._M_end_of_storage = __q + _S_nword(__len); - this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_start = __start; } } @@ -759,14 +759,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { const size_type __len = _M_check_len(__n, "vector::_M_insert_range"); - _Bit_type * __q = this->_M_allocate(__len); - iterator __i = _M_copy_aligned(begin(), __position, - iterator(__q, 0)); + _Bit_pointer __q = this->_M_allocate(__len); + iterator __start(std::__addressof(*__q), 0); + iterator __i = _M_copy_aligned(begin(), __position, __start); __i = std::copy(__first, __last, __i); this->_M_impl._M_finish = std::copy(__position, end(), __i); this->_M_deallocate(); this->_M_impl._M_end_of_storage = __q + _S_nword(__len); - this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_start = __start; } } } @@ -776,7 +776,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector:: _M_insert_aux(iterator __position, bool __x) { - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()) { std::copy_backward(__position, this->_M_impl._M_finish, this->_M_impl._M_finish + 1); @@ -787,14 +787,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { const size_type __len = _M_check_len(size_type(1), "vector::_M_insert_aux"); - _Bit_type * __q = this->_M_allocate(__len); - iterator __i = _M_copy_aligned(begin(), __position, - iterator(__q, 0)); + _Bit_pointer __q = this->_M_allocate(__len); + iterator __start(std::__addressof(*__q), 0); + iterator __i = _M_copy_aligned(begin(), __position, __start); *__i++ = __x; this->_M_impl._M_finish = std::copy(__position, end(), __i); this->_M_deallocate(); this->_M_impl._M_end_of_storage = __q + _S_nword(__len); - this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_start = __start; } } diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy.cc new file mode 100644 index 00000000000..7bd0b9898cd --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy.cc @@ -0,0 +1,70 @@ +// Copyright (C) 2014 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 + +using T = bool; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(v1); + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(0 == v2.get_allocator().get_personality()); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(v1); + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(1 == v2.get_allocator().get_personality()); +} + +void test03() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(v1, alloc_type(2)); + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(2 == v2.get_allocator().get_personality()); +} + +int main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy_assign.cc new file mode 100644 index 00000000000..eac6b431c9f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/copy_assign.cc @@ -0,0 +1,61 @@ +// Copyright (C) 2014 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 + +using T = bool; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(alloc_type(2)); + v2.push_back(T()); + v2 = v1; + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(2 == v2.get_allocator().get_personality()); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(alloc_type(2)); + v2.push_back(T()); + v2 = v1; + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(1 == v2.get_allocator().get_personality()); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/ext_ptr.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/ext_ptr.cc new file mode 100644 index 00000000000..94087be95bf --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/ext_ptr.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2014 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 T = bool; + +using __gnu_test::CustomPointerAlloc; + +template class std::vector>; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef CustomPointerAlloc alloc_type; + typedef std::vector test_type; + test_type v; + v.push_back(T()); + VERIFY( ++v.begin() == v.end() ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/minimal.cc new file mode 100644 index 00000000000..56d88b08142 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/minimal.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2014 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" } +// { dg-do compile } + +#include +#include +#include + +using T = bool; + +using __gnu_test::SimpleAllocator; + +template class std::vector>; + +void test01() +{ + typedef SimpleAllocator alloc_type; + typedef std::allocator_traits traits_type; + typedef std::vector test_type; + test_type v(alloc_type{}); + v.push_back(T()); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move.cc new file mode 100644 index 00000000000..c6afcd318da --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move.cc @@ -0,0 +1,59 @@ +// Copyright (C) 2014 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 + +using T = bool; + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef uneq_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1 = { T() }; + auto it = v1.begin(); + test_type v2(std::move(v1)); + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(1 == v2.get_allocator().get_personality()); + VERIFY( it == v2.begin() ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + typedef uneq_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1 = { T() }; + 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; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move_assign.cc new file mode 100644 index 00000000000..da95498f9a2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/move_assign.cc @@ -0,0 +1,80 @@ +// Copyright (C) 2014 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 + +using T = bool; + +using __gnu_test::propagating_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(alloc_type(2)); + v2.push_back(T()); + v2 = std::move(v1); + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(2 == v2.get_allocator().get_personality()); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + auto it = v1.begin(); + test_type v2(alloc_type(2)); + v2.push_back(T()); + v2 = std::move(v1); + VERIFY( it == v2.begin() ); + VERIFY(0 == v1.get_allocator().get_personality()); + VERIFY(1 == v2.get_allocator().get_personality()); +} + +void test03() +{ + bool test __attribute__((unused)) = true; + typedef propagating_allocator alloc_type; + typedef std::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + auto it = v1.begin(); + test_type v2(alloc_type(1)); + v2.push_back(T()); + v2 = std::move(v1); + VERIFY( it == v2.begin() ); + VERIFY(1 == v1.get_allocator().get_personality()); + VERIFY(1 == v2.get_allocator().get_personality()); +} + +int main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/noexcept.cc new file mode 100644 index 00000000000..e86e6b205b8 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/noexcept.cc @@ -0,0 +1,66 @@ +// Copyright (C) 2014 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 + +using T = bool; + +namespace __gnu_test +{ + template + inline void + swap(propagating_allocator& l, propagating_allocator& r) + noexcept(false) + { } +} + +using __gnu_test::propagating_allocator; + +void test01() +{ + typedef std::allocator alloc_type; + typedef std::vector 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::vector 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::vector 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 can throw" ); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/swap.cc new file mode 100644 index 00000000000..cedb24f5ab2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/swap.cc @@ -0,0 +1,80 @@ +// Copyright (C) 2014 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 + +using T = bool; + +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::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(alloc_type(2)); + v2.push_back(T()); + 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::vector test_type; + test_type v1(alloc_type(1)); + v1.push_back(T()); + test_type v2(alloc_type(2)); + v2.push_back(T()); + std::swap(v1, v2); + VERIFY(2 == v1.get_allocator().get_personality()); + VERIFY(1 == v2.get_allocator().get_personality()); +} + +int main() +{ + test01(); + test02(); + return 0; +} -- 2.30.2