summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/utility/pairs
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-07-24 05:51:11 +0000
committerEric Fiselier <eric@efcs.ca>2016-07-24 05:51:11 +0000
commit904a5d700752b19fec363f4bf8d00d5eef2c7efd (patch)
treef7d6a75c823ad18809997cc06944305c5dfd04f7 /libcxx/test/std/utilities/utility/pairs
parent2e99ae4f97322372449697bf5266dc1e75fda48b (diff)
downloadbcm5719-llvm-904a5d700752b19fec363f4bf8d00d5eef2c7efd.tar.gz
bcm5719-llvm-904a5d700752b19fec363f4bf8d00d5eef2c7efd.zip
Make pair/tuples assignment operators SFINAE properly.
llvm-svn: 276548
Diffstat (limited to 'libcxx/test/std/utilities/utility/pairs')
-rw-r--r--libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp90
-rw-r--r--libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp68
2 files changed, 156 insertions, 2 deletions
diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
new file mode 100644
index 00000000000..d75b6a5f820
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <utility>
+
+// template <class T1, class T2> struct pair
+
+// pair& operator=(pair const& p);
+
+#include <utility>
+#include <memory>
+#include <cassert>
+
+
+struct NonAssignable {
+ NonAssignable& operator=(NonAssignable const&) = delete;
+ NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+ CopyAssignable() = default;
+ CopyAssignable(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable&&) = delete;
+};
+struct MoveAssignable {
+ MoveAssignable() = default;
+ MoveAssignable& operator=(MoveAssignable const&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
+
+struct CountAssign {
+ static int copied;
+ static int moved;
+ static void reset() { copied = moved = 0; }
+ CountAssign() = default;
+ CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
+ CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
+};
+int CountAssign::copied = 0;
+int CountAssign::moved = 0;
+
+int main()
+{
+ {
+ typedef std::pair<CopyAssignable, short> P;
+ const P p1(CopyAssignable(), 4);
+ P p2;
+ p2 = p1;
+ assert(p2.second == 4);
+ }
+ {
+ using P = std::pair<int&, int&&>;
+ int x = 42;
+ int y = 101;
+ int x2 = -1;
+ int y2 = 300;
+ P p1(x, std::move(y));
+ P p2(x2, std::move(y2));
+ p1 = p2;
+ assert(p1.first == x2);
+ assert(p1.second == y2);
+ }
+ {
+ using P = std::pair<int, NonAssignable>;
+ static_assert(!std::is_copy_assignable<P>::value, "");
+ }
+ {
+ CountAssign::reset();
+ using P = std::pair<CountAssign, CopyAssignable>;
+ static_assert(std::is_copy_assignable<P>::value, "");
+ P p;
+ P p2;
+ p = p2;
+ assert(CountAssign::copied == 1);
+ assert(CountAssign::moved == 0);
+ }
+ {
+ using P = std::pair<int, MoveAssignable>;
+ static_assert(!std::is_copy_assignable<P>::value, "");
+ }
+}
diff --git a/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
index a753ee520df..38089200e4d 100644
--- a/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
+++ b/libcxx/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <utility>
// template <class T1, class T2> struct pair
@@ -17,9 +19,35 @@
#include <memory>
#include <cassert>
+
+struct NonAssignable {
+ NonAssignable& operator=(NonAssignable const&) = delete;
+ NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+ CopyAssignable() = default;
+ CopyAssignable& operator=(CopyAssignable const&) = default;
+ CopyAssignable& operator=(CopyAssignable&&) = delete;
+};
+struct MoveAssignable {
+ MoveAssignable() = default;
+ MoveAssignable& operator=(MoveAssignable const&) = delete;
+ MoveAssignable& operator=(MoveAssignable&&) = default;
+};
+
+struct CountAssign {
+ static int copied;
+ static int moved;
+ static void reset() { copied = moved = 0; }
+ CountAssign() = default;
+ CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
+ CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
+};
+int CountAssign::copied = 0;
+int CountAssign::moved = 0;
+
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::pair<std::unique_ptr<int>, short> P;
P p1(std::unique_ptr<int>(new int(3)), 4);
@@ -28,5 +56,41 @@ int main()
assert(*p2.first == 3);
assert(p2.second == 4);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ using P = std::pair<int&, int&&>;
+ int x = 42;
+ int y = 101;
+ int x2 = -1;
+ int y2 = 300;
+ P p1(x, std::move(y));
+ P p2(x2, std::move(y2));
+ p1 = std::move(p2);
+ assert(p1.first == x2);
+ assert(p1.second == y2);
+ }
+ {
+ using P = std::pair<int, NonAssignable>;
+ static_assert(!std::is_move_assignable<P>::value, "");
+ }
+ {
+ // The move decays to the copy constructor
+ CountAssign::reset();
+ using P = std::pair<CountAssign, CopyAssignable>;
+ static_assert(std::is_move_assignable<P>::value, "");
+ P p;
+ P p2;
+ p = std::move(p2);
+ assert(CountAssign::moved == 0);
+ assert(CountAssign::copied == 1);
+ }
+ {
+ CountAssign::reset();
+ using P = std::pair<CountAssign, MoveAssignable>;
+ static_assert(std::is_move_assignable<P>::value, "");
+ P p;
+ P p2;
+ p = std::move(p2);
+ assert(CountAssign::moved == 1);
+ assert(CountAssign::copied == 0);
+ }
}
OpenPOWER on IntegriCloud