aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2011-07-25 17:08:48 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-07-25 17:08:48 +0000
commitcc2ba8e30fa7378e5f0e4a7473287c918d7db663 (patch)
tree8bf7168be80b73a3be6683e8ecbc408f74f347c5
parent8175c19c1ba6e51ea44e00ea4bff5a3725ddbddb (diff)
downloadgcc-cc2ba8e30fa7378e5f0e4a7473287c918d7db663.zip
gcc-cc2ba8e30fa7378e5f0e4a7473287c918d7db663.tar.gz
gcc-cc2ba8e30fa7378e5f0e4a7473287c918d7db663.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog25
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h8
-rw-r--r--libstdc++-v3/include/bits/vector.tcc46
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc50
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc50
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc50
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_tr1.h18
11 files changed, 250 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9130181..79db713 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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,
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 0211033..601459b 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -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.
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index 85b514b..ba98c7c 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -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>::
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc
new file mode 100644
index 0000000..290a191
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc
new file mode 100644
index 0000000..b481aff
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc
new file mode 100644
index 0000000..0a6426a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index 8ff8545..55b9096 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index 344f1a6..6ea2c6f 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index 7f3c52e..75b5bd6 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index c2337c8..d93de19 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -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>
diff --git a/libstdc++-v3/testsuite/util/testsuite_tr1.h b/libstdc++-v3/testsuite/util/testsuite_tr1.h
index 842d445..94207a6 100644
--- a/libstdc++-v3/testsuite/util/testsuite_tr1.h
+++ b/libstdc++-v3/testsuite/util/testsuite_tr1.h
@@ -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