diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-31 20:49:40 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-31 20:49:40 +0000 |
commit | 081db185ef94b45c72106e3725fe64de56b402d2 (patch) | |
tree | b2e6ecad35b86d5807204670bcf8e10569378ee0 /libstdc++-v3/include/bits | |
parent | 978e3209f5105a855fff642a0c5487713bab8a23 (diff) | |
download | gcc-081db185ef94b45c72106e3725fe64de56b402d2.tar.gz |
Make std::vector<bool> 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<bool>): Use allocator_traits and _M_end_addr. Add allocator
extended constructors.
* include/bits/vector.tcc (vector<bool>): 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216988 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/bits')
-rw-r--r-- | libstdc++-v3/include/bits/stl_bvector.h | 153 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/vector.tcc | 34 |
2 files changed, 134 insertions, 53 deletions
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<typename _Alloc> 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<typename _Alloc> class vector<bool, _Alloc> : 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<typename> friend struct hash; @@ -573,7 +590,7 @@ template<typename _Alloc> : _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<typename _Alloc> : _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<typename _Alloc> 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<bool> __l, const allocator_type& __a = allocator_type()) : _Base(__a) @@ -633,6 +678,21 @@ template<typename _Alloc> { 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<typename _Alloc> #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<typename _Alloc> const size_type __isize = __gnu_cxx::__numeric_traits<difference_type>::__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<typename _Alloc> 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<typename _Alloc> 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<typename _Base::_Bit_alloc_type>:: - _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<typename _Alloc> #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<typename _Alloc> 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<typename _Alloc> 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<typename _Alloc> { _M_initialize(static_cast<size_type>(__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<typename _InputIterator> @@ -1069,14 +1150,14 @@ template<typename _Alloc> 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<bool, _Alloc>:: _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<bool>::_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<bool>::_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<bool, _Alloc>:: _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<bool>::_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; } } |