Commit 7d594224 by François Dumont

stl_bvector.h (__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)): Change signature.

2017-06-16  François Dumont  <fdumont@gcc.gnu.org>

	* 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<bool>::operator=(vector&&)): Likewise.
	(vector<bool>::vector()): Default.
	(vector<bool>::vector(vector&&)): Default.
	(vector<bool>::assign(_InputIterator, _InputIterator)): Use
	_M_assign_aux.
	(vector<bool>::assign(initializer_list<bool>)): Likewise.
	(vector<bool>::_M_initialize_value(bool)): New.
	(vector<bool>(size_type, const bool&, const allocator_type&)): Use
	latter.
	(vector<bool>::_M_initialize_dispatch(_Integer, _Integer, __true_type)):
	Likewise.
	(vector<bool>::_M_fill_assign(size_t, bool)): Likewise.

From-SVN: r249235
parent c3684b7b
2017-06-16 François Dumont <fdumont@gcc.gnu.org>
* 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<bool>::operator=(vector&&)): Likewise.
(vector<bool>::vector()): Default.
(vector<bool>::vector(vector&&)): Default.
(vector<bool>::assign(_InputIterator, _InputIterator)): Use
_M_assign_aux.
(vector<bool>::assign(initializer_list<bool>)): Likewise.
(vector<bool>::_M_initialize_value(bool)): New.
(vector<bool>(size_type, const bool&, const allocator_type&)): Use
latter.
(vector<bool>::_M_initialize_dispatch(_Integer, _Integer, __true_type)):
Likewise.
(vector<bool>::_M_fill_assign(size_t, bool)): Likewise.
2017-06-15 François Dumont <fdumont@gcc.gnu.org> 2017-06-15 François Dumont <fdumont@gcc.gnu.org>
* src/c++98/tree.cc [!_GLIBCXX_INLINE_VERSION] * src/c++98/tree.cc [!_GLIBCXX_INLINE_VERSION]
......
...@@ -388,10 +388,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -388,10 +388,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return __x + __n; } { return __x + __n; }
inline void 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) const _Bit_type __fmask = ~0ul << __first;
*__first = __x; const _Bit_type __lmask = ~0ul >> (_S_word_bit - __last);
const _Bit_type __mask = __fmask & __lmask;
if (__x)
*__v |= __mask;
else
*__v &= ~__mask;
} }
inline void inline void
...@@ -399,12 +406,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -399,12 +406,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ {
if (__first._M_p != __last._M_p) if (__first._M_p != __last._M_p)
{ {
std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0); _Bit_type *__first_p = __first._M_p;
__fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x); if (__first._M_offset != 0)
__fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x); __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 else
__fill_bvector(__first, __last, __x); __fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x);
} }
template<typename _Alloc> template<typename _Alloc>
...@@ -416,33 +429,62 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -416,33 +429,62 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Bit_alloc_traits; _Bit_alloc_traits;
typedef typename _Bit_alloc_traits::pointer _Bit_pointer; typedef typename _Bit_alloc_traits::pointer _Bit_pointer;
struct _Bvector_impl struct _Bvector_impl_data
: public _Bit_alloc_type
{ {
_Bit_iterator _M_start; _Bit_iterator _M_start;
_Bit_iterator _M_finish; _Bit_iterator _M_finish;
_Bit_pointer _M_end_of_storage; _Bit_pointer _M_end_of_storage;
_Bvector_impl_data() _GLIBCXX_NOEXCEPT
: _M_start(), _M_finish(), _M_end_of_storage()
{ }
#if __cplusplus >= 201103L
_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() _Bvector_impl()
: _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage() _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type()) )
: _Bit_alloc_type()
{ } { }
_Bvector_impl(const _Bit_alloc_type& __a) _Bvector_impl(const _Bit_alloc_type& __a) _GLIBCXX_NOEXCEPT
: _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage() : _Bit_alloc_type(__a)
{ } { }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
_Bvector_impl(_Bit_alloc_type&& __a) _Bvector_impl(_Bvector_impl&&) = default;
: _Bit_alloc_type(std::move(__a)), _M_start(), _M_finish(),
_M_end_of_storage()
{ }
#endif #endif
_Bit_type* _Bit_type*
_M_end_addr() const _GLIBCXX_NOEXCEPT _M_end_addr() const _GLIBCXX_NOEXCEPT
{ {
if (_M_end_of_storage) if (this->_M_end_of_storage)
return std::__addressof(_M_end_of_storage[-1]) + 1; return std::__addressof(this->_M_end_of_storage[-1]) + 1;
return 0; return 0;
} }
}; };
...@@ -452,33 +494,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -452,33 +494,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Bit_alloc_type& _Bit_alloc_type&
_M_get_Bit_allocator() _GLIBCXX_NOEXCEPT _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT
{ return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } { return this->_M_impl; }
const _Bit_alloc_type& const _Bit_alloc_type&
_M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT
{ return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); } { return this->_M_impl; }
allocator_type allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT get_allocator() const _GLIBCXX_NOEXCEPT
{ return allocator_type(_M_get_Bit_allocator()); } { return allocator_type(_M_get_Bit_allocator()); }
_Bvector_base() #if __cplusplus >= 201103L
: _M_impl() { } _Bvector_base() = default;
#else
_Bvector_base() { }
#endif
_Bvector_base(const allocator_type& __a) _Bvector_base(const allocator_type& __a)
: _M_impl(__a) { } : _M_impl(__a) { }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
_Bvector_base(_Bvector_base&& __x) noexcept _Bvector_base(_Bvector_base&&) = default;
: _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;
}
#endif #endif
~_Bvector_base() ~_Bvector_base()
...@@ -500,11 +536,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -500,11 +536,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Bit_alloc_traits::deallocate(_M_impl, _Bit_alloc_traits::deallocate(_M_impl,
_M_impl._M_end_of_storage - __n, _M_impl._M_end_of_storage - __n,
__n); __n);
_M_impl._M_start = _M_impl._M_finish = _Bit_iterator(); _M_impl._M_reset();
_M_impl._M_end_of_storage = _Bit_pointer();
} }
} }
#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 static size_t
_S_nword(size_t __n) _S_nword(size_t __n)
{ return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); } { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
...@@ -539,7 +580,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -539,7 +580,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* memory and size allocation. Subscripting ( @c [] ) access is * memory and size allocation. Subscripting ( @c [] ) access is
* also provided as with C-style arrays. * also provided as with C-style arrays.
*/ */
template<typename _Alloc> template<typename _Alloc>
class vector<bool, _Alloc> : protected _Bvector_base<_Alloc> class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
{ {
typedef _Bvector_base<_Alloc> _Base; typedef _Bvector_base<_Alloc> _Base;
...@@ -564,7 +605,8 @@ template<typename _Alloc> ...@@ -564,7 +605,8 @@ template<typename _Alloc>
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef _Alloc allocator_type; typedef _Alloc allocator_type;
allocator_type get_allocator() const allocator_type
get_allocator() const
{ return _Base::get_allocator(); } { return _Base::get_allocator(); }
protected: protected:
...@@ -574,11 +616,11 @@ template<typename _Alloc> ...@@ -574,11 +616,11 @@ template<typename _Alloc>
using _Base::_M_get_Bit_allocator; using _Base::_M_get_Bit_allocator;
public: public:
vector()
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
noexcept(is_nothrow_default_constructible<allocator_type>::value) vector() = default;
#else
vector() { }
#endif #endif
: _Base() { }
explicit explicit
vector(const allocator_type& __a) vector(const allocator_type& __a)
...@@ -592,23 +634,16 @@ template<typename _Alloc> ...@@ -592,23 +634,16 @@ template<typename _Alloc>
vector(size_type __n, const bool& __value, vector(size_type __n, const bool& __value,
const allocator_type& __a = allocator_type()) 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);
}
#else #else
explicit explicit
vector(size_type __n, const bool& __value = bool(), vector(size_type __n, const bool& __value = bool(),
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
#endif
: _Base(__a) : _Base(__a)
{ {
_M_initialize(__n); _M_initialize(__n);
std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(), _M_initialize_value(__value);
__value ? ~0 : 0);
} }
#endif
vector(const vector& __x) vector(const vector& __x)
: _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator())) : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator()))
...@@ -618,22 +653,14 @@ template<typename _Alloc> ...@@ -618,22 +653,14 @@ template<typename _Alloc>
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
vector(vector&& __x) noexcept vector(vector&&) = default;
: _Base(std::move(__x)) { }
vector(vector&& __x, const allocator_type& __a) vector(vector&& __x, const allocator_type& __a)
noexcept(_Bit_alloc_traits::_S_always_equal()) noexcept(_Bit_alloc_traits::_S_always_equal())
: _Base(__a) : _Base(__a)
{ {
if (__x.get_allocator() == __a) if (__x.get_allocator() == __a)
{ this->_M_move_data(std::move(__x));
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 else
{ {
_M_initialize(__x.size()); _M_initialize(__x.size());
...@@ -716,12 +743,7 @@ template<typename _Alloc> ...@@ -716,12 +743,7 @@ template<typename _Alloc>
|| this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator()) || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator())
{ {
this->_M_deallocate(); this->_M_deallocate();
this->_M_impl._M_start = __x._M_impl._M_start; this->_M_move_data(std::move(__x));
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(), std::__alloc_on_move(_M_get_Bit_allocator(),
__x._M_get_Bit_allocator()); __x._M_get_Bit_allocator());
} }
...@@ -760,7 +782,7 @@ template<typename _Alloc> ...@@ -760,7 +782,7 @@ template<typename _Alloc>
typename = std::_RequireInputIter<_InputIterator>> typename = std::_RequireInputIter<_InputIterator>>
void void
assign(_InputIterator __first, _InputIterator __last) assign(_InputIterator __first, _InputIterator __last)
{ _M_assign_dispatch(__first, __last, __false_type()); } { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
#else #else
template<typename _InputIterator> template<typename _InputIterator>
void void
...@@ -774,7 +796,7 @@ template<typename _Alloc> ...@@ -774,7 +796,7 @@ template<typename _Alloc>
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
void void
assign(initializer_list<bool> __l) assign(initializer_list<bool> __l)
{ this->assign(__l.begin(), __l.end()); } { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); }
#endif #endif
iterator iterator
...@@ -1101,6 +1123,15 @@ template<typename _Alloc> ...@@ -1101,6 +1123,15 @@ template<typename _Alloc>
this->_M_impl._M_start = iterator(0, 0); this->_M_impl._M_start = iterator(0, 0);
} }
this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
}
void
_M_initialize_value(bool __x)
{
__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));
} }
void void
...@@ -1120,8 +1151,7 @@ template<typename _Alloc> ...@@ -1120,8 +1151,7 @@ template<typename _Alloc>
_M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
{ {
_M_initialize(static_cast<size_type>(__n)); _M_initialize(static_cast<size_type>(__n));
std::fill(this->_M_impl._M_start._M_p, _M_initialize_value(__x);
this->_M_impl._M_end_addr(), __x ? ~0 : 0);
} }
template<typename _InputIterator> template<typename _InputIterator>
...@@ -1150,6 +1180,7 @@ template<typename _Alloc> ...@@ -1150,6 +1180,7 @@ template<typename _Alloc>
std::copy(__first, __last, this->_M_impl._M_start); std::copy(__first, __last, this->_M_impl._M_start);
} }
#if __cplusplus < 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// 438. Ambiguity in the "do the right thing" clause // 438. Ambiguity in the "do the right thing" clause
template<typename _Integer> template<typename _Integer>
...@@ -1162,21 +1193,20 @@ template<typename _Alloc> ...@@ -1162,21 +1193,20 @@ template<typename _Alloc>
_M_assign_dispatch(_InputIterator __first, _InputIterator __last, _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type) __false_type)
{ _M_assign_aux(__first, __last, std::__iterator_category(__first)); } { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
#endif
void void
_M_fill_assign(size_t __n, bool __x) _M_fill_assign(size_t __n, bool __x)
{ {
if (__n > size()) if (__n > size())
{ {
std::fill(this->_M_impl._M_start._M_p, _M_initialize_value(__x);
this->_M_impl._M_end_addr(), __x ? ~0 : 0);
insert(end(), __n - size(), __x); insert(end(), __n - size(), __x);
} }
else else
{ {
_M_erase_at_end(begin() + __n); _M_erase_at_end(begin() + __n);
std::fill(this->_M_impl._M_start._M_p, _M_initialize_value(__x);
this->_M_impl._M_end_addr(), __x ? ~0 : 0);
} }
} }
......
// 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
// <http://www.gnu.org/licenses/>.
// { dg-do run { target c++11 } }
// { dg-options "-O0" }
// { dg-xfail-run-if "PR c++/65816" { *-*-* } }
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
#include <ext/aligned_buffer.h>
using T = bool;
using __gnu_test::default_init_allocator;
void test01()
{
typedef default_init_allocator<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
__gnu_cxx::__aligned_buffer<test_type> 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<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
__gnu_cxx::__aligned_buffer<test_type> 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment