summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-31 20:49:40 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-31 20:49:40 +0000
commit081db185ef94b45c72106e3725fe64de56b402d2 (patch)
treeb2e6ecad35b86d5807204670bcf8e10569378ee0 /libstdc++-v3/include/bits
parent978e3209f5105a855fff642a0c5487713bab8a23 (diff)
downloadgcc-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.h153
-rw-r--r--libstdc++-v3/include/bits/vector.tcc34
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;
}
}