mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-30 21:41:16 +08:00
move.h (struct __move_if_noexcept_cond): Add.
2011-06-07 Paolo Carlini <paolo.carlini@oracle.com> * include/bits/move.h (struct __move_if_noexcept_cond): Add. (move_if_noexcept): Use the latter. * include/bits/stl_iterator.h (__make_move_if_noexcept_iterator, _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR): Add. * include/bits/stl_uninitialized.h (__uninitialized_move_if_noexcept_a): Add. * include/bits/vector.tcc (vector<>::reserve): Use _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR. (vector<>::_M_insert_aux, _M_fill_insert, _M_default_append, _M_range_insert): Use __uninitialized_move_if_noexcept_a. * testsuite/23_containers/vector/modifiers/moveable2.cc: New. * testsuite/23_containers/vector/capacity/resize/moveable2.cc: Likewise. * testsuite/23_containers/vector/capacity/reserve/moveable2.cc: Likewise. From-SVN: r174756
This commit is contained in:
parent
06bc3ec790
commit
74a2a1b4f6
@ -1,3 +1,21 @@
|
||||
2011-06-07 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* include/bits/move.h (struct __move_if_noexcept_cond): Add.
|
||||
(move_if_noexcept): Use the latter.
|
||||
* include/bits/stl_iterator.h (__make_move_if_noexcept_iterator,
|
||||
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR): Add.
|
||||
* include/bits/stl_uninitialized.h
|
||||
(__uninitialized_move_if_noexcept_a): Add.
|
||||
* include/bits/vector.tcc (vector<>::reserve): Use
|
||||
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR.
|
||||
(vector<>::_M_insert_aux, _M_fill_insert, _M_default_append,
|
||||
_M_range_insert): Use __uninitialized_move_if_noexcept_a.
|
||||
* testsuite/23_containers/vector/modifiers/moveable2.cc: New.
|
||||
* testsuite/23_containers/vector/capacity/resize/moveable2.cc:
|
||||
Likewise.
|
||||
* testsuite/23_containers/vector/capacity/reserve/moveable2.cc:
|
||||
Likewise.
|
||||
|
||||
2011-06-07 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/49293
|
||||
|
@ -82,6 +82,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
move(_Tp&& __t) noexcept
|
||||
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
|
||||
|
||||
|
||||
template<typename _Tp>
|
||||
struct __move_if_noexcept_cond
|
||||
: public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
|
||||
is_copy_constructible<_Tp>>::type { };
|
||||
|
||||
/**
|
||||
* @brief Move unless it could throw and the type is copyable.
|
||||
* @ingroup utilities
|
||||
@ -90,9 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
*/
|
||||
template<typename _Tp>
|
||||
inline typename
|
||||
conditional<__and_<__not_<is_nothrow_move_constructible<_Tp>>,
|
||||
is_copy_constructible<_Tp>>::value,
|
||||
const _Tp&, _Tp&&>::type
|
||||
conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
|
||||
move_if_noexcept(_Tp& __x) noexcept
|
||||
{ return std::move(__x); }
|
||||
|
||||
|
@ -1118,14 +1118,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
make_move_iterator(const _Iterator& __i)
|
||||
{ return move_iterator<_Iterator>(__i); }
|
||||
|
||||
template<typename _Iterator, typename _ReturnType
|
||||
= typename conditional<__move_if_noexcept_cond
|
||||
<typename iterator_traits<_Iterator>::value_type>::value,
|
||||
_Iterator, move_iterator<_Iterator>>::type>
|
||||
inline _ReturnType
|
||||
__make_move_if_noexcept_iterator(_Iterator __i)
|
||||
{ return _ReturnType(__i); }
|
||||
|
||||
// @} group iterators
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter)
|
||||
#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \
|
||||
std::__make_move_if_noexcept_iterator(_Iter)
|
||||
#else
|
||||
#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter)
|
||||
#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
|
||||
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||
|
||||
#endif
|
||||
|
@ -269,6 +269,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__result, __alloc);
|
||||
}
|
||||
|
||||
template<typename _InputIterator, typename _ForwardIterator,
|
||||
typename _Allocator>
|
||||
inline _ForwardIterator
|
||||
__uninitialized_move_if_noexcept_a(_InputIterator __first,
|
||||
_InputIterator __last,
|
||||
_ForwardIterator __result,
|
||||
_Allocator& __alloc)
|
||||
{
|
||||
return std::__uninitialized_copy_a
|
||||
(_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
|
||||
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
|
||||
}
|
||||
|
||||
template<typename _ForwardIterator, typename _Tp, typename _Allocator>
|
||||
void
|
||||
__uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
|
||||
|
@ -72,8 +72,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
{
|
||||
const size_type __old_size = size();
|
||||
pointer __tmp = _M_allocate_and_copy(__n,
|
||||
_GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start),
|
||||
_GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish));
|
||||
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
|
||||
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
|
||||
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
|
||||
_M_get_Tp_allocator());
|
||||
_M_deallocate(this->_M_impl._M_start,
|
||||
@ -337,17 +337,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
#endif
|
||||
__new_finish = 0;
|
||||
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(this->_M_impl._M_start,
|
||||
__position.base(), __new_start,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(this->_M_impl._M_start, __position.base(),
|
||||
__new_start, _M_get_Tp_allocator());
|
||||
|
||||
++__new_finish;
|
||||
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(__position.base(),
|
||||
this->_M_impl._M_finish,
|
||||
__new_finish,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(__position.base(), this->_M_impl._M_finish,
|
||||
__new_finish, _M_get_Tp_allocator());
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
@ -423,18 +423,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish = 0;
|
||||
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(this->_M_impl._M_start,
|
||||
__position.base(),
|
||||
__new_start,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(this->_M_impl._M_start, __position.base(),
|
||||
__new_start, _M_get_Tp_allocator());
|
||||
|
||||
__new_finish += __n;
|
||||
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(__position.base(),
|
||||
this->_M_impl._M_finish,
|
||||
__new_finish,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(__position.base(), this->_M_impl._M_finish,
|
||||
__new_finish, _M_get_Tp_allocator());
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
@ -484,11 +483,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
pointer __new_finish(__new_start);
|
||||
__try
|
||||
{
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(this->_M_impl._M_start,
|
||||
this->_M_impl._M_finish,
|
||||
__new_start,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(this->_M_impl._M_start, this->_M_impl._M_finish,
|
||||
__new_start, _M_get_Tp_allocator());
|
||||
std::__uninitialized_default_n_a(__new_finish, __n,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish += __n;
|
||||
@ -577,20 +575,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
pointer __new_finish(__new_start);
|
||||
__try
|
||||
{
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(this->_M_impl._M_start,
|
||||
__position.base(),
|
||||
__new_start,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish =
|
||||
std::__uninitialized_copy_a(__first, __last,
|
||||
__new_finish,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish =
|
||||
std::__uninitialized_move_a(__position.base(),
|
||||
this->_M_impl._M_finish,
|
||||
__new_finish,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(this->_M_impl._M_start, __position.base(),
|
||||
__new_start, _M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_copy_a(__first, __last,
|
||||
__new_finish,
|
||||
_M_get_Tp_allocator());
|
||||
__new_finish
|
||||
= std::__uninitialized_move_if_noexcept_a
|
||||
(__position.base(), this->_M_impl._M_finish,
|
||||
__new_finish, _M_get_Tp_allocator());
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
|
@ -0,0 +1,45 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
// 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_rvalref.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
using namespace __gnu_test;
|
||||
|
||||
std::vector<throwing_move_constructor> v(5);
|
||||
|
||||
v.reserve(50);
|
||||
VERIFY( v.capacity() >= 50 );
|
||||
|
||||
v.reserve(500);
|
||||
VERIFY( v.capacity() >= 500 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
// 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_rvalref.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
using namespace __gnu_test;
|
||||
|
||||
std::vector<throwing_move_constructor> v(5);
|
||||
|
||||
v.resize(50);
|
||||
VERIFY( v.size() == 50 );
|
||||
|
||||
v.reserve(200);
|
||||
VERIFY( v.capacity() >= 200 );
|
||||
|
||||
v.resize(100);
|
||||
VERIFY( v.size() == 100 );
|
||||
|
||||
v.resize(500, throwing_move_constructor());
|
||||
VERIFY( v.size() == 500 );
|
||||
|
||||
v.reserve(2000);
|
||||
VERIFY( v.capacity() >= 2000 );
|
||||
|
||||
v.resize(1000, throwing_move_constructor());
|
||||
VERIFY( v.size() == 1000 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
// 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_rvalref.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
using namespace __gnu_test;
|
||||
|
||||
std::vector<throwing_move_constructor> v1;
|
||||
|
||||
throwing_move_constructor tmc;
|
||||
|
||||
v1.push_back(tmc);
|
||||
VERIFY( v1.size() == 1 );
|
||||
|
||||
v1.push_back(tmc);
|
||||
VERIFY( v1.size() == 2 );
|
||||
|
||||
v1.insert(v1.end(), tmc);
|
||||
VERIFY( v1.size() == 3 );
|
||||
|
||||
v1.insert(v1.end(), 100, tmc);
|
||||
VERIFY( v1.size() == 103 );
|
||||
|
||||
v1.insert(v1.end(), 10, tmc);
|
||||
VERIFY( v1.size() == 113 );
|
||||
|
||||
v1.insert(v1.end(), 1, tmc);
|
||||
VERIFY( v1.size() == 114 );
|
||||
|
||||
std::vector<throwing_move_constructor> v2;
|
||||
|
||||
throwing_move_constructor tmca[]
|
||||
= { throwing_move_constructor(), throwing_move_constructor(),
|
||||
throwing_move_constructor(), throwing_move_constructor() };
|
||||
|
||||
v2.insert(v2.end(), tmca, tmca + 1);
|
||||
VERIFY( v2.size() == 1 );
|
||||
|
||||
v2.insert(v2.end(), tmca, tmca + 4);
|
||||
VERIFY( v2.size() == 5 );
|
||||
|
||||
v2.insert(v2.end(), tmca, tmca + 2);
|
||||
VERIFY( v2.size() == 7 );
|
||||
|
||||
v2.insert(v2.end(), tmca, tmca + 1);
|
||||
VERIFY( v2.size() == 8 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
@ -117,7 +117,7 @@ namespace __gnu_test
|
||||
++copycount;
|
||||
}
|
||||
|
||||
copycounter(copycounter&& in)
|
||||
copycounter(copycounter&& in) noexcept
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
VERIFY( in.valid == true );
|
||||
@ -156,7 +156,7 @@ namespace __gnu_test
|
||||
return *this;
|
||||
}
|
||||
|
||||
~copycounter()
|
||||
~copycounter() noexcept
|
||||
{ valid = false; }
|
||||
};
|
||||
|
||||
@ -246,6 +246,16 @@ namespace __gnu_test
|
||||
return lh.val < rh.val;
|
||||
}
|
||||
|
||||
struct throwing_move_constructor
|
||||
{
|
||||
throwing_move_constructor() = default;
|
||||
|
||||
throwing_move_constructor(throwing_move_constructor&&)
|
||||
{ throw 1; }
|
||||
|
||||
throwing_move_constructor(const throwing_move_constructor&) = default;
|
||||
};
|
||||
|
||||
} // namespace __gnu_test
|
||||
|
||||
namespace std
|
||||
|
Loading…
x
Reference in New Issue
Block a user