summaryrefslogtreecommitdiffstats
path: root/libcxx/test/support
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-10-17 13:03:17 +0000
committerEric Fiselier <eric@efcs.ca>2017-10-17 13:03:17 +0000
commit1c0cedccb62480d61bc4c0c31c871f9096b4873a (patch)
tree7f0273afe6543f92aa56aa048e3c9ed812386c9b /libcxx/test/support
parent228340315d655373219db0d61bd48e390b9f5735 (diff)
downloadbcm5719-llvm-1c0cedccb62480d61bc4c0c31c871f9096b4873a.tar.gz
bcm5719-llvm-1c0cedccb62480d61bc4c0c31c871f9096b4873a.zip
[libc++] Fix PR34898 - vector iterator constructors and assign method perform push_back instead of emplace_back.
Summary: The constructors `vector(Iter, Iter, Alloc = Alloc{})` and `assign(Iter, Iter)` don't correctly perform EmplaceConstruction from the result of dereferencing the iterator. This results in them performing an additional and unneeded copy. This patch addresses the issue by correctly using `emplace_back` in C++11 and newer. There are also some bugs in our `insert` implementation, but those will be handled separately. @mclow.lists We should probably merge this into 5.1, agreed? Reviewers: mclow.lists, dlj, EricWF Reviewed By: mclow.lists, EricWF Subscribers: cfe-commits, mclow.lists Differential Revision: https://reviews.llvm.org/D38757 llvm-svn: 315994
Diffstat (limited to 'libcxx/test/support')
-rw-r--r--libcxx/test/support/container_test_types.h28
-rw-r--r--libcxx/test/support/emplace_constructible.h74
2 files changed, 100 insertions, 2 deletions
diff --git a/libcxx/test/support/container_test_types.h b/libcxx/test/support/container_test_types.h
index 08e88f09146..b8422ec4602 100644
--- a/libcxx/test/support/container_test_types.h
+++ b/libcxx/test/support/container_test_types.h
@@ -234,6 +234,19 @@ inline ConstructController* getConstructController() {
return &c;
}
+template <class ...Args>
+struct ExpectConstructGuard {
+ ExpectConstructGuard(int N) {
+ auto CC = getConstructController();
+ assert(!CC->unchecked());
+ CC->expect<Args...>(N);
+ }
+
+ ~ExpectConstructGuard() {
+ assert(!getConstructController()->unchecked());
+ }
+};
+
//===----------------------------------------------------------------------===//
// ContainerTestAllocator
//===----------------------------------------------------------------------===//
@@ -417,7 +430,12 @@ namespace std {
return arg.data;
}
};
-
+ template <class T, class Alloc>
+ class vector;
+ template <class T, class Alloc>
+ class deque;
+ template <class T, class Alloc>
+ class list;
template <class _Key, class _Value, class _Less, class _Alloc>
class map;
template <class _Key, class _Value, class _Less, class _Alloc>
@@ -444,6 +462,13 @@ _LIBCPP_END_NAMESPACE_STD
// TCT - Test container type
namespace TCT {
+template <class T = CopyInsertable<1>>
+using vector = std::vector<T, ContainerTestAllocator<T, T> >;
+template <class T = CopyInsertable<1>>
+using deque = std::deque<T, ContainerTestAllocator<T, T> >;
+template <class T = CopyInsertable<1>>
+using list = std::list<T, ContainerTestAllocator<T, T> >;
+
template <class Key = CopyInsertable<1>, class Value = CopyInsertable<2>,
class ValueTp = std::pair<const Key, Value> >
using unordered_map =
@@ -488,5 +513,4 @@ using multiset =
} // end namespace TCT
-
#endif // SUPPORT_CONTAINER_TEST_TYPES_H
diff --git a/libcxx/test/support/emplace_constructible.h b/libcxx/test/support/emplace_constructible.h
new file mode 100644
index 00000000000..f2bc0ec6a36
--- /dev/null
+++ b/libcxx/test/support/emplace_constructible.h
@@ -0,0 +1,74 @@
+#ifndef TEST_SUPPORT_EMPLACE_CONSTRUCTIBLE_H
+#define TEST_SUPPORT_EMPLACE_CONSTRUCTIBLE_H
+
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 11
+template <class T>
+struct EmplaceConstructible {
+ T value;
+ explicit EmplaceConstructible(T value) : value(value) {}
+ EmplaceConstructible(EmplaceConstructible const&) = delete;
+};
+
+template <class T>
+struct EmplaceConstructibleAndMoveInsertable {
+ int copied = 0;
+ T value;
+ explicit EmplaceConstructibleAndMoveInsertable(T value) : value(value) {}
+
+ EmplaceConstructibleAndMoveInsertable(
+ EmplaceConstructibleAndMoveInsertable&& Other)
+ : copied(Other.copied + 1), value(std::move(Other.value)) {}
+};
+
+template <class T>
+struct EmplaceConstructibleAndMoveable {
+ int copied = 0;
+ int assigned = 0;
+ T value;
+ explicit EmplaceConstructibleAndMoveable(T value) noexcept : value(value) {}
+
+ EmplaceConstructibleAndMoveable(EmplaceConstructibleAndMoveable&& Other)
+ noexcept : copied(Other.copied + 1),
+ value(std::move(Other.value)) {}
+
+ EmplaceConstructibleAndMoveable&
+ operator=(EmplaceConstructibleAndMoveable&& Other) noexcept {
+ copied = Other.copied;
+ assigned = Other.assigned + 1;
+ value = std::move(Other.value);
+ return *this;
+ }
+};
+
+template <class T>
+struct EmplaceConstructibleMoveableAndAssignable {
+ int copied = 0;
+ int assigned = 0;
+ T value;
+ explicit EmplaceConstructibleMoveableAndAssignable(T value) noexcept
+ : value(value) {}
+
+ EmplaceConstructibleMoveableAndAssignable(
+ EmplaceConstructibleMoveableAndAssignable&& Other) noexcept
+ : copied(Other.copied + 1),
+ value(std::move(Other.value)) {}
+
+ EmplaceConstructibleMoveableAndAssignable&
+ operator=(EmplaceConstructibleMoveableAndAssignable&& Other) noexcept {
+ copied = Other.copied;
+ assigned = Other.assigned + 1;
+ value = std::move(Other.value);
+ return *this;
+ }
+
+ EmplaceConstructibleMoveableAndAssignable& operator=(T xvalue) {
+ value = std::move(xvalue);
+ ++assigned;
+ return *this;
+ }
+};
+#endif
+
+#endif // TEST_SUPPORT_EMPLACE_CONSTRUCTIBLE_H
OpenPOWER on IntegriCloud