stl_vector.h: Use new allocator model in C++0x mode.
2011-07-09 Jonathan Wakely <jwakely.gcc@gmail.com> * include/bits/stl_vector.h: Use new allocator model in C++0x mode. * include/bits/vector.tcc: Likewise. * testsuite/util/testsuite_allocator.h (propagating_allocator): Define. * testsuite/23_containers/vector/allocator/copy_assign.cc: New. * testsuite/23_containers/vector/allocator/noexcept.cc: New. * testsuite/23_containers/vector/allocator/copy.cc: New. * testsuite/23_containers/vector/allocator/swap.cc: New. * testsuite/23_containers/vector/allocator/move_assign.cc: New. * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust dg-error line numbers. * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc: Likewise. From-SVN: r176078
This commit is contained in:
parent
d526242cd8
commit
bd8485dc9f
@ -1,3 +1,22 @@
|
||||
2011-07-09 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
* include/bits/stl_vector.h: Use new allocator model in C++0x mode.
|
||||
* include/bits/vector.tcc: Likewise.
|
||||
* testsuite/util/testsuite_allocator.h (propagating_allocator): Define.
|
||||
* testsuite/23_containers/vector/allocator/copy_assign.cc: New.
|
||||
* testsuite/23_containers/vector/allocator/noexcept.cc: New.
|
||||
* testsuite/23_containers/vector/allocator/copy.cc: New.
|
||||
* testsuite/23_containers/vector/allocator/swap.cc: New.
|
||||
* testsuite/23_containers/vector/allocator/move_assign.cc: New.
|
||||
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
|
||||
Adjust dg-error line numbers.
|
||||
* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
|
||||
Likewise.
|
||||
* testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc:
|
||||
Likewise.
|
||||
* testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc:
|
||||
Likewise.
|
||||
|
||||
2011-07-09 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
* include/ext/alloc_traits.h (__allocator_always_compares_equal): New
|
||||
|
@ -71,13 +71,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
struct _Vector_base
|
||||
{
|
||||
typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
|
||||
typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
|
||||
pointer;
|
||||
|
||||
struct _Vector_impl
|
||||
: public _Tp_alloc_type
|
||||
{
|
||||
typename _Tp_alloc_type::pointer _M_start;
|
||||
typename _Tp_alloc_type::pointer _M_finish;
|
||||
typename _Tp_alloc_type::pointer _M_end_of_storage;
|
||||
pointer _M_start;
|
||||
pointer _M_finish;
|
||||
pointer _M_end_of_storage;
|
||||
|
||||
_Vector_impl()
|
||||
: _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
|
||||
@ -93,6 +95,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
_M_start(0), _M_finish(0), _M_end_of_storage(0)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
void _M_swap_data(_Vector_impl& __x)
|
||||
{
|
||||
std::swap(_M_start, __x._M_start);
|
||||
std::swap(_M_finish, __x._M_finish);
|
||||
std::swap(_M_end_of_storage, __x._M_end_of_storage);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
@ -118,30 +127,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
|
||||
_Vector_base(size_t __n)
|
||||
: _M_impl()
|
||||
{
|
||||
this->_M_impl._M_start = this->_M_allocate(__n);
|
||||
this->_M_impl._M_finish = this->_M_impl._M_start;
|
||||
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
|
||||
}
|
||||
{ _M_create_storage(__n); }
|
||||
|
||||
_Vector_base(size_t __n, const allocator_type& __a)
|
||||
: _M_impl(__a)
|
||||
{
|
||||
this->_M_impl._M_start = this->_M_allocate(__n);
|
||||
this->_M_impl._M_finish = this->_M_impl._M_start;
|
||||
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
|
||||
}
|
||||
{ _M_create_storage(__n); }
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
_Vector_base(_Tp_alloc_type&& __a)
|
||||
: _M_impl(std::move(__a)) { }
|
||||
|
||||
_Vector_base(_Vector_base&& __x)
|
||||
: _M_impl(std::move(__x._M_get_Tp_allocator()))
|
||||
{ this->_M_impl._M_swap_data(__x._M_impl); }
|
||||
|
||||
_Vector_base(_Vector_base&& __x, const allocator_type& __a)
|
||||
: _M_impl(__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 = 0;
|
||||
__x._M_impl._M_finish = 0;
|
||||
__x._M_impl._M_end_of_storage = 0;
|
||||
if (__x.get_allocator() == __a)
|
||||
this->_M_impl._M_swap_data(__x._M_impl);
|
||||
else
|
||||
{
|
||||
size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
|
||||
_M_create_storage(__n);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -152,16 +161,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
public:
|
||||
_Vector_impl _M_impl;
|
||||
|
||||
typename _Tp_alloc_type::pointer
|
||||
pointer
|
||||
_M_allocate(size_t __n)
|
||||
{ return __n != 0 ? _M_impl.allocate(__n) : 0; }
|
||||
|
||||
void
|
||||
_M_deallocate(typename _Tp_alloc_type::pointer __p, size_t __n)
|
||||
_M_deallocate(pointer __p, size_t __n)
|
||||
{
|
||||
if (__p)
|
||||
_M_impl.deallocate(__p, __n);
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
_M_create_storage(size_t __n)
|
||||
{
|
||||
this->_M_impl._M_start = this->_M_allocate(__n);
|
||||
this->_M_impl._M_finish = this->_M_impl._M_start;
|
||||
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -196,10 +214,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
|
||||
public:
|
||||
typedef _Tp value_type;
|
||||
typedef typename _Tp_alloc_type::pointer pointer;
|
||||
typedef typename _Tp_alloc_type::const_pointer const_pointer;
|
||||
typedef typename _Tp_alloc_type::reference reference;
|
||||
typedef typename _Tp_alloc_type::const_reference const_reference;
|
||||
typedef typename _Base::pointer pointer;
|
||||
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
|
||||
typedef typename _Alloc_traits::const_pointer const_pointer;
|
||||
typedef typename _Alloc_traits::reference reference;
|
||||
typedef typename _Alloc_traits::const_reference const_reference;
|
||||
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
|
||||
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
|
||||
const_iterator;
|
||||
@ -283,7 +302,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
* @a x (for fast expansion) will not be copied.
|
||||
*/
|
||||
vector(const vector& __x)
|
||||
: _Base(__x.size(), __x._M_get_Tp_allocator())
|
||||
: _Base(__x.size(),
|
||||
_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
|
||||
{ this->_M_impl._M_finish =
|
||||
std::__uninitialized_copy_a(__x.begin(), __x.end(),
|
||||
this->_M_impl._M_start,
|
||||
@ -301,6 +321,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
vector(vector&& __x) noexcept
|
||||
: _Base(std::move(__x)) { }
|
||||
|
||||
/// Copy constructor with alternative allocator
|
||||
vector(const vector& __x, const allocator_type& __a)
|
||||
: _Base(__x.size(), __a)
|
||||
{ this->_M_impl._M_finish =
|
||||
std::__uninitialized_copy_a(__x.begin(), __x.end(),
|
||||
this->_M_impl._M_start,
|
||||
_M_get_Tp_allocator());
|
||||
}
|
||||
|
||||
/// Move constructor with alternative allocator
|
||||
vector(vector&& __rv, const allocator_type& __m)
|
||||
: _Base(std::move(__rv), __m)
|
||||
{
|
||||
if (__rv.get_allocator() != __m)
|
||||
{
|
||||
this->_M_impl._M_finish =
|
||||
std::__uninitialized_move_a(__rv.begin(), __rv.end(),
|
||||
this->_M_impl._M_start,
|
||||
_M_get_Tp_allocator());
|
||||
__rv.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds a %vector from an initializer list.
|
||||
* @param l An initializer_list.
|
||||
@ -377,12 +420,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
* @a x is a valid, but unspecified %vector.
|
||||
*/
|
||||
vector&
|
||||
operator=(vector&& __x)
|
||||
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
this->clear();
|
||||
this->swap(__x);
|
||||
if (_Alloc_traits::_S_propagate_on_move_assign())
|
||||
{
|
||||
// We're moving the rvalue's allocator so can move the data too.
|
||||
const vector __tmp(std::move(*this)); // discard existing data
|
||||
this->_M_impl._M_swap_data(__x._M_impl);
|
||||
std::__alloc_on_move(_M_get_Tp_allocator(),
|
||||
__x._M_get_Tp_allocator());
|
||||
}
|
||||
else if (_Alloc_traits::_S_always_equal()
|
||||
|| __x._M_get_Tp_allocator() == this->_M_get_Tp_allocator())
|
||||
{
|
||||
// The rvalue's allocator can free our storage and vice versa,
|
||||
// so can swap the data storage after destroying our contents.
|
||||
this->clear();
|
||||
this->_M_impl._M_swap_data(__x._M_impl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The rvalue's allocator cannot be moved, or is not equal,
|
||||
// so we need to individually move each element.
|
||||
this->assign(std::__make_move_if_noexcept_iterator(__x.begin()),
|
||||
std::__make_move_if_noexcept_iterator(__x.end()));
|
||||
__x.clear();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -834,7 +897,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
{
|
||||
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
|
||||
{
|
||||
this->_M_impl.construct(this->_M_impl._M_finish, __x);
|
||||
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
|
||||
__x);
|
||||
++this->_M_impl._M_finish;
|
||||
}
|
||||
else
|
||||
@ -864,7 +928,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
pop_back()
|
||||
{
|
||||
--this->_M_impl._M_finish;
|
||||
this->_M_impl.destroy(this->_M_impl._M_finish);
|
||||
_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
@ -1024,16 +1088,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
*/
|
||||
void
|
||||
swap(vector& __x)
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
noexcept(_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<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(),
|
||||
__x._M_get_Tp_allocator());
|
||||
this->_M_impl._M_swap_data(__x._M_impl);
|
||||
_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
|
||||
__x._M_get_Tp_allocator());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,8 +94,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
{
|
||||
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
|
||||
{
|
||||
this->_M_impl.construct(this->_M_impl._M_finish,
|
||||
std::forward<_Args>(__args)...);
|
||||
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
|
||||
std::forward<_Args>(__args)...);
|
||||
++this->_M_impl._M_finish;
|
||||
}
|
||||
else
|
||||
@ -112,7 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
|
||||
&& __position == end())
|
||||
{
|
||||
this->_M_impl.construct(this->_M_impl._M_finish, __x);
|
||||
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x);
|
||||
++this->_M_impl._M_finish;
|
||||
}
|
||||
else
|
||||
@ -138,7 +138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
if (__position + 1 != end())
|
||||
_GLIBCXX_MOVE3(__position + 1, end(), __position);
|
||||
--this->_M_impl._M_finish;
|
||||
this->_M_impl.destroy(this->_M_impl._M_finish);
|
||||
_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
|
||||
return __position;
|
||||
}
|
||||
|
||||
@ -160,6 +160,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
{
|
||||
if (&__x != this)
|
||||
{
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
if (_Alloc_traits::_S_propagate_on_copy_assign())
|
||||
{
|
||||
if (!_Alloc_traits::_S_always_equal()
|
||||
&& _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
|
||||
{
|
||||
// replacement allocator cannot free existing storage
|
||||
this->clear();
|
||||
_M_deallocate(this->_M_impl._M_start,
|
||||
this->_M_impl._M_end_of_storage
|
||||
- this->_M_impl._M_start);
|
||||
}
|
||||
std::__alloc_on_copy(_M_get_Tp_allocator(),
|
||||
__x._M_get_Tp_allocator());
|
||||
}
|
||||
#endif
|
||||
const size_type __xlen = __x.size();
|
||||
if (__xlen > capacity())
|
||||
{
|
||||
@ -277,8 +293,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
|
||||
&& __position == end())
|
||||
{
|
||||
this->_M_impl.construct(this->_M_impl._M_finish,
|
||||
std::forward<_Args>(__args)...);
|
||||
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
|
||||
std::forward<_Args>(__args)...);
|
||||
++this->_M_impl._M_finish;
|
||||
}
|
||||
else
|
||||
@ -300,9 +316,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
{
|
||||
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
|
||||
{
|
||||
this->_M_impl.construct(this->_M_impl._M_finish,
|
||||
_GLIBCXX_MOVE(*(this->_M_impl._M_finish
|
||||
- 1)));
|
||||
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
|
||||
_GLIBCXX_MOVE(*(this->_M_impl._M_finish
|
||||
- 1)));
|
||||
++this->_M_impl._M_finish;
|
||||
#ifndef __GXX_EXPERIMENTAL_CXX0X__
|
||||
_Tp __x_copy = __x;
|
||||
@ -329,11 +345,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
// case, where the moves could alter a new element belonging
|
||||
// to the existing vector. This is an issue only for callers
|
||||
// taking the element by const lvalue ref (see 23.1/13).
|
||||
this->_M_impl.construct(__new_start + __elems_before,
|
||||
_Alloc_traits::construct(this->_M_impl,
|
||||
__new_start + __elems_before,
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
std::forward<_Args>(__args)...);
|
||||
std::forward<_Args>(__args)...);
|
||||
#else
|
||||
__x);
|
||||
__x);
|
||||
#endif
|
||||
__new_finish = 0;
|
||||
|
||||
@ -352,7 +369,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
__catch(...)
|
||||
{
|
||||
if (!__new_finish)
|
||||
this->_M_impl.destroy(__new_start + __elems_before);
|
||||
_Alloc_traits::destroy(this->_M_impl,
|
||||
__new_start + __elems_before);
|
||||
else
|
||||
std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
|
||||
_M_deallocate(__new_start, __len);
|
||||
|
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2011 Free Software Foundation
|
||||
//
|
||||
// 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++0x" }
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct T { int i; };
|
||||
|
||||
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));
|
||||
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));
|
||||
test_type v2(v1);
|
||||
VERIFY(1 == v1.get_allocator().get_personality());
|
||||
VERIFY(1 == v2.get_allocator().get_personality());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2011 Free Software Foundation
|
||||
//
|
||||
// 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++0x" }
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct T { int i; };
|
||||
|
||||
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));
|
||||
test_type v2(alloc_type(2));
|
||||
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));
|
||||
test_type v2(alloc_type(2));
|
||||
v2 = v1;
|
||||
VERIFY(1 == v1.get_allocator().get_personality());
|
||||
VERIFY(1 == v2.get_allocator().get_personality());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2011 Free Software Foundation
|
||||
//
|
||||
// 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++0x" }
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct T { int i; };
|
||||
|
||||
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));
|
||||
test_type v2(alloc_type(2));
|
||||
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));
|
||||
test_type v2(alloc_type(2));
|
||||
v2 = std::move(v1);
|
||||
VERIFY(0 == v1.get_allocator().get_personality());
|
||||
VERIFY(1 == v2.get_allocator().get_personality());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2011 Free Software Foundation
|
||||
//
|
||||
// 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++0x" }
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct T { int i; };
|
||||
|
||||
namespace __gnu_test
|
||||
{
|
||||
inline void
|
||||
swap(propagating_allocator<T, true>& l, propagating_allocator<T, true>& r)
|
||||
noexcept(false)
|
||||
{
|
||||
typedef uneq_allocator<T> base_alloc;
|
||||
swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
|
||||
}
|
||||
}
|
||||
|
||||
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" );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2011 Free Software Foundation
|
||||
//
|
||||
// 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++0x" }
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct T { int i; };
|
||||
|
||||
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));
|
||||
test_type v2(alloc_type(2));
|
||||
std::swap(v1, v2);
|
||||
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));
|
||||
test_type v2(alloc_type(2));
|
||||
std::swap(v1, v2);
|
||||
VERIFY(2 == v1.get_allocator().get_personality());
|
||||
VERIFY(1 == v2.get_allocator().get_personality());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1157 }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1218 }
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1087 }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1148 }
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1087 }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1148 }
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
@ -18,7 +18,7 @@
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do compile }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1198 }
|
||||
// { dg-error "no matching" "" { target *-*-* } 1259 }
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -371,6 +371,68 @@ namespace __gnu_test
|
||||
|
||||
int personality;
|
||||
};
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
// An uneq_allocator which can be used to test allocator propagation.
|
||||
template<typename Tp, bool Propagate>
|
||||
class propagating_allocator : public uneq_allocator<Tp>
|
||||
{
|
||||
typedef uneq_allocator<Tp> base_alloc;
|
||||
base_alloc& base() { return *this; }
|
||||
const base_alloc& base() const { return *this; }
|
||||
void swap_base(base_alloc& b) { swap(b, this->base()); }
|
||||
|
||||
typedef std::integral_constant<bool, Propagate> trait_type;
|
||||
|
||||
public:
|
||||
template<typename Up>
|
||||
struct rebind { typedef propagating_allocator<Up, Propagate> other; };
|
||||
|
||||
propagating_allocator(int i) noexcept
|
||||
: base_alloc(i)
|
||||
{ }
|
||||
|
||||
template<typename Up>
|
||||
propagating_allocator(const propagating_allocator<Up, Propagate>& a)
|
||||
noexcept
|
||||
: base_alloc(a)
|
||||
{ }
|
||||
|
||||
propagating_allocator() noexcept = default;
|
||||
|
||||
propagating_allocator(const propagating_allocator&) noexcept = default;
|
||||
|
||||
template<bool P2>
|
||||
propagating_allocator&
|
||||
operator=(const propagating_allocator<Tp, P2>& a) noexcept
|
||||
{
|
||||
static_assert(P2, "assigning propagating_allocator<T, true>");
|
||||
propagating_allocator(a).swap_base(*this);
|
||||
}
|
||||
|
||||
// postcondition: a.get_personality() == 0
|
||||
propagating_allocator(propagating_allocator&& a) noexcept
|
||||
: base_alloc()
|
||||
{ swap_base(a); }
|
||||
|
||||
// postcondition: a.get_personality() == 0
|
||||
propagating_allocator&
|
||||
operator=(propagating_allocator&& a) noexcept
|
||||
{
|
||||
propagating_allocator(std::move(a)).swap_base(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef trait_type propagate_on_container_copy_assignment;
|
||||
typedef trait_type propagate_on_container_move_assignment;
|
||||
typedef trait_type propagate_on_container_swap;
|
||||
|
||||
propagating_allocator select_on_container_copy_construction() const
|
||||
{ return Propagate ? *this : propagating_allocator(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace __gnu_test
|
||||
|
||||
#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
|
||||
|
Loading…
Reference in New Issue
Block a user