aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2011-06-07 16:11:36 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-06-07 16:11:36 +0000
commit74a2a1b4f60cb499962d67c43e7d0b3b783b1373 (patch)
tree44f8b32ca92b13801daecdae7376732bd875fb7c
parent06bc3ec79056f8c53d4e59f45afe78a547c23546 (diff)
downloadgcc-74a2a1b4f60cb499962d67c43e7d0b3b783b1373.zip
gcc-74a2a1b4f60cb499962d67c43e7d0b3b783b1373.tar.gz
gcc-74a2a1b4f60cb499962d67c43e7d0b3b783b1373.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog18
-rw-r--r--libstdc++-v3/include/bits/move.h10
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h11
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h13
-rw-r--r--libstdc++-v3/include/bits/vector.tcc76
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc45
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc77
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_rvalref.h14
9 files changed, 276 insertions, 45 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0e3d551..2f3707b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,23 @@
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
* testsuite/22_locale/time_get/get_weekday/char/38081-1.cc: Tweak
for glibc 2.14.
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 6f3b420..d791d69 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -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); }
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index b23107d..c2a1689 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -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
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index f15be3a..246d5c3 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -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,
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 3aaee39..5b6a8d7 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -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(...)
{
diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc b/libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc
new file mode 100644
index 0000000..3a6c313
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc b/libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc
new file mode 100644
index 0000000..5bdb981
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc
new file mode 100644
index 0000000..000db2c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_rvalref.h b/libstdc++-v3/testsuite/util/testsuite_rvalref.h
index 8e37bbd..3159915 100644
--- a/libstdc++-v3/testsuite/util/testsuite_rvalref.h
+++ b/libstdc++-v3/testsuite/util/testsuite_rvalref.h
@@ -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