summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/std/utilities')
-rw-r--r--libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp25
-rw-r--r--libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp83
-rw-r--r--libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp81
-rw-r--r--libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp77
-rw-r--r--libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp43
-rw-r--r--libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp78
-rw-r--r--libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp100
-rw-r--r--libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp108
8 files changed, 534 insertions, 61 deletions
diff --git a/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp b/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp
index 44b746fbcfd..c525137d484 100644
--- a/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp
+++ b/libcxx/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp
@@ -16,6 +16,7 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
#include "../deleter.h"
struct A
@@ -34,6 +35,16 @@ struct A
int A::count = 0;
+template <class T>
+struct NonSwappableDeleter {
+ explicit NonSwappableDeleter(int) {}
+ NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
+ void operator()(T*) const {}
+private:
+ NonSwappableDeleter(NonSwappableDeleter const&);
+
+};
+
int main()
{
{
@@ -74,4 +85,18 @@ int main()
assert(A::count == 6);
}
assert(A::count == 0);
+#if TEST_STD_VER >= 11
+ {
+ // test that unique_ptr's specialized swap is disabled when the deleter
+ // is non-swappable. Instead we should pick up the generic swap(T, T)
+ // and perform 3 move constructions.
+ typedef NonSwappableDeleter<int> D;
+ D d(42);
+ int x = 42;
+ int y = 43;
+ std::unique_ptr<int, D&> p(&x, d);
+ std::unique_ptr<int, D&> p2(&y, d);
+ std::swap(p, p2);
+ }
+#endif
}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp
new file mode 100644
index 00000000000..2465987355b
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14
+
+// type_traits
+
+// is_swappable
+
+#include <type_traits>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+// Make the test types non-copyable so that generic std::swap is not valid.
+struct A {
+ A(A const&) = delete;
+ A& operator=(A const&) = delete;
+};
+
+struct B {
+ B(B const&) = delete;
+ B& operator=(B const&) = delete;
+};
+
+void swap(A&, A&) noexcept {}
+void swap(B&, B&) {}
+
+struct M {
+ M(M const&) = delete;
+ M& operator=(M const&) = delete;
+};
+
+void swap(M&&, M&&) noexcept {}
+
+struct ThrowingMove {
+ ThrowingMove(ThrowingMove&&){}
+ ThrowingMove& operator=(ThrowingMove&&) {}
+};
+
+} // namespace MyNS
+
+int main()
+{
+ using namespace MyNS;
+ {
+ // Test that is_swappable applies an lvalue reference to the type.
+ static_assert(std::is_nothrow_swappable<int>::value, "");
+ static_assert(std::is_nothrow_swappable<int&>::value, "");
+ static_assert(!std::is_nothrow_swappable<M>::value, "");
+ static_assert(!std::is_nothrow_swappable<M&&>::value, "");
+ }
+ {
+ // Test that it correctly deduces the noexcept of swap.
+ static_assert(std::is_nothrow_swappable<A>::value, "");
+ static_assert(!std::is_nothrow_swappable<B>::value
+ && std::is_swappable<B>::value, "");
+ static_assert(!std::is_nothrow_swappable<ThrowingMove>::value
+ && std::is_swappable<ThrowingMove>::value);
+ }
+ {
+ // Test that it doesn't drop the qualifiers
+ static_assert(!std::is_nothrow_swappable<const A>::value, "");
+ }
+ {
+ // test non-referenceable types
+ static_assert(!std::is_nothrow_swappable<void>::value, "");
+ static_assert(!std::is_nothrow_swappable<int() const>::value, "");
+ static_assert(!std::is_nothrow_swappable<int(int, ...) const &>::value, "");
+ }
+ {
+ // test for presence of is_nothrow_swappable_v
+ static_assert(std::is_nothrow_swappable_v<int>);
+ static_assert(!std::is_nothrow_swappable_v<void>);
+ }
+}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
new file mode 100644
index 00000000000..54c0a040398
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14
+
+// type_traits
+
+// is_nothrow_swappable_with
+
+#include <type_traits>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+struct A {
+ A(A const&) = delete;
+ A& operator=(A const&) = delete;
+};
+
+struct B {
+ B(B const&) = delete;
+ B& operator=(B const&) = delete;
+};
+
+struct C {};
+struct D {};
+
+void swap(A&, A&) {}
+
+void swap(A&, B&) noexcept {}
+void swap(B&, A&) noexcept {}
+
+void swap(A&, C&) noexcept {}
+void swap(C&, A&) {}
+
+struct M {};
+
+void swap(M&&, M&&) noexcept {}
+
+} // namespace MyNS
+
+int main()
+{
+ using namespace MyNS;
+ {
+ // Test that is_swappable_with doesn't apply an lvalue reference
+ // to the type. Instead it is up to the user.
+ static_assert(!std::is_nothrow_swappable_with<int, int>::value, "");
+ static_assert(std::is_nothrow_swappable_with<int&, int&>::value, "");
+ static_assert(std::is_nothrow_swappable_with<M, M>::value, "");
+ static_assert(std::is_swappable_with<A&, A&>::value &&
+ !std::is_nothrow_swappable_with<A&, A&>::value, "");
+ }
+ {
+ // test that hetrogenius swap is allowed only if both 'swap(A, B)' and
+ // 'swap(B, A)' are valid.
+ static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");
+ static_assert(!std::is_nothrow_swappable_with<A&, C&>::value &&
+ std::is_swappable_with<A&, C&>::value, "");
+ static_assert(!std::is_nothrow_swappable_with<D&, C&>::value, "");
+ }
+ {
+ // test we guard against cv void inputs as required.
+ static_assert(!std::is_nothrow_swappable_with_v<void, int>);
+ static_assert(!std::is_nothrow_swappable_with_v<int, void>);
+ static_assert(!std::is_nothrow_swappable_with_v<const void, const volatile void>);
+
+ }
+ {
+ // test for presense of is_nothrow_swappable_with_v
+ static_assert(std::is_nothrow_swappable_with_v<int&, int&>);
+ static_assert(!std::is_nothrow_swappable_with_v<int&&, int&&>);
+ }
+}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp
new file mode 100644
index 00000000000..43a0a4fe46b
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14
+
+// type_traits
+
+// is_swappable
+
+#include <type_traits>
+#include <utility>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+// Make the test types non-copyable so that generic std::swap is not valid.
+struct A {
+ A(A const&) = delete;
+ A& operator=(A const&) = delete;
+};
+
+struct B {
+ B(B const&) = delete;
+ B& operator=(B const&) = delete;
+};
+
+struct C {};
+struct D {};
+
+void swap(A&, A&) {}
+
+void swap(A&, B&) {}
+void swap(B&, A&) {}
+
+void swap(A&, C&) {} // missing swap(C, A)
+void swap(D&, C&) {}
+
+struct M {
+ M(M const&) = delete;
+ M& operator=(M const&) = delete;
+};
+
+void swap(M&&, M&&) {}
+
+} // namespace MyNS
+
+int main()
+{
+ using namespace MyNS;
+ {
+ // Test that is_swappable applies an lvalue reference to the type.
+ static_assert(std::is_swappable<A>::value, "");
+ static_assert(std::is_swappable<A&>::value, "");
+ static_assert(!std::is_swappable<M>::value, "");
+ static_assert(!std::is_swappable<M&&>::value, "");
+ }
+ static_assert(!std::is_swappable<B>::value, "");
+ static_assert(std::is_swappable<C>::value, "");
+ {
+ // test non-referencable types
+ static_assert(!std::is_swappable<void>::value, "");
+ static_assert(!std::is_swappable<int() const>::value, "");
+ static_assert(!std::is_swappable<int() &>::value, "");
+ }
+ {
+ // test for presense of is_swappable_v
+ static_assert(std::is_swappable_v<int>);
+ static_assert(!std::is_swappable_v<M>);
+ }
+}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp
new file mode 100644
index 00000000000..8bd5614065d
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_swappable
+
+// IMPORTANT: The include order is part of the test. We want to pick up
+// the following definitions in this order:
+// 1) is_swappable, is_nothrow_swappable
+// 2) iter_swap, swap_ranges
+// 3) swap(T (&)[N], T(&)[N]
+// This test checks that (1) and (2) see forward declarations
+// for (3).
+#include <type_traits>
+#include <algorithm>
+#include <utility>
+
+#include "test_macros.h"
+
+int main()
+{
+ // Use a builtin type so we don't get ADL lookup.
+ typedef double T[42][50];
+ {
+ static_assert(std::__is_swappable<T>::value, "");
+#if TEST_STD_VER > 14
+ static_assert(std::is_swappable_v<T>);
+#endif
+ }
+ {
+ T t1 = {};
+ T t2 = {};
+ std::iter_swap(t1, t2);
+ std::swap_ranges(t1, t1 + 42, t2);
+ }
+}
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp
new file mode 100644
index 00000000000..9d470c156dc
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14
+
+// type_traits
+
+// is_swappable_with
+
+#include <type_traits>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+struct A {
+ A(A const&) = delete;
+ A& operator=(A const&) = delete;
+};
+
+struct B {
+ B(B const&) = delete;
+ B& operator=(B const&) = delete;
+};
+
+struct C {};
+struct D {};
+
+void swap(A&, A&) {}
+
+void swap(A&, B&) {}
+void swap(B&, A&) {}
+
+void swap(A&, C&) {} // missing swap(C, A)
+void swap(D&, C&) {}
+
+struct M {};
+
+void swap(M&&, M&&) {}
+
+} // namespace MyNS
+
+int main()
+{
+ using namespace MyNS;
+ {
+ // Test that is_swappable_with doesn't apply an lvalue reference
+ // to the type. Instead it is up to the user.
+ static_assert(!std::is_swappable_with<int, int>::value, "");
+ static_assert(std::is_swappable_with<int&, int&>::value, "");
+ static_assert(std::is_swappable_with<M, M>::value, "");
+ static_assert(std::is_swappable_with<A&, A&>::value, "");
+ }
+ {
+ // test that heterogeneous swap is allowed only if both 'swap(A, B)' and
+ // 'swap(B, A)' are valid.
+ static_assert(std::is_swappable_with<A&, B&>::value, "");
+ static_assert(!std::is_swappable_with<A&, C&>::value, "");
+ static_assert(!std::is_swappable_with<D&, C&>::value, "");
+ }
+ {
+ // test that cv void is guarded against as required.
+ static_assert(!std::is_swappable_with_v<void, int>);
+ static_assert(!std::is_swappable_with_v<int, void>);
+ static_assert(!std::is_swappable_with_v<const void, const volatile void>);
+ }
+ {
+ // test for presence of is_swappable_with_v
+ static_assert(std::is_swappable_with_v<int&, int&>);
+ static_assert(!std::is_swappable_with_v<D&, C&>);
+ }
+}
diff --git a/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp b/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp
index 8606611f660..c9c9f3b5276 100644
--- a/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.swap/swap.pass.cpp
@@ -16,38 +16,88 @@
#include <utility>
#include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#include <memory>
-#endif
-void
-test()
-{
- int i = 1;
- int j = 2;
- std::swap(i, j);
- assert(i == 2);
- assert(j == 1);
-}
+#include "test_macros.h"
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
+struct CopyOnly {
+ CopyOnly() {}
+ CopyOnly(CopyOnly const&) noexcept {}
+ CopyOnly& operator=(CopyOnly const&) { return *this; }
+};
-void
-test1()
-{
- std::unique_ptr<int> i(new int(1));
- std::unique_ptr<int> j(new int(2));
- std::swap(i, j);
- assert(*i == 2);
- assert(*j == 1);
-}
+struct MoveOnly {
+ MoveOnly() {}
+ MoveOnly(MoveOnly&&) {}
+ MoveOnly& operator=(MoveOnly&&) noexcept { return *this; }
+};
+
+struct NoexceptMoveOnly {
+ NoexceptMoveOnly() {}
+ NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
+ NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
+};
+
+struct NotMoveConstructible {
+ NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
+private:
+ NotMoveConstructible(NotMoveConstructible&&);
+};
+
+struct NotMoveAssignable {
+ NotMoveAssignable(NotMoveAssignable&&);
+private:
+ NotMoveAssignable& operator=(NotMoveAssignable&&);
+};
+
+template <class Tp>
+auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class Tp>
+auto can_swap_test(...) -> std::false_type;
+
+template <class Tp>
+constexpr bool can_swap() {
+ return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
+}
+#endif
int main()
{
- test();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- test1();
+
+ {
+ int i = 1;
+ int j = 2;
+ std::swap(i, j);
+ assert(i == 2);
+ assert(j == 1);
+ }
+#if TEST_STD_VER >= 11
+ {
+
+ std::unique_ptr<int> i(new int(1));
+ std::unique_ptr<int> j(new int(2));
+ std::swap(i, j);
+ assert(*i == 2);
+ assert(*j == 1);
+
+ }
+ {
+ // test that the swap
+ static_assert(can_swap<CopyOnly&>(), "");
+ static_assert(can_swap<MoveOnly&>(), "");
+ static_assert(can_swap<NoexceptMoveOnly&>(), "");
+
+ static_assert(!can_swap<NotMoveConstructible&>(), "");
+ static_assert(!can_swap<NotMoveAssignable&>(), "");
+
+ CopyOnly c;
+ MoveOnly m;
+ NoexceptMoveOnly nm;
+ static_assert(!noexcept(std::swap(c, c)), "");
+ static_assert(!noexcept(std::swap(m, m)), "");
+ static_assert(noexcept(std::swap(nm, nm)), "");
+ }
#endif
}
diff --git a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
index b1209c3c365..ad39934b20c 100644
--- a/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
+++ b/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
@@ -16,50 +16,86 @@
#include <utility>
#include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#include <memory>
-#endif
-void
-test()
-{
- int i[3] = {1, 2, 3};
- int j[3] = {4, 5, 6};
- std::swap(i, j);
- assert(i[0] == 4);
- assert(i[1] == 5);
- assert(i[2] == 6);
- assert(j[0] == 1);
- assert(j[1] == 2);
- assert(j[2] == 3);
-}
+#include "test_macros.h"
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-void
-test1()
-{
- std::unique_ptr<int> i[3];
- for (int k = 0; k < 3; ++k)
- i[k].reset(new int(k+1));
- std::unique_ptr<int> j[3];
- for (int k = 0; k < 3; ++k)
- j[k].reset(new int(k+4));
- std::swap(i, j);
- assert(*i[0] == 4);
- assert(*i[1] == 5);
- assert(*i[2] == 6);
- assert(*j[0] == 1);
- assert(*j[1] == 2);
- assert(*j[2] == 3);
+#if TEST_STD_VER >= 11
+struct CopyOnly {
+ CopyOnly() {}
+ CopyOnly(CopyOnly const&) noexcept {}
+ CopyOnly& operator=(CopyOnly const&) { return *this; }
+};
+
+
+struct NoexceptMoveOnly {
+ NoexceptMoveOnly() {}
+ NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
+ NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
+};
+
+struct NotMoveConstructible {
+ NotMoveConstructible() {}
+ NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
+private:
+ NotMoveConstructible(NotMoveConstructible&&);
+};
+
+template <class Tp>
+auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
+
+template <class Tp>
+auto can_swap_test(...) -> std::false_type;
+
+template <class Tp>
+constexpr bool can_swap() {
+ return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
}
+#endif
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
int main()
{
- test();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- test1();
+ {
+ int i[3] = {1, 2, 3};
+ int j[3] = {4, 5, 6};
+ std::swap(i, j);
+ assert(i[0] == 4);
+ assert(i[1] == 5);
+ assert(i[2] == 6);
+ assert(j[0] == 1);
+ assert(j[1] == 2);
+ assert(j[2] == 3);
+ }
+#if TEST_STD_VER >= 11
+ {
+ std::unique_ptr<int> i[3];
+ for (int k = 0; k < 3; ++k)
+ i[k].reset(new int(k+1));
+ std::unique_ptr<int> j[3];
+ for (int k = 0; k < 3; ++k)
+ j[k].reset(new int(k+4));
+ std::swap(i, j);
+ assert(*i[0] == 4);
+ assert(*i[1] == 5);
+ assert(*i[2] == 6);
+ assert(*j[0] == 1);
+ assert(*j[1] == 2);
+ assert(*j[2] == 3);
+ }
+ {
+ using CA = CopyOnly[42];
+ using MA = NoexceptMoveOnly[42];
+ using NA = NotMoveConstructible[42];
+ static_assert(can_swap<CA&>(), "");
+ static_assert(can_swap<MA&>(), "");
+ static_assert(!can_swap<NA&>(), "");
+
+ CA ca;
+ MA ma;
+ static_assert(!noexcept(std::swap(ca, ca)), "");
+ static_assert(noexcept(std::swap(ma, ma)), "");
+ }
#endif
}
OpenPOWER on IntegriCloud