From 7d594224c2375ae5b067b727a46c42b6ddc86de2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Fri, 16 Jun 2017 05:28:06 +0000 Subject: [PATCH] stl_bvector.h (__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)): Change signature. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 2017-06-16 François Dumont * include/bits/stl_bvector.h (__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)): Change signature. (std::fill(_Bit_iterator, _Bit_iterator, bool)): Adapt. (_Bvector_impl_data): New. (_Bvector_impl): Inherits from latter. (_Bvector_impl(_Bit_alloc_type&&)): Delete. (_Bvector_impl(_Bvector_impl&&)): New, default. (_Bvector_base()): Default. (_Bvector_base(_Bvector_base&&)): Default. (_Bvector_base::_M_move_data(_Bvector_base&&)): New. (vector(vector&&, const allocator_type&)): Use latter. (vector::operator=(vector&&)): Likewise. (vector::vector()): Default. (vector::vector(vector&&)): Default. (vector::assign(_InputIterator, _InputIterator)): Use _M_assign_aux. (vector::assign(initializer_list)): Likewise. (vector::_M_initialize_value(bool)): New. (vector(size_type, const bool&, const allocator_type&)): Use latter. (vector::_M_initialize_dispatch(_Integer, _Integer, __true_type)): Likewise. (vector::_M_fill_assign(size_t, bool)): Likewise. From-SVN: r249235 --- libstdc++-v3/ChangeLog | 27 + libstdc++-v3/include/bits/stl_bvector.h | 1264 +++++++++-------- .../vector/bool/allocator/default_init.cc | 67 + 3 files changed, 741 insertions(+), 617 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ceb4811ff35..26b3075143d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,30 @@ +2017-06-16 François Dumont + + * include/bits/stl_bvector.h + (__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)): + Change signature. + (std::fill(_Bit_iterator, _Bit_iterator, bool)): Adapt. + (_Bvector_impl_data): New. + (_Bvector_impl): Inherits from latter. + (_Bvector_impl(_Bit_alloc_type&&)): Delete. + (_Bvector_impl(_Bvector_impl&&)): New, default. + (_Bvector_base()): Default. + (_Bvector_base(_Bvector_base&&)): Default. + (_Bvector_base::_M_move_data(_Bvector_base&&)): New. + (vector(vector&&, const allocator_type&)): Use latter. + (vector::operator=(vector&&)): Likewise. + (vector::vector()): Default. + (vector::vector(vector&&)): Default. + (vector::assign(_InputIterator, _InputIterator)): Use + _M_assign_aux. + (vector::assign(initializer_list)): Likewise. + (vector::_M_initialize_value(bool)): New. + (vector(size_type, const bool&, const allocator_type&)): Use + latter. + (vector::_M_initialize_dispatch(_Integer, _Integer, __true_type)): + Likewise. + (vector::_M_fill_assign(size_t, bool)): Likewise. + 2017-06-15 François Dumont * src/c++98/tree.cc [!_GLIBCXX_INLINE_VERSION] diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 78195c1295d..c9433d4f80f 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -184,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER operator<(const _Bit_iterator_base& __i) const { return _M_p < __i._M_p - || (_M_p == __i._M_p && _M_offset < __i._M_offset); + || (_M_p == __i._M_p && _M_offset < __i._M_offset); } bool @@ -388,10 +388,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return __x + __n; } inline void - __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x) + __fill_bvector(_Bit_type * __v, + unsigned int __first, unsigned int __last, bool __x) { - for (; __first != __last; ++__first) - *__first = __x; + const _Bit_type __fmask = ~0ul << __first; + const _Bit_type __lmask = ~0ul >> (_S_word_bit - __last); + const _Bit_type __mask = __fmask & __lmask; + + if (__x) + *__v |= __mask; + else + *__v &= ~__mask; } inline void @@ -399,12 +406,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (__first._M_p != __last._M_p) { - std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0); - __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x); - __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x); + _Bit_type *__first_p = __first._M_p; + if (__first._M_offset != 0) + __fill_bvector(__first_p++, __first._M_offset, _S_word_bit, __x); + + __builtin_memset(__first_p, __x ? ~0 : 0, + (__last._M_p - __first_p) * sizeof(_Bit_type)); + + if (__last._M_offset != 0) + __fill_bvector(__last._M_p, 0, __last._M_offset, __x); } else - __fill_bvector(__first, __last, __x); + __fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x); } template @@ -416,33 +429,62 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Bit_alloc_traits; typedef typename _Bit_alloc_traits::pointer _Bit_pointer; - struct _Bvector_impl - : public _Bit_alloc_type + struct _Bvector_impl_data { _Bit_iterator _M_start; _Bit_iterator _M_finish; _Bit_pointer _M_end_of_storage; - _Bvector_impl() - : _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() + _Bvector_impl_data() _GLIBCXX_NOEXCEPT + : _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() - { } + _Bvector_impl_data(_Bvector_impl_data&& __x) noexcept + : _M_start(__x._M_start), _M_finish(__x._M_finish) + , _M_end_of_storage(__x._M_end_of_storage) + { __x._M_reset(); } + + void + _M_move_data(_Bvector_impl_data&& __x) noexcept + { + this->_M_start = __x._M_start; + this->_M_finish = __x._M_finish; + this->_M_end_of_storage = __x._M_end_of_storage; + __x._M_reset(); + } +#endif + + void + _M_reset() _GLIBCXX_NOEXCEPT + { + _M_start = _M_finish = _Bit_iterator(); + _M_end_of_storage = _Bit_pointer(); + } + }; + + struct _Bvector_impl + : public _Bit_alloc_type, public _Bvector_impl_data + { + public: + _Bvector_impl() + _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type()) ) + : _Bit_alloc_type() + { } + + _Bvector_impl(const _Bit_alloc_type& __a) _GLIBCXX_NOEXCEPT + : _Bit_alloc_type(__a) + { } + +#if __cplusplus >= 201103L + _Bvector_impl(_Bvector_impl&&) = default; #endif _Bit_type* _M_end_addr() const _GLIBCXX_NOEXCEPT { - if (_M_end_of_storage) - return std::__addressof(_M_end_of_storage[-1]) + 1; + if (this->_M_end_of_storage) + return std::__addressof(this->_M_end_of_storage[-1]) + 1; return 0; } }; @@ -452,33 +494,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Bit_alloc_type& _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT - { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } + { return this->_M_impl; } const _Bit_alloc_type& _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT - { return *static_cast(&this->_M_impl); } + { return this->_M_impl; } allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Bit_allocator()); } - _Bvector_base() - : _M_impl() { } +#if __cplusplus >= 201103L + _Bvector_base() = default; +#else + _Bvector_base() { } +#endif _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } #if __cplusplus >= 201103L - _Bvector_base(_Bvector_base&& __x) noexcept - : _M_impl(std::move(__x._M_get_Bit_allocator())) - { - 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; - } + _Bvector_base(_Bvector_base&&) = default; #endif ~_Bvector_base() @@ -500,11 +536,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Bit_alloc_traits::deallocate(_M_impl, _M_impl._M_end_of_storage - __n, __n); - _M_impl._M_start = _M_impl._M_finish = _Bit_iterator(); - _M_impl._M_end_of_storage = _Bit_pointer(); + _M_impl._M_reset(); } } +#if __cplusplus >= 201103L + void + _M_move_data(_Bvector_base&& __x) noexcept + { _M_impl._M_move_data(std::move(__x._M_impl)); } +#endif + static size_t _S_nword(size_t __n) { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); } @@ -539,738 +580,727 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * memory and size allocation. Subscripting ( @c [] ) access is * also provided as with C-style arrays. */ -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; + 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; + template friend struct hash; #endif - public: - typedef bool value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Bit_reference reference; - typedef bool const_reference; - typedef _Bit_reference* pointer; - typedef const bool* const_pointer; - typedef _Bit_iterator iterator; - typedef _Bit_const_iterator const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef _Alloc allocator_type; - - allocator_type get_allocator() const - { return _Base::get_allocator(); } - - protected: - using _Base::_M_allocate; - using _Base::_M_deallocate; - using _Base::_S_nword; - using _Base::_M_get_Bit_allocator; - - public: - vector() -#if __cplusplus >= 201103L - noexcept(is_nothrow_default_constructible::value) -#endif - : _Base() { } + public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef _Alloc allocator_type; - explicit - vector(const allocator_type& __a) - : _Base(__a) { } + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + protected: + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_S_nword; + using _Base::_M_get_Bit_allocator; + public: #if __cplusplus >= 201103L - explicit - vector(size_type __n, const allocator_type& __a = allocator_type()) - : vector(__n, false, __a) - { } - - vector(size_type __n, const bool& __value, - const allocator_type& __a = allocator_type()) - : _Base(__a) - { - _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(), - __value ? ~0 : 0); - } + vector() = default; #else - explicit - vector(size_type __n, const bool& __value = bool(), - const allocator_type& __a = allocator_type()) - : _Base(__a) - { - _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(), - __value ? ~0 : 0); - } + vector() { } #endif - vector(const vector& __x) - : _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); - } + explicit + vector(const allocator_type& __a) + : _Base(__a) { } #if __cplusplus >= 201103L - 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); - } + explicit + vector(size_type __n, const allocator_type& __a = allocator_type()) + : vector(__n, false, __a) + { } - vector(initializer_list __l, - const allocator_type& __a = allocator_type()) - : _Base(__a) - { - _M_initialize_range(__l.begin(), __l.end(), - random_access_iterator_tag()); - } + vector(size_type __n, const bool& __value, + const allocator_type& __a = allocator_type()) +#else + explicit + vector(size_type __n, const bool& __value = bool(), + const allocator_type& __a = allocator_type()) #endif + : _Base(__a) + { + _M_initialize(__n); + _M_initialize_value(__value); + } + + vector(const vector& __x) + : _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); + } #if __cplusplus >= 201103L - template> - vector(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) + vector(vector&&) = default; + + vector(vector&& __x, const allocator_type& __a) + noexcept(_Bit_alloc_traits::_S_always_equal()) : _Base(__a) - { _M_initialize_dispatch(__first, __last, __false_type()); } -#else - template - vector(_InputIterator __first, _InputIterator __last, + { + if (__x.get_allocator() == __a) + this->_M_move_data(std::move(__x)); + 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) { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - _M_initialize_dispatch(__first, __last, _Integral()); + _M_initialize_range(__l.begin(), __l.end(), + random_access_iterator_tag()); } #endif - ~vector() _GLIBCXX_NOEXCEPT { } - - vector& - operator=(const vector& __x) - { - if (&__x == this) - return *this; #if __cplusplus >= 201103L - if (_Bit_alloc_traits::_S_propagate_on_copy_assign()) + template> + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_initialize_dispatch(__first, __last, __false_type()); } +#else + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) { - if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator()) - { - this->_M_deallocate(); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } +#endif + + ~vector() _GLIBCXX_NOEXCEPT { } + + vector& + operator=(const vector& __x) + { + 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()); - _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(); - _M_initialize(__x.size()); - } - this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), - begin()); - return *this; - } + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), + begin()); + return *this; + } #if __cplusplus >= 201103L - vector& - operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move()) - { - 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; - } + vector& + operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move()) + { + if (_Bit_alloc_traits::_S_propagate_on_move_assign() + || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator()) + { + this->_M_deallocate(); + this->_M_move_data(std::move(__x)); + 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; + } - vector& - operator=(initializer_list __l) - { - this->assign (__l.begin(), __l.end()); - return *this; - } + vector& + operator=(initializer_list __l) + { + this->assign (__l.begin(), __l.end()); + return *this; + } #endif - // assign(), a generalized assignment member function. Two - // versions: one that takes a count, and one that takes a range. - // The range version is a member template, so we dispatch on whether - // or not the type is an integer. - void - assign(size_type __n, const bool& __x) - { _M_fill_assign(__n, __x); } + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + void + assign(size_type __n, const bool& __x) + { _M_fill_assign(__n, __x); } #if __cplusplus >= 201103L - template> - void - assign(_InputIterator __first, _InputIterator __last) - { _M_assign_dispatch(__first, __last, __false_type()); } + template> + void + assign(_InputIterator __first, _InputIterator __last) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } #else - template - void - assign(_InputIterator __first, _InputIterator __last) - { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - _M_assign_dispatch(__first, __last, _Integral()); - } + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } #endif #if __cplusplus >= 201103L - void - assign(initializer_list __l) - { this->assign(__l.begin(), __l.end()); } + void + assign(initializer_list __l) + { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif - iterator - begin() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + iterator + begin() _GLIBCXX_NOEXCEPT + { return this->_M_impl._M_start; } - const_iterator - begin() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + const_iterator + begin() const _GLIBCXX_NOEXCEPT + { return this->_M_impl._M_start; } - iterator - end() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + iterator + end() _GLIBCXX_NOEXCEPT + { return this->_M_impl._M_finish; } - const_iterator - end() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + const_iterator + end() const _GLIBCXX_NOEXCEPT + { return this->_M_impl._M_finish; } - reverse_iterator - rbegin() _GLIBCXX_NOEXCEPT - { return reverse_iterator(end()); } + reverse_iterator + rbegin() _GLIBCXX_NOEXCEPT + { return reverse_iterator(end()); } - const_reverse_iterator - rbegin() const _GLIBCXX_NOEXCEPT - { return const_reverse_iterator(end()); } + const_reverse_iterator + rbegin() const _GLIBCXX_NOEXCEPT + { return const_reverse_iterator(end()); } - reverse_iterator - rend() _GLIBCXX_NOEXCEPT - { return reverse_iterator(begin()); } + reverse_iterator + rend() _GLIBCXX_NOEXCEPT + { return reverse_iterator(begin()); } - const_reverse_iterator - rend() const _GLIBCXX_NOEXCEPT - { return const_reverse_iterator(begin()); } + const_reverse_iterator + rend() const _GLIBCXX_NOEXCEPT + { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L - const_iterator - cbegin() const noexcept - { return this->_M_impl._M_start; } + const_iterator + cbegin() const noexcept + { return this->_M_impl._M_start; } - const_iterator - cend() const noexcept - { return this->_M_impl._M_finish; } + const_iterator + cend() const noexcept + { return this->_M_impl._M_finish; } - const_reverse_iterator - crbegin() const noexcept - { return const_reverse_iterator(end()); } + const_reverse_iterator + crbegin() const noexcept + { return const_reverse_iterator(end()); } - const_reverse_iterator - crend() const noexcept - { return const_reverse_iterator(begin()); } + const_reverse_iterator + crend() const noexcept + { return const_reverse_iterator(begin()); } #endif - size_type - size() const _GLIBCXX_NOEXCEPT - { return size_type(end() - begin()); } + size_type + size() const _GLIBCXX_NOEXCEPT + { return size_type(end() - begin()); } - size_type - max_size() const _GLIBCXX_NOEXCEPT - { - const size_type __isize = - __gnu_cxx::__numeric_traits::__max - - int(_S_word_bit) + 1; - 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 + max_size() const _GLIBCXX_NOEXCEPT + { + const size_type __isize = + __gnu_cxx::__numeric_traits::__max + - int(_S_word_bit) + 1; + 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_addr(), 0) - - begin()); } + size_type + capacity() const _GLIBCXX_NOEXCEPT + { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0) + - begin()); } - bool - empty() const _GLIBCXX_NOEXCEPT - { return begin() == end(); } + bool + empty() const _GLIBCXX_NOEXCEPT + { return begin() == end(); } - reference - operator[](size_type __n) - { - return *iterator(this->_M_impl._M_start._M_p - + __n / int(_S_word_bit), __n % int(_S_word_bit)); - } + reference + operator[](size_type __n) + { + return *iterator(this->_M_impl._M_start._M_p + + __n / int(_S_word_bit), __n % int(_S_word_bit)); + } - const_reference - operator[](size_type __n) const - { - return *const_iterator(this->_M_impl._M_start._M_p + const_reference + operator[](size_type __n) const + { + return *const_iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); - } + } - protected: - void - _M_range_check(size_type __n) const - { - if (__n >= this->size()) - __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " - "(which is %zu) >= this->size() " - "(which is %zu)"), - __n, this->size()); - } + protected: + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); + } - public: - reference - at(size_type __n) - { _M_range_check(__n); return (*this)[__n]; } + public: + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } - const_reference - at(size_type __n) const - { _M_range_check(__n); return (*this)[__n]; } + const_reference + at(size_type __n) const + { _M_range_check(__n); return (*this)[__n]; } - void - reserve(size_type __n) - { - if (__n > max_size()) - __throw_length_error(__N("vector::reserve")); - if (capacity() < __n) - _M_reallocate(__n); - } + void + reserve(size_type __n) + { + if (__n > max_size()) + __throw_length_error(__N("vector::reserve")); + if (capacity() < __n) + _M_reallocate(__n); + } - reference - front() - { return *begin(); } + reference + front() + { return *begin(); } - const_reference - front() const - { return *begin(); } + const_reference + front() const + { return *begin(); } - reference - back() - { return *(end() - 1); } + reference + back() + { return *(end() - 1); } + + const_reference + back() const + { return *(end() - 1); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 464. Suggestion for new member functions in standard containers. + // N.B. DR 464 says nothing about vector but we need something + // here due to the way we are implementing DR 464 in the debug-mode + // vector class. + void + data() _GLIBCXX_NOEXCEPT { } - const_reference - back() const - { return *(end() - 1); } - - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // DR 464. Suggestion for new member functions in standard containers. - // N.B. DR 464 says nothing about vector but we need something - // here due to the way we are implementing DR 464 in the debug-mode - // vector class. - void - data() _GLIBCXX_NOEXCEPT { } + void + push_back(bool __x) + { + 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); + } - void - push_back(bool __x) - { - 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); - } + void + swap(vector& __x) _GLIBCXX_NOEXCEPT + { + 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); + _Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(), + __x._M_get_Bit_allocator()); + } - void - swap(vector& __x) _GLIBCXX_NOEXCEPT - { - 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); - _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 + static void + swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT + { + bool __tmp = __x; + __x = __y; + __y = __tmp; + } - // [23.2.5]/1, third-to-last entry in synopsis listing - static void - swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT - { - bool __tmp = __x; - __x = __y; - __y = __tmp; - } + iterator +#if __cplusplus >= 201103L + insert(const_iterator __position, const bool& __x = bool()) +#else + insert(iterator __position, const bool& __x = bool()) +#endif + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr() + && __position == end()) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(__position._M_const_cast(), __x); + return begin() + __n; + } - iterator #if __cplusplus >= 201103L - insert(const_iterator __position, const bool& __x = bool()) + template> + iterator + insert(const_iterator __position, + _InputIterator __first, _InputIterator __last) + { + difference_type __offset = __position - cbegin(); + _M_insert_dispatch(__position._M_const_cast(), + __first, __last, __false_type()); + return begin() + __offset; + } #else - insert(iterator __position, const bool& __x = bool()) + template + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } #endif - { - const difference_type __n = __position - begin(); - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr() - && __position == end()) - *this->_M_impl._M_finish++ = __x; - else - _M_insert_aux(__position._M_const_cast(), __x); - return begin() + __n; - } #if __cplusplus >= 201103L - template> iterator - insert(const_iterator __position, - _InputIterator __first, _InputIterator __last) + insert(const_iterator __position, size_type __n, const bool& __x) { difference_type __offset = __position - cbegin(); - _M_insert_dispatch(__position._M_const_cast(), - __first, __last, __false_type()); + _M_fill_insert(__position._M_const_cast(), __n, __x); return begin() + __offset; } #else - template void - insert(iterator __position, - _InputIterator __first, _InputIterator __last) - { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - _M_insert_dispatch(__position, __first, __last, _Integral()); - } -#endif - -#if __cplusplus >= 201103L - iterator - insert(const_iterator __position, size_type __n, const bool& __x) - { - difference_type __offset = __position - cbegin(); - _M_fill_insert(__position._M_const_cast(), __n, __x); - return begin() + __offset; - } -#else - void - insert(iterator __position, size_type __n, const bool& __x) - { _M_fill_insert(__position, __n, __x); } + insert(iterator __position, size_type __n, const bool& __x) + { _M_fill_insert(__position, __n, __x); } #endif #if __cplusplus >= 201103L - iterator - insert(const_iterator __p, initializer_list __l) - { return this->insert(__p, __l.begin(), __l.end()); } + iterator + insert(const_iterator __p, initializer_list __l) + { return this->insert(__p, __l.begin(), __l.end()); } #endif - void - pop_back() - { --this->_M_impl._M_finish; } + void + pop_back() + { --this->_M_impl._M_finish; } - iterator + iterator #if __cplusplus >= 201103L - erase(const_iterator __position) + erase(const_iterator __position) #else - erase(iterator __position) + erase(iterator __position) #endif - { return _M_erase(__position._M_const_cast()); } + { return _M_erase(__position._M_const_cast()); } - iterator + iterator #if __cplusplus >= 201103L - erase(const_iterator __first, const_iterator __last) + erase(const_iterator __first, const_iterator __last) #else - erase(iterator __first, iterator __last) + erase(iterator __first, iterator __last) #endif - { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); } + { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); } - void - resize(size_type __new_size, bool __x = bool()) - { - if (__new_size < size()) - _M_erase_at_end(begin() + difference_type(__new_size)); - else - insert(end(), __new_size - size(), __x); - } + void + resize(size_type __new_size, bool __x = bool()) + { + if (__new_size < size()) + _M_erase_at_end(begin() + difference_type(__new_size)); + else + insert(end(), __new_size - size(), __x); + } #if __cplusplus >= 201103L - void - shrink_to_fit() - { _M_shrink_to_fit(); } + void + shrink_to_fit() + { _M_shrink_to_fit(); } #endif - void - flip() _GLIBCXX_NOEXCEPT - { - _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; - } + void + flip() _GLIBCXX_NOEXCEPT + { + _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; + } - void - clear() _GLIBCXX_NOEXCEPT - { _M_erase_at_end(begin()); } + void + clear() _GLIBCXX_NOEXCEPT + { _M_erase_at_end(begin()); } #if __cplusplus >= 201103L - template + template #if __cplusplus > 201402L - reference + reference #else - void + void #endif - emplace_back(_Args&&... __args) - { - push_back(bool(__args...)); + emplace_back(_Args&&... __args) + { + push_back(bool(__args...)); #if __cplusplus > 201402L - return back(); -#endif - } - - template - iterator - emplace(const_iterator __pos, _Args&&... __args) - { return insert(__pos, bool(__args...)); } + return back(); #endif - - protected: - // Precondition: __first._M_offset == 0 && __result._M_offset == 0. - iterator - _M_copy_aligned(const_iterator __first, const_iterator __last, - iterator __result) - { - _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); - return std::copy(const_iterator(__last._M_p, 0), __last, - iterator(__q, 0)); - } - - void - _M_initialize(size_type __n) - { - if (__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(std::__addressof(*__q), 0); - } - else - { - this->_M_impl._M_end_of_storage = _Bit_pointer(); - this->_M_impl._M_start = iterator(0, 0); } - this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); - } - void - _M_reallocate(size_type __n); - -#if __cplusplus >= 201103L - bool - _M_shrink_to_fit(); + template + iterator + emplace(const_iterator __pos, _Args&&... __args) + { return insert(__pos, bool(__args...)); } #endif - // Check whether it's an integral type. If so, it's not an iterator. - - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 438. Ambiguity in the "do the right thing" clause - template - void - _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + protected: + // Precondition: __first._M_offset == 0 && __result._M_offset == 0. + iterator + _M_copy_aligned(const_iterator __first, const_iterator __last, + iterator __result) { - _M_initialize(static_cast(__n)); - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_addr(), __x ? ~0 : 0); + _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); + return std::copy(const_iterator(__last._M_p, 0), __last, + iterator(__q, 0)); } - template - void - _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, - __false_type) - { _M_initialize_range(__first, __last, - std::__iterator_category(__first)); } - - template void - _M_initialize_range(_InputIterator __first, _InputIterator __last, - std::input_iterator_tag) + _M_initialize(size_type __n) { - for (; __first != __last; ++__first) - push_back(*__first); + if (__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(std::__addressof(*__q), 0); + } + else + { + this->_M_impl._M_end_of_storage = _Bit_pointer(); + this->_M_impl._M_start = iterator(0, 0); + } + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + } - template void - _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, - std::forward_iterator_tag) + _M_initialize_value(bool __x) { - const size_type __n = std::distance(__first, __last); - _M_initialize(__n); - std::copy(__first, __last, this->_M_impl._M_start); + __builtin_memset(this->_M_impl._M_start._M_p, __x ? ~0 : 0, + (this->_M_impl._M_end_addr() - this->_M_impl._M_start._M_p) + * sizeof(_Bit_type)); } - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 438. Ambiguity in the "do the right thing" clause - template void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) - { _M_fill_assign(__n, __val); } + _M_reallocate(size_type __n); - template - void - _M_assign_dispatch(_InputIterator __first, _InputIterator __last, - __false_type) - { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } +#if __cplusplus >= 201103L + bool + _M_shrink_to_fit(); +#endif - void - _M_fill_assign(size_t __n, bool __x) - { - if (__n > size()) + // Check whether it's an integral type. If so, it's not an iterator. + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 438. Ambiguity in the "do the right thing" clause + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_addr(), __x ? ~0 : 0); - insert(end(), __n - size(), __x); + _M_initialize(static_cast(__n)); + _M_initialize_value(__x); } - else + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } + + template + void + _M_initialize_range(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) { - _M_erase_at_end(begin() + __n); - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_addr(), __x ? ~0 : 0); + for (; __first != __last; ++__first) + push_back(*__first); } - } - template - void - _M_assign_aux(_InputIterator __first, _InputIterator __last, - std::input_iterator_tag) - { - iterator __cur = begin(); - for (; __first != __last && __cur != end(); ++__cur, ++__first) - *__cur = *__first; - if (__first == __last) - _M_erase_at_end(__cur); - else - insert(end(), __first, __last); - } - - template + template + void + _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); + _M_initialize(__n); + std::copy(__first, __last, this->_M_impl._M_start); + } + +#if __cplusplus < 201103L + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 438. Ambiguity in the "do the right thing" clause + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign(__n, __val); } + + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } +#endif + void - _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, - std::forward_iterator_tag) + _M_fill_assign(size_t __n, bool __x) { - const size_type __len = std::distance(__first, __last); - if (__len < size()) - _M_erase_at_end(std::copy(__first, __last, begin())); + if (__n > size()) + { + _M_initialize_value(__x); + insert(end(), __n - size(), __x); + } else { - _ForwardIterator __mid = __first; - std::advance(__mid, size()); - std::copy(__first, __mid, begin()); - insert(end(), __mid, __last); + _M_erase_at_end(begin() + __n); + _M_initialize_value(__x); } } - // Check whether it's an integral type. If so, it's not an iterator. + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) + { + iterator __cur = begin(); + for (; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + _M_erase_at_end(__cur); + else + insert(end(), __first, __last); + } + + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len < size()) + _M_erase_at_end(std::copy(__first, __last, begin())); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 438. Ambiguity in the "do the right thing" clause - template - void - _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, - __true_type) - { _M_fill_insert(__pos, __n, __x); } + // Check whether it's an integral type. If so, it's not an iterator. - template - void - _M_insert_dispatch(iterator __pos, - _InputIterator __first, _InputIterator __last, - __false_type) - { _M_insert_range(__pos, __first, __last, - std::__iterator_category(__first)); } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 438. Ambiguity in the "do the right thing" clause + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { _M_fill_insert(__pos, __n, __x); } - void - _M_fill_insert(iterator __position, size_type __n, bool __x); + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { _M_insert_range(__pos, __first, __last, + std::__iterator_category(__first)); } - template void - _M_insert_range(iterator __pos, _InputIterator __first, - _InputIterator __last, std::input_iterator_tag) - { - for (; __first != __last; ++__first) - { - __pos = insert(__pos, *__first); - ++__pos; - } - } + _M_fill_insert(iterator __position, size_type __n, bool __x); - template - void - _M_insert_range(iterator __position, _ForwardIterator __first, - _ForwardIterator __last, std::forward_iterator_tag); + template + void + _M_insert_range(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } - void - _M_insert_aux(iterator __position, bool __x); + template + void + _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag); - size_type - _M_check_len(size_type __n, const char* __s) const - { - if (max_size() - size() < __n) - __throw_length_error(__N(__s)); + void + _M_insert_aux(iterator __position, bool __x); - const size_type __len = size() + std::max(size(), __n); - return (__len < size() || __len > max_size()) ? max_size() : __len; - } + size_type + _M_check_len(size_type __n, const char* __s) const + { + if (max_size() - size() < __n) + __throw_length_error(__N(__s)); - void - _M_erase_at_end(iterator __pos) - { this->_M_impl._M_finish = __pos; } + const size_type __len = size() + std::max(size(), __n); + return (__len < size() || __len > max_size()) ? max_size() : __len; + } - iterator - _M_erase(iterator __pos); + void + _M_erase_at_end(iterator __pos) + { this->_M_impl._M_finish = __pos; } - iterator - _M_erase(iterator __first, iterator __last); + iterator + _M_erase(iterator __pos); + + iterator + _M_erase(iterator __first, iterator __last); }; _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc new file mode 100644 index 00000000000..9ee469716f1 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc @@ -0,0 +1,67 @@ +// Copyright (C) 2017 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 run { target c++11 } } +// { dg-options "-O0" } +// { dg-xfail-run-if "PR c++/65816" { *-*-* } } + +#include +#include +#include + +#include + +using T = bool; + +using __gnu_test::default_init_allocator; + +void test01() +{ + typedef default_init_allocator alloc_type; + typedef std::vector test_type; + + __gnu_cxx::__aligned_buffer buf; + __builtin_memset(buf._M_addr(), ~0, sizeof(test_type)); + + test_type *tmp = ::new(buf._M_addr()) test_type; + + VERIFY( tmp->get_allocator().state == 0 ); + + tmp->~test_type(); +} + +void test02() +{ + typedef default_init_allocator alloc_type; + typedef std::vector test_type; + + __gnu_cxx::__aligned_buffer buf; + __builtin_memset(buf._M_addr(), ~0, sizeof(test_type)); + + test_type *tmp = ::new(buf._M_addr()) test_type(); + + VERIFY( tmp->get_allocator().state == 0 ); + + tmp->~test_type(); +} + +int main() +{ + test01(); + test02(); + return 0; +} -- 2.30.2