Commit ccd615e3 by Jonathan Wakely Committed by Jonathan Wakely

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.

From-SVN: r216988
parent 9ccb17b4
2014-10-31 Jonathan Wakely <jwakely@redhat.com>
* 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.
2014-10-30 David Edelsohn <dje.gcc@gmail.com>
* configure.host (aix5+): New stanza.
......
......@@ -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;
}
}
......
// Copyright (C) 2014 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-options "-std=gnu++11" }
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, false> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(0 == v2.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, true> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
void test03()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, true> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(v1, alloc_type(2));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
test03();
return 0;
}
// Copyright (C) 2014 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-options "-std=gnu++11" }
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, false> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(alloc_type(2));
v2.push_back(T());
v2 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, true> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(alloc_type(2));
v2.push_back(T());
v2 = v1;
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
// Copyright (C) 2014 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-options "-std=gnu++11" }
#include <vector>
#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::CustomPointerAlloc;
template class std::vector<T, CustomPointerAlloc<T>>;
void test01()
{
bool test __attribute__((unused)) = true;
typedef CustomPointerAlloc<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v;
v.push_back(T());
VERIFY( ++v.begin() == v.end() );
}
int main()
{
test01();
}
// Copyright (C) 2014 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-options "-std=gnu++11" }
// { dg-do compile }
#include <vector>
#include <memory>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::SimpleAllocator;
template class std::vector<T, SimpleAllocator<T>>;
void test01()
{
typedef SimpleAllocator<T> alloc_type;
typedef std::allocator_traits<alloc_type> traits_type;
typedef std::vector<T, alloc_type> test_type;
test_type v(alloc_type{});
v.push_back(T());
}
// Copyright (C) 2014 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-options "-std=gnu++11" }
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { T() };
auto it = v1.begin();
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { T() };
test_type v2(std::move(v1), alloc_type(2));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
return 0;
}
// Copyright (C) 2014 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-options "-std=gnu++11" }
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::propagating_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, false> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(alloc_type(2));
v2.push_back(T());
v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, true> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.push_back(T());
v2 = std::move(v1);
VERIFY( it == v2.begin() );
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
void test03()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, false> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
auto it = v1.begin();
test_type v2(alloc_type(1));
v2.push_back(T());
v2 = std::move(v1);
VERIFY( it == v2.begin() );
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
int main()
{
test01();
test02();
test03();
return 0;
}
// Copyright (C) 2014 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 compile }
// { dg-options "-std=gnu++11" }
#include <vector>
#include <testsuite_allocator.h>
using T = bool;
namespace __gnu_test
{
template<typename U>
inline void
swap(propagating_allocator<U, true>& l, propagating_allocator<U, true>& r)
noexcept(false)
{ }
}
using __gnu_test::propagating_allocator;
void test01()
{
typedef std::allocator<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1;
test_type v2;
// this is a GNU extension for std::allocator
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
void test02()
{
typedef propagating_allocator<T, false> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
test_type v2(alloc_type(2));
static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
}
void test03()
{
typedef propagating_allocator<T, true> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
test_type v2(alloc_type(2));
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
}
// Copyright (C) 2014 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-options "-std=gnu++11" }
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using T = bool;
using __gnu_test::propagating_allocator;
// It is undefined behaviour to swap() containers wth unequal allocators
// if the allocator doesn't propagate, so ensure the allocators compare
// equal, while still being able to test propagation via get_personality().
bool
operator==(const propagating_allocator<T, false>&,
const propagating_allocator<T, false>&)
{
return true;
}
bool
operator!=(const propagating_allocator<T, false>&,
const propagating_allocator<T, false>&)
{
return false;
}
void test01()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, false> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(alloc_type(2));
v2.push_back(T());
std::swap(v1, v2);
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
// swap back so assertions in uneq_allocator::deallocate don't fail
std::swap(v1, v2);
}
void test02()
{
bool test __attribute__((unused)) = true;
typedef propagating_allocator<T, true> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_back(T());
test_type v2(alloc_type(2));
v2.push_back(T());
std::swap(v1, v2);
VERIFY(2 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
}
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