From e7385d7ed67d696c66c7f4a356f92ca312a61b20 Mon Sep 17 00:00:00 2001 From: paolo Date: Fri, 6 Jan 2006 11:23:02 +0000 Subject: [PATCH] 2006-01-06 Paolo Carlini * include/bits/stl_bvector.h (vector::erase(iterator, iterator)): Just use _M_erase_at_end. 2006-01-06 Paolo Carlini * include/bits/stl_bvector.h (class vector): Move all the helpers under protected access mode, consistently with the primary vector template. (vector::_M_erase_at_end): Add. (erase(iterator, iterator), clear, resize, _M_fill_assign, _M_assign_aux): Use it. * testsuite/23_containers/vector/bool/modifiers/erase/1.cc: New. 2006-01-06 Paolo Carlini Implement Option 3 of DR 431 for vector. * include/bits/stl_bvector.h (class _Bvector_base): Change to a struct, consistently with the primary vector template. (class vector): Adjust to protected inheritance, tidy typedefs. (_Bvector_base<>::_M_get_Bit_allocator): Add. (vector::vector(const vector&)): Use it. (_Bvector_base<>::get_allocator): Tidy. (vector::swap): Use __alloc_swap. * testsuite/23_containers/vector/bool/modifiers/swap/1.cc: New. * testsuite/23_containers/vector/bool/modifiers/swap/2.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109415 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 31 +- libstdc++-v3/include/bits/stl_bvector.h | 646 +++++++++++---------- .../23_containers/vector/bool/modifiers/erase/1.cc | 137 +++++ .../23_containers/vector/bool/modifiers/swap/1.cc | 146 +++++ .../23_containers/vector/bool/modifiers/swap/2.cc | 175 ++++++ 5 files changed, 818 insertions(+), 317 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/erase/1.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/1.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/2.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ffb3edb..963e6e4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,32 @@ +2006-01-06 Paolo Carlini + + * include/bits/stl_bvector.h (vector::erase(iterator, + iterator)): Just use _M_erase_at_end. + +2006-01-06 Paolo Carlini + + * include/bits/stl_bvector.h (class vector): Move all the + helpers under protected access mode, consistently with the primary + vector template. + (vector::_M_erase_at_end): Add. + (erase(iterator, iterator), clear, resize, _M_fill_assign, + _M_assign_aux): Use it. + * testsuite/23_containers/vector/bool/modifiers/erase/1.cc: New. + +2006-01-06 Paolo Carlini + + Implement Option 3 of DR 431 for vector. + * include/bits/stl_bvector.h (class _Bvector_base): Change to + a struct, consistently with the primary vector template. + (class vector): Adjust to protected inheritance, tidy + typedefs. + (_Bvector_base<>::_M_get_Bit_allocator): Add. + (vector::vector(const vector&)): Use it. + (_Bvector_base<>::get_allocator): Tidy. + (vector::swap): Use __alloc_swap. + * testsuite/23_containers/vector/bool/modifiers/swap/1.cc: New. + * testsuite/23_containers/vector/bool/modifiers/swap/2.cc: New. + 2006-01-05 Paolo Carlini * testsuite/testsuite_hooks.h (test_tm(unsigned)): Change to @@ -32,7 +61,7 @@ * testsuite/22_locale/time_get/get_monthname/wchar_t/1.cc: Likewise. * testsuite/22_locale/time_get/get_monthname/wchar_t/2.cc: Likewise. * testsuite/22_locale/time_get/get_monthname/char/1.cc: Likewise. - * testsuite/22_locale/time_get/get_monthname/char/2.cc: Likewise. + * testsuite/22_locale/time_get/get_monthname/char/2.cc: Likewise. * testsuite/22_locale/time_get/get_weekday/wchar_t/1.cc: Likewise. * testsuite/22_locale/time_get/get_weekday/wchar_t/2.cc: Likewise. * testsuite/22_locale/time_get/get_weekday/wchar_t/3.cc: Likewise. diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 0779ea6..ab65710 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -1,6 +1,7 @@ // vector specialization -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// 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 @@ -354,12 +355,13 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) { return __x + __n; } template - class _Bvector_base + struct _Bvector_base { typedef typename _Alloc::template rebind<_Bit_type>::other _Bit_alloc_type; - struct _Bvector_impl : public _Bit_alloc_type + struct _Bvector_impl + : public _Bit_alloc_type { _Bit_iterator _M_start; _Bit_iterator _M_finish; @@ -372,9 +374,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) public: typedef _Alloc allocator_type; + _Bit_alloc_type& + _M_get_Bit_allocator() + { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } + + const _Bit_alloc_type& + _M_get_Bit_allocator() const + { return *static_cast(&this->_M_impl); } + allocator_type get_allocator() const - { return *static_cast(&this->_M_impl); } + { return allocator_type(_M_get_Bit_allocator()); } _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } @@ -424,139 +434,96 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) * also provided as with C-style arrays. */ template - class vector : public _Bvector_base<_Alloc> + class vector : protected _Bvector_base<_Alloc> { - 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 _Bvector_base<_Alloc> _Base; - typedef typename _Bvector_base<_Alloc>::allocator_type allocator_type; + 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 _Bvector_base<_Alloc>::get_allocator(); } + { return _Base::get_allocator(); } protected: - using _Bvector_base<_Alloc>::_M_allocate; - using _Bvector_base<_Alloc>::_M_deallocate; + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_get_Bit_allocator; - protected: - void - _M_initialize(size_type __n) + public: + explicit + vector(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + explicit + vector(size_type __n, const bool& __value = bool(), + const allocator_type& __a = allocator_type()) + : _Base(__a) { - _Bit_type* __q = this->_M_allocate(__n); - this->_M_impl._M_end_of_storage = (__q - + ((__n + int(_S_word_bit) - 1) - / int(_S_word_bit))); - this->_M_impl._M_start = iterator(__q, 0); - this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + __value ? ~0 : 0); } - void - _M_insert_aux(iterator __position, bool __x) + vector(const vector& __x) + : _Base(__x._M_get_Bit_allocator()) { - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) - { - std::copy_backward(__position, this->_M_impl._M_finish, - this->_M_impl._M_finish + 1); - *__position = __x; - ++this->_M_impl._M_finish; - } - else - { - const size_type __len = size() ? 2 * size() - : static_cast(_S_word_bit); - _Bit_type * __q = this->_M_allocate(__len); - iterator __i = std::copy(begin(), __position, iterator(__q, 0)); - *__i++ = __x; - this->_M_impl._M_finish = std::copy(__position, end(), __i); - this->_M_deallocate(); - this->_M_impl._M_end_of_storage = (__q + ((__len - + int(_S_word_bit) - 1) - / int(_S_word_bit))); - this->_M_impl._M_start = iterator(__q, 0); - } + _M_initialize(__x.size()); + std::copy(__x.begin(), __x.end(), this->_M_impl._M_start); } template - void - _M_initialize_range(_InputIterator __first, _InputIterator __last, - std::input_iterator_tag) + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) { - this->_M_impl._M_start = iterator(); - this->_M_impl._M_finish = iterator(); - this->_M_impl._M_end_of_storage = 0; - for (; __first != __last; ++__first) - push_back(*__first); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); } - 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); - } + ~vector() { } - template - void - _M_insert_range(iterator __pos, _InputIterator __first, - _InputIterator __last, std::input_iterator_tag) - { - for (; __first != __last; ++__first) - { - __pos = insert(__pos, *__first); - ++__pos; - } - } + vector& + operator=(const vector& __x) + { + if (&__x == this) + return *this; + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + std::copy(__x.begin(), __x.end(), begin()); + this->_M_impl._M_finish = begin() + difference_type(__x.size()); + return *this; + } - template + // 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); } + + template void - _M_insert_range(iterator __position, _ForwardIterator __first, - _ForwardIterator __last, std::forward_iterator_tag) + assign(_InputIterator __first, _InputIterator __last) { - if (__first != __last) - { - size_type __n = std::distance(__first, __last); - if (capacity() - size() >= __n) - { - std::copy_backward(__position, end(), - this->_M_impl._M_finish - + difference_type(__n)); - std::copy(__first, __last, __position); - this->_M_impl._M_finish += difference_type(__n); - } - else - { - const size_type __len = size() + std::max(size(), __n); - _Bit_type * __q = this->_M_allocate(__len); - iterator __i = std::copy(begin(), __position, - iterator(__q, 0)); - __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 - + ((__len - + int(_S_word_bit) - 1) - / int(_S_word_bit))); - this->_M_impl._M_start = iterator(__q, 0); - } - } + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } - public: iterator begin() { return this->_M_impl._M_start; } @@ -601,6 +568,7 @@ template capacity() const { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) - begin()); } + bool empty() const { return begin() == end(); } @@ -613,6 +581,7 @@ template operator[](size_type __n) const { return *(begin() + difference_type(__n)); } + protected: void _M_range_check(size_type __n) const { @@ -620,6 +589,7 @@ template __throw_out_of_range(__N("vector::_M_range_check")); } + public: reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } @@ -628,110 +598,196 @@ template at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } - explicit - vector(const allocator_type& __a = allocator_type()) - : _Bvector_base<_Alloc>(__a) { } - - vector(size_type __n, bool __value, - const allocator_type& __a = allocator_type()) - : _Bvector_base<_Alloc>(__a) + void + reserve(size_type __n) { - _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, - __value ? ~0 : 0); + if (__n > this->max_size()) + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = std::copy(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1) + / int(_S_word_bit)); + } } - explicit - vector(size_type __n) - : _Bvector_base<_Alloc>(allocator_type()) + reference + front() + { return *begin(); } + + const_reference + front() const + { return *begin(); } + + 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() { } + + void + push_back(bool __x) { - _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, 0); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(end(), __x); } - vector(const vector& __x) - : _Bvector_base<_Alloc>(__x.get_allocator()) + void + swap(vector& __x) { - _M_initialize(__x.size()); - std::copy(__x.begin(), __x.end(), this->_M_impl._M_start); + 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()); } - // Check whether it's an integral type. If so, it's not an iterator. - template - void - _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) - { - _M_initialize(__n); - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, __x ? ~0 : 0); - } + // [23.2.5]/1, third-to-last entry in synopsis listing + static void + swap(reference __x, reference __y) + { + bool __tmp = __x; + __x = __y; + __y = __tmp; + } - template - void - _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, - __false_type) - { _M_initialize_range(__first, __last, - std::__iterator_category(__first)); } + iterator + insert(iterator __position, const bool& __x = bool()) + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + && __position == end()) + *this->_M_impl._M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } template - vector(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Bvector_base<_Alloc>(__a) + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; - _M_initialize_dispatch(__first, __last, _Integral()); + _M_insert_dispatch(__position, __first, __last, _Integral()); } - ~vector() { } + void + insert(iterator __position, size_type __n, const bool& __x) + { _M_fill_insert(__position, __n, __x); } - vector& - operator=(const vector& __x) - { - if (&__x == this) - return *this; - if (__x.size() > capacity()) - { - this->_M_deallocate(); - _M_initialize(__x.size()); - } - std::copy(__x.begin(), __x.end(), begin()); - this->_M_impl._M_finish = begin() + difference_type(__x.size()); - return *this; + void + pop_back() + { --this->_M_impl._M_finish; } + + iterator + erase(iterator __position) + { + if (__position + 1 != end()) + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + return __position; } - // 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. + iterator + erase(iterator __first, iterator __last) + { + _M_erase_at_end(std::copy(__last, end(), __first)); + return __first; + } void - _M_fill_assign(size_t __n, bool __x) + resize(size_type __new_size, bool __x = bool()) { - if (__n > size()) - { - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, __x ? ~0 : 0); - insert(end(), __n - size(), __x); - } + if (__new_size < size()) + _M_erase_at_end(begin() + difference_type(__new_size)); else - { - erase(begin() + __n, end()); - std::fill(this->_M_impl._M_start._M_p, - this->_M_impl._M_end_of_storage, __x ? ~0 : 0); - } + insert(end(), __new_size - size(), __x); } void - assign(size_t __n, bool __x) - { _M_fill_assign(__n, __x); } + flip() + { + for (_Bit_type * __p = this->_M_impl._M_start._M_p; + __p != this->_M_impl._M_end_of_storage; ++__p) + *__p = ~*__p; + } + + void + clear() + { _M_erase_at_end(begin()); } + + + protected: + + void + _M_initialize(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = (__q + + ((__n + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); + } + + // Check whether it's an integral type. If so, it's not an iterator. + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize(__n); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } + + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } template void - assign(_InputIterator __first, _InputIterator __last) + _M_initialize_range(_InputIterator __first, _InputIterator __last, + std::input_iterator_tag) { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - _M_assign_dispatch(__first, __last, _Integral()); + this->_M_impl._M_start = iterator(); + this->_M_impl._M_finish = iterator(); + this->_M_impl._M_end_of_storage = 0; + for (; __first != __last; ++__first) + push_back(*__first); + } + + 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); } template @@ -745,6 +801,23 @@ template __false_type) { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } + void + _M_fill_assign(size_t __n, bool __x) + { + if (__n > size()) + { + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __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); + } + } + template void _M_assign_aux(_InputIterator __first, _InputIterator __last, @@ -754,7 +827,7 @@ template for (; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; if (__first == __last) - erase(__cur, end()); + _M_erase_at_end(__cur); else insert(end(), __first, __last); } @@ -766,7 +839,7 @@ template { const size_type __len = std::distance(__first, __last); if (__len < size()) - erase(std::copy(__first, __last, begin()), end()); + _M_erase_at_end(std::copy(__first, __last, begin())); else { _ForwardIterator __mid = __first; @@ -776,88 +849,7 @@ template } } - void - reserve(size_type __n) - { - if (__n > this->max_size()) - __throw_length_error(__N("vector::reserve")); - if (this->capacity() < __n) - { - _Bit_type* __q = this->_M_allocate(__n); - this->_M_impl._M_finish = std::copy(begin(), end(), - iterator(__q, 0)); - this->_M_deallocate(); - this->_M_impl._M_start = iterator(__q, 0); - this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1) - / int(_S_word_bit)); - } - } - - reference - front() - { return *begin(); } - - const_reference - front() const - { return *begin(); } - - 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() { } - - void - push_back(bool __x) - { - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) - *this->_M_impl._M_finish++ = __x; - else - _M_insert_aux(end(), __x); - } - - void - swap(vector& __x) - { - 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); - } - - // [23.2.5]/1, third-to-last entry in synopsis listing - static void - swap(reference __x, reference __y) - { - bool __tmp = __x; - __x = __y; - __y = __tmp; - } - - iterator - insert(iterator __position, bool __x = bool()) - { - const difference_type __n = __position - begin(); - if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage - && __position == end()) - *this->_M_impl._M_finish++ = __x; - else - _M_insert_aux(__position, __x); - return begin() + __n; - } - // Check whether it's an integral type. If so, it's not an iterator. - template void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, @@ -872,15 +864,6 @@ template { _M_insert_range(__pos, __first, __last, std::__iterator_category(__first)); } - template - void - insert(iterator __position, - _InputIterator __first, _InputIterator __last) - { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - _M_insert_dispatch(__position, __first, __last, _Integral()); - } - void _M_fill_insert(iterator __position, size_type __n, bool __x) { @@ -909,50 +892,81 @@ template } } - void - insert(iterator __position, size_type __n, bool __x) - { _M_fill_insert(__position, __n, __x); } - - void - pop_back() - { --this->_M_impl._M_finish; } - - iterator - erase(iterator __position) - { - if (__position + 1 != end()) - std::copy(__position + 1, end(), __position); - --this->_M_impl._M_finish; - return __position; - } + template + void + _M_insert_range(iterator __pos, _InputIterator __first, + _InputIterator __last, std::input_iterator_tag) + { + for (; __first != __last; ++__first) + { + __pos = insert(__pos, *__first); + ++__pos; + } + } - iterator - erase(iterator __first, iterator __last) - { - this->_M_impl._M_finish = std::copy(__last, end(), __first); - return __first; - } + template + void + _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, std::forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + + difference_type(__n)); + std::copy(__first, __last, __position); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, + iterator(__q, 0)); + __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 + + ((__len + + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + } + } + } void - resize(size_type __new_size, bool __x = bool()) + _M_insert_aux(iterator __position, bool __x) { - if (__new_size < size()) - erase(begin() + difference_type(__new_size), end()); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + { + std::copy_backward(__position, this->_M_impl._M_finish, + this->_M_impl._M_finish + 1); + *__position = __x; + ++this->_M_impl._M_finish; + } else - insert(end(), __new_size - size(), __x); - } - - void - flip() - { - for (_Bit_type * __p = this->_M_impl._M_start._M_p; - __p != this->_M_impl._M_end_of_storage; ++__p) - *__p = ~*__p; + { + const size_type __len = size() ? 2 * size() + : static_cast(_S_word_bit); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = (__q + ((__len + + int(_S_word_bit) - 1) + / int(_S_word_bit))); + this->_M_impl._M_start = iterator(__q, 0); + } } void - clear() - { erase(begin(), end()); } + _M_erase_at_end(iterator __pos) + { this->_M_impl._M_finish = __pos; } }; _GLIBCXX_END_NESTED_NAMESPACE diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/erase/1.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/erase/1.cc new file mode 100644 index 0000000..a6706a5 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/erase/1.cc @@ -0,0 +1,137 @@ +// 2005-12-23 Paolo Carlini + +// Copyright (C) 2005, 2006 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 23.2.5 vector modifiers + +#include +#include + +const bool A[] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; +const bool A1[] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; +const bool A2[] = {0, 0, 1, 0, 0, 1, 0, 1, 0, 1}; +const bool A3[] = {0, 0, 1, 0, 0, 1}; +const bool A4[] = {0, 0, 1}; +const bool A5[] = {0, 0}; + +const unsigned N = sizeof(A) / sizeof(bool); +const unsigned N1 = sizeof(A1) / sizeof(bool); +const unsigned N2 = sizeof(A2) / sizeof(bool); +const unsigned N3 = sizeof(A3) / sizeof(bool); +const unsigned N4 = sizeof(A4) / sizeof(bool); +const unsigned N5 = sizeof(A5) / sizeof(bool); + +void +test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::vector vec_type; + typedef vec_type::iterator iterator_type; + + vec_type v(A, A + N); + + iterator_type it1 = v.erase(v.begin() + 1); + VERIFY( it1 == v.begin() + 1 ); + VERIFY( v.size() == N1 ); + VERIFY( std::equal(v.begin(), v.end(), A1) ); + + iterator_type it2 = v.erase(v.begin() + 4, v.begin() + 9); + VERIFY( it2 == v.begin() + 4 ); + VERIFY( v.size() == N2 ); + VERIFY( std::equal(v.begin(), v.end(), A2) ); + + iterator_type it3 = v.erase(v.begin() + 6, v.end()); + VERIFY( it3 == v.begin() + 6 ); + VERIFY( v.size() == N3 ); + VERIFY( std::equal(v.begin(), v.end(), A3) ); + + iterator_type it4 = v.erase(v.begin(), v.begin() + 3); + VERIFY( it4 == v.begin() ); + VERIFY( v.size() == N4 ); + VERIFY( std::equal(v.begin(), v.end(), A4) ); + + iterator_type it5 = v.erase(v.begin() + 2); + VERIFY( it5 == v.begin() + 2 ); + VERIFY( v.size() == N5 ); + VERIFY( std::equal(v.begin(), v.end(), A5) ); + + iterator_type it6 = v.erase(v.begin(), v.end()); + VERIFY( it6 == v.begin() ); + VERIFY( v.empty() ); +} + +void +test02() +{ + bool test __attribute__((unused)) = true; + + typedef std::vector > vec_type; + typedef vec_type::iterator iterator_type; + + vec_type v, v1, v2, v3, v4, v5; + for (unsigned i = 0; i < N; ++i) + v.push_back(std::vector(1, A[i])); + for (unsigned i = 0; i < N1; ++i) + v1.push_back(std::vector(1, A1[i])); + for (unsigned i = 0; i < N2; ++i) + v2.push_back(std::vector(1, A2[i])); + for (unsigned i = 0; i < N3; ++i) + v3.push_back(std::vector(1, A3[i])); + for (unsigned i = 0; i < N4; ++i) + v4.push_back(std::vector(1, A4[i])); + for (unsigned i = 0; i < N5; ++i) + v5.push_back(std::vector(1, A5[i])); + + iterator_type it1 = v.erase(v.begin() + 1); + VERIFY( it1 == v.begin() + 1 ); + VERIFY( v.size() == N1 ); + VERIFY( std::equal(v.begin(), v.end(), v1.begin()) ); + + iterator_type it2 = v.erase(v.begin() + 4, v.begin() + 9); + VERIFY( it2 == v.begin() + 4 ); + VERIFY( v.size() == N2 ); + VERIFY( std::equal(v.begin(), v.end(), v2.begin()) ); + + iterator_type it3 = v.erase(v.begin() + 6, v.end()); + VERIFY( it3 == v.begin() + 6 ); + VERIFY( v.size() == N3 ); + VERIFY( std::equal(v.begin(), v.end(), v3.begin()) ); + + iterator_type it4 = v.erase(v.begin(), v.begin() + 3); + VERIFY( it4 == v.begin() ); + VERIFY( v.size() == N4 ); + VERIFY( std::equal(v.begin(), v.end(), v4.begin()) ); + + iterator_type it5 = v.erase(v.begin() + 2); + VERIFY( it5 == v.begin() + 2 ); + VERIFY( v.size() == N5 ); + VERIFY( std::equal(v.begin(), v.end(), v5.begin()) ); + + iterator_type it6 = v.erase(v.begin(), v.end()); + VERIFY( it6 == v.begin() ); + VERIFY( v.empty() ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/1.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/1.cc new file mode 100644 index 0000000..48f7640 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/1.cc @@ -0,0 +1,146 @@ +// 2005-12-23 Paolo Carlini + +// Copyright (C) 2005, 2006 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 23.2.5 vector::swap + +#include +#include +#include + +// uneq_allocator as a non-empty allocator. +void +test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + typedef __gnu_test::uneq_allocator my_alloc; + typedef vector my_vector; + + const char title01[] = "Rivers of sand"; + const char title02[] = "Concret PH"; + const char title03[] = "Sonatas and Interludes for Prepared Piano"; + const char title04[] = "never as tired as when i'm waking up"; + + const size_t N1 = sizeof(title01); + const size_t N2 = sizeof(title02); + const size_t N3 = sizeof(title03); + const size_t N4 = sizeof(title04); + + vector vec01_ref; + for (size_t i = 0; i < N1; ++i) + vec01_ref.push_back(bool(title01[i] > 96 ? 1 : 0)); + vector vec02_ref; + for (size_t i = 0; i < N2; ++i) + vec02_ref.push_back(bool(title02[i] > 96 ? 1 : 0)); + vector vec03_ref; + for (size_t i = 0; i < N3; ++i) + vec03_ref.push_back(bool(title03[i] > 96 ? 1 : 0)); + vector vec04_ref; + for (size_t i = 0; i < N4; ++i) + vec04_ref.push_back(bool(title04[i] > 96 ? 1 : 0)); + + my_vector::size_type size01, size02; + + my_alloc alloc01(1); + + my_vector vec01(alloc01); + size01 = vec01.size(); + my_vector vec02(alloc01); + size02 = vec02.size(); + + vec01.swap(vec02); + VERIFY( vec01.size() == size02 ); + VERIFY( vec01.empty() ); + VERIFY( vec02.size() == size01 ); + VERIFY( vec02.empty() ); + + my_vector vec03(alloc01); + size01 = vec03.size(); + my_vector vec04(vec02_ref.begin(), vec02_ref.end(), alloc01); + size02 = vec04.size(); + + vec03.swap(vec04); + VERIFY( vec03.size() == size02 ); + VERIFY( equal(vec03.begin(), vec03.end(), vec02_ref.begin()) ); + VERIFY( vec04.size() == size01 ); + VERIFY( vec04.empty() ); + + my_vector vec05(vec01_ref.begin(), vec01_ref.end(), alloc01); + size01 = vec05.size(); + my_vector vec06(vec02_ref.begin(), vec02_ref.end(), alloc01); + size02 = vec06.size(); + + vec05.swap(vec06); + VERIFY( vec05.size() == size02 ); + VERIFY( equal(vec05.begin(), vec05.end(), vec02_ref.begin()) ); + VERIFY( vec06.size() == size01 ); + VERIFY( equal(vec06.begin(), vec06.end(), vec01_ref.begin()) ); + + my_vector vec07(vec01_ref.begin(), vec01_ref.end(), alloc01); + size01 = vec07.size(); + my_vector vec08(vec03_ref.begin(), vec03_ref.end(), alloc01); + size02 = vec08.size(); + + vec07.swap(vec08); + VERIFY( vec07.size() == size02 ); + VERIFY( equal(vec07.begin(), vec07.end(), vec03_ref.begin()) ); + VERIFY( vec08.size() == size01 ); + VERIFY( equal(vec08.begin(), vec08.end(), vec01_ref.begin()) ); + + my_vector vec09(vec03_ref.begin(), vec03_ref.end(), alloc01); + size01 = vec09.size(); + my_vector vec10(vec04_ref.begin(), vec04_ref.end(), alloc01); + size02 = vec10.size(); + + vec09.swap(vec10); + VERIFY( vec09.size() == size02 ); + VERIFY( equal(vec09.begin(), vec09.end(), vec04_ref.begin()) ); + VERIFY( vec10.size() == size01 ); + VERIFY( equal(vec10.begin(), vec10.end(), vec03_ref.begin()) ); + + my_vector vec11(vec04_ref.begin(), vec04_ref.end(), alloc01); + size01 = vec11.size(); + my_vector vec12(vec01_ref.begin(), vec01_ref.end(), alloc01); + size02 = vec12.size(); + + vec11.swap(vec12); + VERIFY( vec11.size() == size02 ); + VERIFY( equal(vec11.begin(), vec11.end(), vec01_ref.begin()) ); + VERIFY( vec12.size() == size01 ); + VERIFY( equal(vec12.begin(), vec12.end(), vec04_ref.begin()) ); + + my_vector vec13(vec03_ref.begin(), vec03_ref.end(), alloc01); + size01 = vec13.size(); + my_vector vec14(vec03_ref.begin(), vec03_ref.end(), alloc01); + size02 = vec14.size(); + + vec13.swap(vec14); + VERIFY( vec13.size() == size02 ); + VERIFY( equal(vec13.begin(), vec13.end(), vec03_ref.begin()) ); + VERIFY( vec14.size() == size01 ); + VERIFY( equal(vec14.begin(), vec14.end(), vec03_ref.begin()) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/2.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/2.cc new file mode 100644 index 0000000..606254b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/swap/2.cc @@ -0,0 +1,175 @@ +// 2005-12-23 Paolo Carlini + +// Copyright (C) 2005, 2006 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 23.2.5 vector::swap + +#include +#include +#include + +// uneq_allocator, two different personalities. +void +test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + typedef __gnu_test::uneq_allocator my_alloc; + typedef vector my_vector; + + const char title01[] = "Rivers of sand"; + const char title02[] = "Concret PH"; + const char title03[] = "Sonatas and Interludes for Prepared Piano"; + const char title04[] = "never as tired as when i'm waking up"; + + const size_t N1 = sizeof(title01); + const size_t N2 = sizeof(title02); + const size_t N3 = sizeof(title03); + const size_t N4 = sizeof(title04); + + vector vec01_ref; + for (size_t i = 0; i < N1; ++i) + vec01_ref.push_back(bool(title01[i] > 96 ? 1 : 0)); + vector vec02_ref; + for (size_t i = 0; i < N2; ++i) + vec02_ref.push_back(bool(title02[i] > 96 ? 1 : 0)); + vector vec03_ref; + for (size_t i = 0; i < N3; ++i) + vec03_ref.push_back(bool(title03[i] > 96 ? 1 : 0)); + vector vec04_ref; + for (size_t i = 0; i < N4; ++i) + vec04_ref.push_back(bool(title04[i] > 96 ? 1 : 0)); + + my_vector::size_type size01, size02; + + my_alloc alloc01(1), alloc02(2); + int personality01, personality02; + + my_vector vec01(alloc01); + size01 = vec01.size(); + personality01 = vec01.get_allocator().get_personality(); + my_vector vec02(alloc02); + size02 = vec02.size(); + personality02 = vec02.get_allocator().get_personality(); + + vec01.swap(vec02); + VERIFY( vec01.size() == size02 ); + VERIFY( vec01.empty() ); + VERIFY( vec02.size() == size01 ); + VERIFY( vec02.empty() ); + VERIFY( vec01.get_allocator().get_personality() == personality02 ); + VERIFY( vec02.get_allocator().get_personality() == personality01 ); + + my_vector vec03(alloc02); + size01 = vec03.size(); + personality01 = vec03.get_allocator().get_personality(); + my_vector vec04(vec02_ref.begin(), vec02_ref.end(), alloc01); + size02 = vec04.size(); + personality02 = vec04.get_allocator().get_personality(); + + vec03.swap(vec04); + VERIFY( vec03.size() == size02 ); + VERIFY( equal(vec03.begin(), vec03.end(), vec02_ref.begin()) ); + VERIFY( vec04.size() == size01 ); + VERIFY( vec04.empty() ); + VERIFY( vec03.get_allocator().get_personality() == personality02 ); + VERIFY( vec04.get_allocator().get_personality() == personality01 ); + + my_vector vec05(vec01_ref.begin(), vec01_ref.end(), alloc01); + size01 = vec05.size(); + personality01 = vec05.get_allocator().get_personality(); + my_vector vec06(vec02_ref.begin(), vec02_ref.end(), alloc02); + size02 = vec06.size(); + personality02 = vec06.get_allocator().get_personality(); + + vec05.swap(vec06); + VERIFY( vec05.size() == size02 ); + VERIFY( equal(vec05.begin(), vec05.end(), vec02_ref.begin()) ); + VERIFY( vec06.size() == size01 ); + VERIFY( equal(vec06.begin(), vec06.end(), vec01_ref.begin()) ); + VERIFY( vec05.get_allocator().get_personality() == personality02 ); + VERIFY( vec06.get_allocator().get_personality() == personality01 ); + + my_vector vec07(vec01_ref.begin(), vec01_ref.end(), alloc02); + size01 = vec07.size(); + personality01 = vec07.get_allocator().get_personality(); + my_vector vec08(vec03_ref.begin(), vec03_ref.end(), alloc01); + size02 = vec08.size(); + personality02 = vec08.get_allocator().get_personality(); + + vec07.swap(vec08); + VERIFY( vec07.size() == size02 ); + VERIFY( equal(vec07.begin(), vec07.end(), vec03_ref.begin()) ); + VERIFY( vec08.size() == size01 ); + VERIFY( equal(vec08.begin(), vec08.end(), vec01_ref.begin()) ); + VERIFY( vec07.get_allocator().get_personality() == personality02 ); + VERIFY( vec08.get_allocator().get_personality() == personality01 ); + + my_vector vec09(vec03_ref.begin(), vec03_ref.end(), alloc01); + size01 = vec09.size(); + personality01 = vec09.get_allocator().get_personality(); + my_vector vec10(vec04_ref.begin(), vec04_ref.end(), alloc02); + size02 = vec10.size(); + personality02 = vec10.get_allocator().get_personality(); + + vec09.swap(vec10); + VERIFY( vec09.size() == size02 ); + VERIFY( equal(vec09.begin(), vec09.end(), vec04_ref.begin()) ); + VERIFY( vec10.size() == size01 ); + VERIFY( equal(vec10.begin(), vec10.end(), vec03_ref.begin()) ); + VERIFY( vec09.get_allocator().get_personality() == personality02 ); + VERIFY( vec10.get_allocator().get_personality() == personality01 ); + + my_vector vec11(vec04_ref.begin(), vec04_ref.end(), alloc02); + size01 = vec11.size(); + personality01 = vec11.get_allocator().get_personality(); + my_vector vec12(vec01_ref.begin(), vec01_ref.end(), alloc01); + size02 = vec12.size(); + personality02 = vec12.get_allocator().get_personality(); + + vec11.swap(vec12); + VERIFY( vec11.size() == size02 ); + VERIFY( equal(vec11.begin(), vec11.end(), vec01_ref.begin()) ); + VERIFY( vec12.size() == size01 ); + VERIFY( equal(vec12.begin(), vec12.end(), vec04_ref.begin()) ); + VERIFY( vec11.get_allocator().get_personality() == personality02 ); + VERIFY( vec12.get_allocator().get_personality() == personality01 ); + + my_vector vec13(vec03_ref.begin(), vec03_ref.end(), alloc01); + size01 = vec13.size(); + personality01 = vec13.get_allocator().get_personality(); + my_vector vec14(vec03_ref.begin(), vec03_ref.end(), alloc02); + size02 = vec14.size(); + personality02 = vec14.get_allocator().get_personality(); + + vec13.swap(vec14); + VERIFY( vec13.size() == size02 ); + VERIFY( equal(vec13.begin(), vec13.end(), vec03_ref.begin()) ); + VERIFY( vec14.size() == size01 ); + VERIFY( equal(vec14.begin(), vec14.end(), vec03_ref.begin()) ); + VERIFY( vec13.get_allocator().get_personality() == personality02 ); + VERIFY( vec14.get_allocator().get_personality() == personality01 ); +} + +int main() +{ + test01(); + return 0; +} -- 2.7.4