re PR libstdc++/49836 ([C++0x] vector<T>::push_back() should not require T to be (move-)assignable)

2011-07-25  Paolo Carlini  <paolo.carlini@oracle.com>
	    Nathan Ridge  <zeratul976@hotmail.com>

	PR libstdc++/49836
	* include/bits/stl_vector.h (vector<>::_M_emplace_back_aux):
	Declare.
	(vector<>::push_back(const value_type&)): Use it.
	* include/bits/vector.tcc: Define.
	(vector<>::emplace_back(_Args&&...)): Use it.
	* testsuite/util/testsuite_tr1.h (CopyConsOnlyType, MoveConsOnlyType):
	Add.
	* testsuite/23_containers/vector/modifiers/push_back/49836.cc: New.
	* testsuite/23_containers/deque/modifiers/push_back/49836.cc:
	Likewise.
	* testsuite/23_containers/deque/modifiers/push_front/49836.cc:
	Likewise.
	* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
	Adjust dg-error line number.
	* 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.

Co-Authored-By: Nathan Ridge <zeratul976@hotmail.com>

From-SVN: r176761
This commit is contained in:
Paolo Carlini 2011-07-25 17:08:48 +00:00 committed by Paolo Carlini
parent 8175c19c1b
commit cc2ba8e30f
11 changed files with 250 additions and 5 deletions

View File

@ -1,3 +1,28 @@
2011-07-25 Paolo Carlini <paolo.carlini@oracle.com>
Nathan Ridge <zeratul976@hotmail.com>
PR libstdc++/49836
* include/bits/stl_vector.h (vector<>::_M_emplace_back_aux):
Declare.
(vector<>::push_back(const value_type&)): Use it.
* include/bits/vector.tcc: Define.
(vector<>::emplace_back(_Args&&...)): Use it.
* testsuite/util/testsuite_tr1.h (CopyConsOnlyType, MoveConsOnlyType):
Add.
* testsuite/23_containers/vector/modifiers/push_back/49836.cc: New.
* testsuite/23_containers/deque/modifiers/push_back/49836.cc:
Likewise.
* testsuite/23_containers/deque/modifiers/push_front/49836.cc:
Likewise.
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
Adjust dg-error line number.
* 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-24 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/hashtable_policy.h (_Prime_rehash_policy::_M_next_bkt,

View File

@ -902,7 +902,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
++this->_M_impl._M_finish;
}
else
#ifdef __GXX_EXPERIMENTAL_CXX0X__
_M_emplace_back_aux(__x);
#else
_M_insert_aux(end(), __x);
#endif
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@ -1303,6 +1307,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename... _Args>
void
_M_insert_aux(iterator __position, _Args&&... __args);
template<typename... _Args>
void
_M_emplace_back_aux(_Args&&... __args);
#endif
// Called by the latter.

View File

@ -99,7 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
++this->_M_impl._M_finish;
}
else
_M_insert_aux(end(), std::forward<_Args>(__args)...);
_M_emplace_back_aux(std::forward<_Args>(__args)...);
}
#endif
@ -387,6 +387,50 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename _Tp, typename _Alloc>
template<typename... _Args>
void
vector<_Tp, _Alloc>::
_M_emplace_back_aux(_Args&&... __args)
{
const size_type __len =
_M_check_len(size_type(1), "vector::_M_emplace_back_aux");
pointer __new_start(this->_M_allocate(__len));
pointer __new_finish(__new_start);
__try
{
_Alloc_traits::construct(this->_M_impl, __new_start + size(),
std::forward<_Args>(__args)...);
__new_finish = 0;
__new_finish
= std::__uninitialized_move_if_noexcept_a
(this->_M_impl._M_start, this->_M_impl._M_finish,
__new_start, _M_get_Tp_allocator());
++__new_finish;
}
__catch(...)
{
if (!__new_finish)
_Alloc_traits::destroy(this->_M_impl, __new_start + size());
else
std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
_M_deallocate(__new_start, __len);
__throw_exception_again;
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
this->_M_impl._M_start = __new_start;
this->_M_impl._M_finish = __new_finish;
this->_M_impl._M_end_of_storage = __new_start + __len;
}
#endif
template<typename _Tp, typename _Alloc>
void
vector<_Tp, _Alloc>::

View File

@ -0,0 +1,50 @@
// { dg-options "-std=gnu++0x" }
// Copyright (C) 2011 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/>.
#include <deque>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>
// libstdc++/49836
void test01()
{
bool test __attribute__((unused)) = true;
using __gnu_test::CopyConsOnlyType;
using __gnu_test::MoveConsOnlyType;
std::deque<CopyConsOnlyType> d1;
CopyConsOnlyType t1(1);
d1.push_back(t1);
d1.push_back(t1);
d1.push_back(t1);
VERIFY( d1.size() == 3 );
std::deque<MoveConsOnlyType> d2;
MoveConsOnlyType t2(1);
d2.push_back(std::move(t2));
d2.push_back(std::move(t2));
d2.push_back(std::move(t2));
VERIFY( d2.size() == 3 );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,50 @@
// { dg-options "-std=gnu++0x" }
// Copyright (C) 2011 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/>.
#include <deque>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>
// libstdc++/49836
void test01()
{
bool test __attribute__((unused)) = true;
using __gnu_test::CopyConsOnlyType;
using __gnu_test::MoveConsOnlyType;
std::deque<CopyConsOnlyType> d1;
CopyConsOnlyType t1(1);
d1.push_front(t1);
d1.push_front(t1);
d1.push_front(t1);
VERIFY( d1.size() == 3 );
std::deque<MoveConsOnlyType> d2;
MoveConsOnlyType t2(1);
d2.push_front(std::move(t2));
d2.push_front(std::move(t2));
d2.push_front(std::move(t2));
VERIFY( d2.size() == 3 );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,50 @@
// { dg-options "-std=gnu++0x" }
// Copyright (C) 2011 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/>.
#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>
// libstdc++/49836
void test01()
{
bool test __attribute__((unused)) = true;
using __gnu_test::CopyConsOnlyType;
using __gnu_test::MoveConsOnlyType;
std::vector<CopyConsOnlyType> v1;
CopyConsOnlyType t1(1);
v1.push_back(t1);
v1.push_back(t1);
v1.push_back(t1);
VERIFY( v1.size() == 3 );
std::vector<MoveConsOnlyType> v2;
MoveConsOnlyType t2(1);
v2.push_back(std::move(t2));
v2.push_back(std::move(t2));
v2.push_back(std::move(t2));
VERIFY( v2.size() == 3 );
}
int main()
{
test01();
return 0;
}

View File

@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
// { dg-error "no matching" "" { target *-*-* } 1218 }
// { dg-error "no matching" "" { target *-*-* } 1222 }
#include <vector>

View File

@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
// { dg-error "no matching" "" { target *-*-* } 1148 }
// { dg-error "no matching" "" { target *-*-* } 1152 }
#include <vector>

View File

@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
// { dg-error "no matching" "" { target *-*-* } 1148 }
// { dg-error "no matching" "" { target *-*-* } 1152 }
#include <vector>
#include <utility>

View File

@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
// { dg-error "no matching" "" { target *-*-* } 1259 }
// { dg-error "no matching" "" { target *-*-* } 1263 }
#include <vector>

View File

@ -696,6 +696,24 @@ namespace __gnu_test
MO& operator=(MO&&) = default;
};
}
struct CopyConsOnlyType
{
CopyConsOnlyType(int) { }
CopyConsOnlyType(CopyConsOnlyType&&) = delete;
CopyConsOnlyType(const CopyConsOnlyType&) = default;
CopyConsOnlyType& operator=(const CopyConsOnlyType&) = delete;
CopyConsOnlyType& operator=(CopyConsOnlyType&&) = delete;
};
struct MoveConsOnlyType
{
MoveConsOnlyType(int) { }
MoveConsOnlyType(const MoveConsOnlyType&) = delete;
MoveConsOnlyType(MoveConsOnlyType&&) = default;
MoveConsOnlyType& operator=(const MoveConsOnlyType&) = delete;
MoveConsOnlyType& operator=(MoveConsOnlyType&&) = delete;
};
#endif
} // namespace __gnu_test