summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/pair
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/pair')
-rw-r--r--src/boost/libs/hana/test/pair/assign.copy.cpp40
-rw-r--r--src/boost/libs/hana/test/pair/assign.move.cpp70
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.copy.cpp94
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.default.cpp71
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.memberwise.cpp87
-rw-r--r--src/boost/libs/hana/test/pair/cnstr.move.cpp97
-rw-r--r--src/boost/libs/hana/test/pair/comparable.cpp33
-rw-r--r--src/boost/libs/hana/test/pair/empty_storage.cpp34
-rw-r--r--src/boost/libs/hana/test/pair/foldable.cpp31
-rw-r--r--src/boost/libs/hana/test/pair/issue_90.cpp43
-rw-r--r--src/boost/libs/hana/test/pair/make.cpp57
-rw-r--r--src/boost/libs/hana/test/pair/orderable.cpp46
-rw-r--r--src/boost/libs/hana/test/pair/product.cpp29
-rw-r--r--src/boost/libs/hana/test/pair/tag_of.cpp36
14 files changed, 768 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/pair/assign.copy.cpp b/src/boost/libs/hana/test/pair/assign.copy.cpp
new file mode 100644
index 000000000..ddcf97c3f
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/assign.copy.cpp
@@ -0,0 +1,40 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+constexpr auto in_constexpr_context(int a, short b) {
+ hana::pair<int, short> p1(a, b);
+ hana::pair<int, short> p2;
+ hana::pair<double, long> p3;
+ p2 = p1;
+ p3 = p2;
+ return p3;
+}
+
+int main() {
+ {
+ hana::pair<int, short> p1(3, 4);
+ hana::pair<double, long> p2;
+ p2 = p1;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // make sure that also works in a constexpr context
+ // (test fails under GCC <= 6 due to buggy constexpr)
+#if BOOST_HANA_CONFIG_GCC >= BOOST_HANA_CONFIG_VERSION(7, 0, 0)
+ {
+ constexpr auto p = in_constexpr_context(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+#endif
+}
diff --git a/src/boost/libs/hana/test/pair/assign.move.cpp b/src/boost/libs/hana/test/pair/assign.move.cpp
new file mode 100644
index 000000000..5d3fd18df
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/assign.move.cpp
@@ -0,0 +1,70 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+struct MoveOnlyDerived : MoveOnly {
+ MoveOnlyDerived(MoveOnlyDerived&&) = default;
+ MoveOnlyDerived(int data = 1) : MoveOnly(data) { }
+};
+
+constexpr auto in_constexpr_context(int a, short b) {
+ hana::pair<int, short> p1(a, b);
+ hana::pair<int, short> p2;
+ hana::pair<double, long> p3;
+ p2 = std::move(p1);
+ p3 = std::move(p2);
+ return p3;
+}
+
+int main() {
+ // from pair<T, U> to pair<T, U>
+ {
+ hana::pair<MoveOnly, short> p1(MoveOnly{3}, 4);
+ hana::pair<MoveOnly, short> p2;
+ p2 = std::move(p1);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // from pair<T, U> to pair<V, W>
+ {
+ hana::pair<MoveOnlyDerived, short> p1(MoveOnlyDerived{3}, 4);
+ hana::pair<MoveOnly, long> p2;
+ p2 = std::move(p1);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // make sure that also works in a constexpr context
+ // (test fails under GCC <= 6 due to buggy constexpr)
+#if BOOST_HANA_CONFIG_GCC >= BOOST_HANA_CONFIG_VERSION(7, 0, 0)
+ {
+ constexpr auto p = in_constexpr_context(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+#endif
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.copy.cpp b/src/boost/libs/hana/test/pair/cnstr.copy.cpp
new file mode 100644
index 000000000..fcf46c4e6
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.copy.cpp
@@ -0,0 +1,94 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+template <typename Target>
+struct implicit_to {
+ constexpr operator Target() const { return Target{}; }
+};
+
+struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+};
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoCopy_nonempty {
+ NoCopy_nonempty() = default;
+ NoCopy_nonempty(NoCopy_nonempty const&) = delete;
+ int i;
+};
+
+int main() {
+ {
+ typedef std::pair<int, short> P1;
+ hana::pair<int, short> p1(3, 4);
+ hana::pair<int, short> p2 = p1;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ static_assert(std::is_trivially_copy_constructible<hana::pair<int, int>>{}, "");
+
+ // make sure it also works constexpr
+ {
+ constexpr hana::pair<int, short> p1(3, 4);
+ constexpr hana::pair<int, short> p2 = p1;
+ static_assert(hana::first(p2) == 3, "");
+ static_assert(hana::second(p2) == 4, "");
+ }
+
+ // Make sure it works across pair types (pair<T, U> -> pair<U, V>)
+ {
+ hana::pair<int, short> p1(3, 4);
+ hana::pair<double, long> p2 = p1;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+ {
+ struct target1 { };
+ struct target2 { };
+ using Target = hana::pair<target1, target2>;
+
+ auto p1_ = hana::make_pair(target1{}, target2{});
+ Target p1(p1_); (void)p1;
+
+ auto p2_ = hana::make_pair(implicit_to<target1>{}, target2{});
+ Target p2(p2_); (void)p2;
+
+ auto p3_ = hana::make_pair(target1{}, implicit_to<target2>{});
+ Target p3(p3_); (void)p3;
+
+ auto p4_ = hana::make_pair(implicit_to<target1>{}, implicit_to<target2>{});
+ Target p4(p4_); (void)p4;
+ }
+
+ // And also constexpr across pair types
+ {
+ constexpr hana::pair<int, short> p1(3, 4);
+ constexpr hana::pair<double, long> p2 = p1;
+ static_assert(hana::first(p2) == 3, "");
+ static_assert(hana::second(p2) == 4, "");
+ }
+
+ // Make sure we don't define the copy constructor when it shouldn't be defined.
+ {
+ using Pair1 = hana::pair<NoCopy, NoCopy>;
+ Pair1 pair1; (void)pair1;
+ static_assert(!std::is_copy_constructible<Pair1>::value, "");
+
+ using Pair2 = hana::pair<NoCopy_nonempty, NoCopy_nonempty>;
+ Pair2 pair2; (void)pair2;
+ static_assert(!std::is_copy_constructible<Pair2>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.default.cpp b/src/boost/libs/hana/test/pair/cnstr.default.cpp
new file mode 100644
index 000000000..4bffb7574
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.default.cpp
@@ -0,0 +1,71 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct NoDefault {
+ NoDefault() = delete;
+ explicit constexpr NoDefault(int) { }
+};
+
+struct NoDefault_nonempty {
+ NoDefault_nonempty() = delete;
+ explicit constexpr NoDefault_nonempty(int k) : i(k) { }
+ int i;
+};
+
+struct DefaultOnly {
+ DefaultOnly() = default;
+ DefaultOnly(DefaultOnly const&) = delete;
+ DefaultOnly(DefaultOnly&&) = delete;
+};
+
+struct NonConstexprDefault {
+ NonConstexprDefault() { }
+};
+
+int main() {
+ {
+ hana::pair<float, short*> p;
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == 0.0f);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == nullptr);
+ }
+
+ // make sure it also works constexpr
+ {
+ constexpr hana::pair<float, short*> p;
+ static_assert(hana::first(p) == 0.0f, "");
+ static_assert(hana::second(p) == nullptr, "");
+ }
+
+ // make sure the default constructor is not instantiated when the
+ // members of the pair are not default-constructible
+ {
+ using Pair1 = hana::pair<NoDefault, NoDefault>;
+ Pair1 p1{NoDefault{1}, NoDefault{2}}; (void)p1;
+ static_assert(!std::is_default_constructible<Pair1>{}, "");
+
+ using Pair2 = hana::pair<NoDefault_nonempty, NoDefault_nonempty>;
+ Pair2 p2{NoDefault_nonempty{1}, NoDefault_nonempty{2}}; (void)p2;
+ static_assert(!std::is_default_constructible<Pair2>{}, "");
+ }
+
+ // make sure it works when only the default constructor is defined
+ {
+ hana::pair<DefaultOnly, DefaultOnly> p;
+ (void)p;
+ }
+
+ {
+ hana::pair<NonConstexprDefault, NonConstexprDefault> p;
+ (void)p;
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.memberwise.cpp b/src/boost/libs/hana/test/pair/cnstr.memberwise.cpp
new file mode 100644
index 000000000..badede7c1
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.memberwise.cpp
@@ -0,0 +1,87 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+class FromInt {
+ int data_;
+public:
+ constexpr FromInt(int data) : data_(data) { }
+ constexpr bool operator==(const FromInt& x) const { return data_ == x.data_; }
+};
+
+int main() {
+ //////////////////////////////////////////////////////////////////////////
+ // Check for the pair(T&&, U&&) constructor
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::pair<MoveOnly, short*> p(MoveOnly{3}, nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == nullptr);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Check for the pair(First const&, Second const&) constructor
+ //////////////////////////////////////////////////////////////////////////
+ {
+ hana::pair<float, short*> p1(3.5f, 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p1) == 3.5f);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p1) == nullptr);
+
+ // brace init
+ hana::pair<float, short*> p2 = {3.5f, 0};
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == 3.5f);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == nullptr);
+ }
+ {
+ hana::pair<FromInt, int> p1(1, 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p1) == FromInt(1));
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p1) == 2);
+
+ // brace init
+ hana::pair<FromInt, int> p2 = {1, 2};
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == FromInt(1));
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 2);
+ }
+
+ // Make sure the above works constexpr too
+ {
+ constexpr hana::pair<float, short*> p1(3.5f, 0);
+ static_assert(hana::first(p1) == 3.5f, "");
+ static_assert(hana::second(p1) == nullptr, "");
+
+ // brace init
+ constexpr hana::pair<float, short*> p2 = {3.5f, 0};
+ static_assert(hana::first(p2) == 3.5f, "");
+ static_assert(hana::second(p2) == nullptr, "");
+ }
+ {
+ constexpr hana::pair<FromInt, int> p1(1, 2);
+ static_assert(hana::first(p1) == FromInt(1), "");
+ static_assert(hana::second(p1) == 2, "");
+
+ // brace init
+ constexpr hana::pair<FromInt, int> p2 = {1, 2};
+ static_assert(hana::first(p2) == FromInt(1), "");
+ static_assert(hana::second(p2) == 2, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/cnstr.move.cpp b/src/boost/libs/hana/test/pair/cnstr.move.cpp
new file mode 100644
index 000000000..cb13e7243
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/cnstr.move.cpp
@@ -0,0 +1,97 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <type_traits>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+struct MoveOnlyDerived : MoveOnly {
+ MoveOnlyDerived(MoveOnlyDerived&&) = default;
+ MoveOnlyDerived(int data = 1) : MoveOnly(data) { }
+};
+
+template <typename Target>
+struct implicit_to {
+ constexpr operator Target() const { return Target{}; }
+};
+
+struct NoMove {
+ NoMove() = default;
+ NoMove(NoMove const&) = delete;
+ NoMove(NoMove&&) = delete;
+};
+
+// Note: It is also useful to check with a non-empty class, because that
+// triggers different instantiations due to EBO.
+struct NoMove_nonempty {
+ NoMove_nonempty() = default;
+ NoMove_nonempty(NoMove_nonempty const&) = delete;
+ NoMove_nonempty(NoMove_nonempty&&) = delete;
+ int i;
+};
+
+int main() {
+ {
+ hana::pair<MoveOnly, short> p1(MoveOnly{3}, 4);
+ hana::pair<MoveOnly, short> p2(std::move(p1));
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+
+ // Make sure it works across pair types
+ {
+ hana::pair<MoveOnlyDerived, short> p1(MoveOnlyDerived{3}, 4);
+ hana::pair<MoveOnly, long> p2 = std::move(p1);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p2) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p2) == 4);
+ }
+ {
+ struct target1 {
+ target1() = default;
+ target1(target1 const&) = delete;
+ target1(target1&&) = default;
+ };
+
+ struct target2 {
+ target2() = default;
+ target2(target2 const&) = delete;
+ target2(target2&&) = default;
+ };
+ using Target = hana::pair<target1, target2>;
+ Target p1(hana::make_pair(target1{}, target2{})); (void)p1;
+ Target p2(hana::make_pair(implicit_to<target1>{}, target2{})); (void)p2;
+ Target p3(hana::make_pair(target1{}, implicit_to<target2>{})); (void)p3;
+ Target p4(hana::make_pair(implicit_to<target1>{}, implicit_to<target2>{})); (void)p4;
+ }
+
+ // Make sure we don't define the move constructor when it shouldn't be defined.
+ {
+ using Pair1 = hana::pair<NoMove, NoMove>;
+ Pair1 pair1; (void)pair1;
+ static_assert(!std::is_move_constructible<Pair1>::value, "");
+
+ using Pair2 = hana::pair<NoMove_nonempty, NoMove_nonempty>;
+ Pair2 pair2; (void)pair2;
+ static_assert(!std::is_move_constructible<Pair2>::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/comparable.cpp b/src/boost/libs/hana/test/pair/comparable.cpp
new file mode 100644
index 000000000..13537c9ef
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/comparable.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_eq<1>{}, ct_eq<2>{}) ==
+ hana::make_pair(ct_eq<1>{}, ct_eq<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_eq<1>{}, ct_eq<3>{}) !=
+ hana::make_pair(ct_eq<1>{}, ct_eq<2>{})
+ );
+
+ hana::test::TestComparable<hana::pair_tag>{hana::make_tuple(
+ hana::make_pair(ct_eq<3>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<4>{})
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/empty_storage.cpp b/src/boost/libs/hana/test/pair/empty_storage.cpp
new file mode 100644
index 000000000..000041485
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/empty_storage.cpp
@@ -0,0 +1,34 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/pair.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct empty1 { };
+struct empty2 { };
+struct empty3 { };
+struct empty4 { };
+
+// Make sure the storage of a pair is compressed
+static_assert(sizeof(hana::pair<empty1, int>) == sizeof(int), "");
+static_assert(sizeof(hana::pair<int, empty1>) == sizeof(int), "");
+
+// Also make sure that a pair with only empty members is empty too. This is
+// important to ensure, for example, that a tuple of pairs of empty objects
+// will get the EBO.
+static_assert(std::is_empty<hana::pair<empty1, empty2>>{}, "");
+
+// Make sure that a pair of empty pairs is still empty.
+static_assert(std::is_empty<
+ hana::pair<hana::pair<empty1, empty2>, empty3>
+>{}, "");
+
+static_assert(std::is_empty<
+ hana::pair<hana::pair<empty1, empty2>, hana::pair<empty3, empty4>>
+>{}, "");
+
+int main() { }
diff --git a/src/boost/libs/hana/test/pair/foldable.cpp b/src/boost/libs/hana/test/pair/foldable.cpp
new file mode 100644
index 000000000..88dc68276
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/foldable.cpp
@@ -0,0 +1,31 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+#include <laws/foldable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_pair(ct_eq<1>{}, ct_eq<2>{}), f),
+ f(ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ hana::test::TestFoldable<hana::pair_tag>{hana::make_tuple(
+ hana::make_pair(ct_eq<3>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<3>{})
+ , hana::make_pair(ct_eq<4>{}, ct_eq<4>{})
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/issue_90.cpp b/src/boost/libs/hana/test/pair/issue_90.cpp
new file mode 100644
index 000000000..a46623e8c
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/issue_90.cpp
@@ -0,0 +1,43 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+template <typename T>
+T const& cref(T& t) { return t; }
+
+// a non-movable, non-copyable type
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+int main() {
+ // This test makes sure that we return the proper reference types from
+ // `first` and `second`.
+ hana::pair<RefOnly, RefOnly> p;
+
+ {
+ RefOnly&& r1 = hana::first(std::move(p));
+ RefOnly& r2 = hana::first(p);
+ RefOnly const& r3 = hana::first(cref(p));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ {
+ RefOnly&& r1 = hana::second(std::move(p));
+ RefOnly& r2 = hana::second(p);
+ RefOnly const& r3 = hana::second(cref(p));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/make.cpp b/src/boost/libs/hana/test/pair/make.cpp
new file mode 100644
index 000000000..3db5030a8
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/make.cpp
@@ -0,0 +1,57 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/core/make.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+namespace hana = boost::hana;
+
+
+struct MoveOnly {
+ int data_;
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+ MoveOnly(int data) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+};
+
+int main() {
+ {
+ hana::pair<int, short> p = hana::make_pair(3, 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == 4);
+ }
+
+ {
+ hana::pair<MoveOnly, short> p = hana::make_pair(MoveOnly{3}, 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == 4);
+ }
+
+ {
+ hana::pair<MoveOnly, short> p = hana::make_pair(3, 4);
+ BOOST_HANA_RUNTIME_CHECK(hana::first(p) == MoveOnly{3});
+ BOOST_HANA_RUNTIME_CHECK(hana::second(p) == 4);
+ }
+
+ {
+ constexpr hana::pair<int, short> p = hana::make_pair(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+
+ // equivalence with make<pair_tag>
+ {
+ constexpr hana::pair<int, short> p = hana::make<hana::pair_tag>(3, 4);
+ static_assert(hana::first(p) == 3, "");
+ static_assert(hana::second(p) == 4, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/pair/orderable.cpp b/src/boost/libs/hana/test/pair/orderable.cpp
new file mode 100644
index 000000000..fabd828d9
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/orderable.cpp
@@ -0,0 +1,46 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/greater.hpp>
+#include <boost/hana/greater_equal.hpp>
+#include <boost/hana/less.hpp>
+#include <boost/hana/less_equal.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/orderable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_ord;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{}) <
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{}) <=
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{}) >=
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{})
+ );
+
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::make_pair(ct_ord<3>{}, ct_ord<2>{}) >
+ hana::make_pair(ct_ord<1>{}, ct_ord<2>{})
+ );
+
+ hana::test::TestOrderable<hana::pair_tag>{hana::make_tuple(
+ hana::make_pair(ct_ord<3>{}, ct_ord<3>{})
+ , hana::make_pair(ct_ord<3>{}, ct_ord<4>{})
+ , hana::make_pair(ct_ord<4>{}, ct_ord<3>{})
+ , hana::make_pair(ct_ord<4>{}, ct_ord<4>{})
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/product.cpp b/src/boost/libs/hana/test/pair/product.cpp
new file mode 100644
index 000000000..b87f06ac6
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/product.cpp
@@ -0,0 +1,29 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/product.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ // first, second
+ {
+ hana::pair<ct_eq<1>, ct_eq<2>> p;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::first(p), ct_eq<1>{}));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(hana::second(p), ct_eq<2>{}));
+ }
+
+ hana::test::TestProduct<hana::pair_tag>{hana::make_tuple(
+ ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}
+ )};
+}
diff --git a/src/boost/libs/hana/test/pair/tag_of.cpp b/src/boost/libs/hana/test/pair/tag_of.cpp
new file mode 100644
index 000000000..285b892e8
--- /dev/null
+++ b/src/boost/libs/hana/test/pair/tag_of.cpp
@@ -0,0 +1,36 @@
+// Copyright Louis Dionne 2013-2016
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/ext/std/integral_constant.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/pair.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ struct T { }; struct U { };
+ static_assert(std::is_same<
+ hana::tag_of<hana::pair<T, U>>::type,
+ hana::pair_tag
+ >{}, "");
+ }
+
+ // Bug #1
+ {
+ using Pair = hana::pair<hana::integral_constant<int, 3>, int>;
+ using PairTag = hana::tag_of<Pair>::type;
+ using Tag = hana::tag_of<std::integral_constant<unsigned long, 0>>::type;
+ }
+
+ // Bug #2
+ {
+ using Pair = hana::pair<std::integral_constant<int, 3>, int>;
+ using PairTag = hana::tag_of<Pair>::type;
+ using Tag = hana::tag_of<std::integral_constant<unsigned long, 0>>::type;
+ }
+}