summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/tuple
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/tuple')
-rw-r--r--src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp19
-rw-r--r--src/boost/libs/hana/test/tuple/assign.convert_copy.cpp59
-rw-r--r--src/boost/libs/hana/test/tuple/assign.convert_move.cpp73
-rw-r--r--src/boost/libs/hana/test/tuple/assign.copy.cpp43
-rw-r--r--src/boost/libs/hana/test/tuple/assign.move.cpp58
-rw-r--r--src/boost/libs/hana/test/tuple/at.const.cpp50
-rw-r--r--src/boost/libs/hana/test/tuple/at.non_const.cpp81
-rw-r--r--src/boost/libs/hana/test/tuple/at.rv.cpp40
-rw-r--r--src/boost/libs/hana/test/tuple/auto/_specs.hpp15
-rw-r--r--src/boost/libs/hana/test/tuple/auto/all_of.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/any_of.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/ap.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/at.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/drop_back.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/drop_front.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/drop_while.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/for_each.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/group.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/index_if.cpp9
-rw-r--r--src/boost/libs/hana/test/tuple/auto/insert.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/insert_range.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/intersperse.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/is_empty.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/length.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/make.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/none_of.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/partition.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/permutations.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/remove_at.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/remove_range.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/reverse.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/scans.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/sequence.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/slice.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/sort.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/span.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/take_back.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/take_front.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/take_while.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/transform.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/unfolds.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/unique.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/auto/zips.cpp8
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp93
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.copy.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.default.cpp138
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.move.cpp73
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.nested.cpp19
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.trap.cpp120
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp19
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp125
-rw-r--r--src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp114
-rw-r--r--src/boost/libs/hana/test/tuple/empty_member.cpp33
-rw-r--r--src/boost/libs/hana/test/tuple/hold_refs.cpp78
-rw-r--r--src/boost/libs/hana/test/tuple/issue_90.cpp72
-rw-r--r--src/boost/libs/hana/test/tuple/laws.cpp43
-rw-r--r--src/boost/libs/hana/test/tuple/laws.functor.cpp64
-rw-r--r--src/boost/libs/hana/test/tuple/laws.searchable.cpp40
-rw-r--r--src/boost/libs/hana/test/tuple/move_only.cpp55
-rw-r--r--src/boost/libs/hana/test/tuple/pair_interop.cpp75
-rw-r--r--src/boost/libs/hana/test/tuple/smart_ptr.cpp23
-rw-r--r--src/boost/libs/hana/test/tuple/special.drop_front_exactly.cpp46
-rw-r--r--src/boost/libs/hana/test/tuple/special.empty.cpp25
-rw-r--r--src/boost/libs/hana/test/tuple/special.equal.cpp76
-rw-r--r--src/boost/libs/hana/test/tuple/special.fill.cpp36
-rw-r--r--src/boost/libs/hana/test/tuple/special.fold_left.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/special.fold_right.cpp68
-rw-r--r--src/boost/libs/hana/test/tuple/special.front.cpp46
-rw-r--r--src/boost/libs/hana/test/tuple/special.is_empty.cpp28
-rw-r--r--src/boost/libs/hana/test/tuple/special.prepend.cpp30
-rw-r--r--src/boost/libs/hana/test/tuple/special.transform.cpp52
-rw-r--r--src/boost/libs/hana/test/tuple/to.cpp18
-rw-r--r--src/boost/libs/hana/test/tuple/unpack.cpp89
-rw-r--r--src/boost/libs/hana/test/tuple/usability_of_types.cpp41
77 files changed, 2670 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp b/src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp
new file mode 100644
index 000000000..4e23874c0
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/any_of.clang_ice.cpp
@@ -0,0 +1,19 @@
+// 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/any_of.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+// This used to trigger an ICE on Clang
+
+struct Car { std::string name; };
+
+int main() {
+ auto stuff = hana::make_tuple(Car{}, Car{}, Car{});
+ hana::any_of(stuff, [](auto&&) { return true; });
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.convert_copy.cpp b/src/boost/libs/hana/test/tuple/assign.convert_copy.cpp
new file mode 100644
index 000000000..b4debb7a6
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.convert_copy.cpp
@@ -0,0 +1,59 @@
+// 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/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct B {
+ int id_;
+ explicit B(int i = 0) : id_(i) { }
+};
+
+struct D : B {
+ explicit D(int i = 0) : B(i) { }
+};
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1;
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1;
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1;
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ D d2(2);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d2);
+ T1 t1(1.5, 'b', d);
+ t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.convert_move.cpp b/src/boost/libs/hana/test/tuple/assign.convert_move.cpp
new file mode 100644
index 000000000..6a7a7943e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.convert_move.cpp
@@ -0,0 +1,73 @@
+// 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/tuple.hpp>
+
+#include <memory>
+#include <utility>
+namespace hana = boost::hana;
+
+
+struct B {
+ int id_;
+ explicit B(int i = 0) : id_(i) {}
+ virtual ~B() {}
+};
+
+struct D : B {
+ explicit D(int i) : B(i) {}
+};
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ D d2(2);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d2);
+ T1 t1(1.5, 'b', d);
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char, std::unique_ptr<D>>;
+ using T1 = hana::tuple<int, int, std::unique_ptr<B>>;
+ T0 t0(2.5, 'a', std::unique_ptr<D>(new D(3)));
+ T1 t1;
+ t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1)->id_ == 3);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.copy.cpp b/src/boost/libs/hana/test/tuple/assign.copy.cpp
new file mode 100644
index 000000000..dedc276a5
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.copy.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/assert.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t;
+ t = t0;
+ }
+ {
+ using T = hana::tuple<int>;
+ T t0(2);
+ T t;
+ t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::tuple<int, char>;
+ T t0(2, 'a');
+ T t;
+ t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ }
+ {
+ using T = hana::tuple<int, char, std::string>;
+ const T t0(2, 'a', "some text");
+ T t;
+ t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "some text");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/assign.move.cpp b/src/boost/libs/hana/test/tuple/assign.move.cpp
new file mode 100644
index 000000000..6dd776129
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/assign.move.cpp
@@ -0,0 +1,58 @@
+// 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/tuple.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; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t;
+ t = std::move(t0);
+ }
+ {
+ using T = hana::tuple<MoveOnly>;
+ T t0(MoveOnly(0));
+ T t;
+ t = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1));
+ T t;
+ t = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1), MoveOnly(2));
+ T t;
+ t = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/at.const.cpp b/src/boost/libs/hana/test/tuple/at.const.cpp
new file mode 100644
index 000000000..47d9b624c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/at.const.cpp
@@ -0,0 +1,50 @@
+// 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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty { };
+
+int main() {
+ {
+ using T = hana::tuple<int>;
+ const T t(3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 3);
+ }
+ {
+ using T = hana::tuple<std::string, int>;
+ const T t("high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 5);
+ }
+ {
+ using T = hana::tuple<double, int>;
+ constexpr T t(2.718, 5);
+ static_assert(hana::at_c<0>(t) == 2.718, "");
+ static_assert(hana::at_c<1>(t) == 5, "");
+ }
+ {
+ using T = hana::tuple<Empty>;
+ constexpr T t{Empty()};
+ constexpr Empty e = hana::at_c<0>(t); (void)e;
+ }
+ {
+ using T = hana::tuple<double&, std::string, int>;
+ double d = 1.5;
+ const T t(d, "high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 5);
+ hana::at_c<0>(t) = 2.5;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 5);
+ BOOST_HANA_RUNTIME_CHECK(d == 2.5);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/at.non_const.cpp b/src/boost/libs/hana/test/tuple/at.non_const.cpp
new file mode 100644
index 000000000..3e47c35d9
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/at.non_const.cpp
@@ -0,0 +1,81 @@
+// 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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty {};
+
+struct S {
+ constexpr S()
+ : a{1, Empty{}},
+ k(hana::at_c<0>(a)),
+ e(hana::at_c<1>(a))
+ { }
+
+ hana::tuple<int, Empty> a;
+ int k;
+ Empty e;
+};
+
+constexpr hana::tuple<int, int> getP () { return { 3, 4 }; }
+
+int main() {
+ {
+ using T = hana::tuple<int>;
+ T t(3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 3);
+ hana::at_c<0>(t) = 2;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::tuple<std::string, int>;
+ T t("high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 5);
+ hana::at_c<0>(t) = "four";
+ hana::at_c<1>(t) = 4;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == "four");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 4);
+ }
+ {
+ using T = hana::tuple<double&, std::string, int>;
+ double d = 1.5;
+ T t(d, "high", 5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "high");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 5);
+ hana::at_c<0>(t) = 2.5;
+ hana::at_c<1>(t) = "four";
+ hana::at_c<2>(t) = 4;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2.5);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == "four");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 4);
+ BOOST_HANA_RUNTIME_CHECK(d == 2.5);
+ }
+ // get on a rvalue tuple
+ {
+ static_assert(hana::at_c<0>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 0, "" );
+ static_assert(hana::at_c<1>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 1, "" );
+ static_assert(hana::at_c<2>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 2, "" );
+ static_assert(hana::at_c<3>(hana::tuple<float, int, double, long>{0.0f, 1, 2.0, 3L}) == 3, "" );
+ static_assert(S().k == 1, "");
+ static_assert(hana::at_c<1>(getP()) == 4, "");
+ }
+ {
+ // make sure get<> returns the right types
+ struct T { };
+ struct U { };
+ struct V { };
+
+ hana::tuple<T, U, V> xs{};
+ (void)static_cast<T>(hana::at_c<0>(xs));
+ (void)static_cast<U>(hana::at_c<1>(xs));
+ (void)static_cast<V>(hana::at_c<2>(xs));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/at.rv.cpp b/src/boost/libs/hana/test/tuple/at.rv.cpp
new file mode 100644
index 000000000..e1591609b
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/at.rv.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/tuple.hpp>
+
+#include <support/tracked.hpp>
+
+#include <utility>
+#include <memory>
+namespace hana = boost::hana;
+
+
+int main() {
+ {
+ using T = hana::tuple<std::unique_ptr<int>>;
+ T t(std::unique_ptr<int>(new int(3)));
+ std::unique_ptr<int> p = hana::at_c<0>(std::move(t));
+ BOOST_HANA_RUNTIME_CHECK(*p == 3);
+ }
+ // make sure we don't double-move and do other weird stuff
+ {
+ hana::tuple<Tracked, Tracked, Tracked> xs{
+ Tracked{1}, Tracked{2}, Tracked{3}
+ };
+
+ Tracked a = hana::at_c<0>(std::move(xs)); (void)a;
+ Tracked b = hana::at_c<1>(std::move(xs)); (void)b;
+ Tracked c = hana::at_c<2>(std::move(xs)); (void)c;
+ }
+ // test with nested closures
+ {
+ using Inner = hana::tuple<Tracked, Tracked>;
+ hana::tuple<Inner> xs{Inner{Tracked{1}, Tracked{2}}};
+
+ Tracked a = hana::at_c<0>(hana::at_c<0>(std::move(xs))); (void)a;
+ Tracked b = hana::at_c<1>(hana::at_c<0>(std::move(xs))); (void)b;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/auto/_specs.hpp b/src/boost/libs/hana/test/tuple/auto/_specs.hpp
new file mode 100644
index 000000000..0b957f4c8
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/_specs.hpp
@@ -0,0 +1,15 @@
+// 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)
+
+#ifndef BOOST_HANA_TEST_TUPLE_AUTO_SPECS_HPP
+#define BOOST_HANA_TEST_TUPLE_AUTO_SPECS_HPP
+
+#include <boost/hana/tuple.hpp>
+
+
+#define MAKE_TUPLE(...) ::boost::hana::make_tuple(__VA_ARGS__)
+#define TUPLE_TYPE(...) ::boost::hana::tuple<__VA_ARGS__>
+#define TUPLE_TAG ::boost::hana::tuple_tag
+
+#endif // !BOOST_HANA_TEST_TUPLE_AUTO_SPECS_HPP
diff --git a/src/boost/libs/hana/test/tuple/auto/all_of.cpp b/src/boost/libs/hana/test/tuple/auto/all_of.cpp
new file mode 100644
index 000000000..f3e974ffd
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/all_of.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/all_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/any_of.cpp b/src/boost/libs/hana/test/tuple/auto/any_of.cpp
new file mode 100644
index 000000000..3065d0175
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/any_of.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/any_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/ap.cpp b/src/boost/libs/hana/test/tuple/auto/ap.cpp
new file mode 100644
index 000000000..59c9cb757
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/ap.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/ap.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/at.cpp b/src/boost/libs/hana/test/tuple/auto/at.cpp
new file mode 100644
index 000000000..605265331
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/at.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp b/src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp
new file mode 100644
index 000000000..b0795e8d7
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/cartesian_product.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/cartesian_product.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/drop_back.cpp b/src/boost/libs/hana/test/tuple/auto/drop_back.cpp
new file mode 100644
index 000000000..b283844d6
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/drop_back.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/drop_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/drop_front.cpp b/src/boost/libs/hana/test/tuple/auto/drop_front.cpp
new file mode 100644
index 000000000..a39d6f450
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/drop_front.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/drop_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/drop_while.cpp b/src/boost/libs/hana/test/tuple/auto/drop_while.cpp
new file mode 100644
index 000000000..18907f033
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/drop_while.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/drop_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/for_each.cpp b/src/boost/libs/hana/test/tuple/auto/for_each.cpp
new file mode 100644
index 000000000..714fe03c0
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/for_each.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/for_each.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/group.cpp b/src/boost/libs/hana/test/tuple/auto/group.cpp
new file mode 100644
index 000000000..0669b496f
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/group.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/group.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/index_if.cpp b/src/boost/libs/hana/test/tuple/auto/index_if.cpp
new file mode 100644
index 000000000..ef37fe65a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/index_if.cpp
@@ -0,0 +1,9 @@
+// Copyright Louis Dionne 2013-2017
+// Copyright Jason Rice 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 "_specs.hpp"
+#include <auto/index_if.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/insert.cpp b/src/boost/libs/hana/test/tuple/auto/insert.cpp
new file mode 100644
index 000000000..e8efc6dc1
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/insert.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/insert.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/insert_range.cpp b/src/boost/libs/hana/test/tuple/auto/insert_range.cpp
new file mode 100644
index 000000000..05ac5774e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/insert_range.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/insert_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/intersperse.cpp b/src/boost/libs/hana/test/tuple/auto/intersperse.cpp
new file mode 100644
index 000000000..185c814a9
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/intersperse.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/intersperse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/is_empty.cpp b/src/boost/libs/hana/test/tuple/auto/is_empty.cpp
new file mode 100644
index 000000000..f175f7ddb
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/is_empty.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/is_empty.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/length.cpp b/src/boost/libs/hana/test/tuple/auto/length.cpp
new file mode 100644
index 000000000..55111dd60
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/length.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/length.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp b/src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp
new file mode 100644
index 000000000..4d2f3edf4
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/lexicographical_compare.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/lexicographical_compare.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/make.cpp b/src/boost/libs/hana/test/tuple/auto/make.cpp
new file mode 100644
index 000000000..f90514f16
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/make.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/make.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/none_of.cpp b/src/boost/libs/hana/test/tuple/auto/none_of.cpp
new file mode 100644
index 000000000..b56a27b47
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/none_of.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/none_of.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/partition.cpp b/src/boost/libs/hana/test/tuple/auto/partition.cpp
new file mode 100644
index 000000000..ba9621a6c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/partition.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/partition.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/permutations.cpp b/src/boost/libs/hana/test/tuple/auto/permutations.cpp
new file mode 100644
index 000000000..3c1a6e852
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/permutations.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/permutations.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/remove_at.cpp b/src/boost/libs/hana/test/tuple/auto/remove_at.cpp
new file mode 100644
index 000000000..5b7c5af47
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/remove_at.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/remove_at.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/remove_range.cpp b/src/boost/libs/hana/test/tuple/auto/remove_range.cpp
new file mode 100644
index 000000000..6d7c6e090
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/remove_range.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/remove_range.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/reverse.cpp b/src/boost/libs/hana/test/tuple/auto/reverse.cpp
new file mode 100644
index 000000000..342278df8
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/reverse.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/reverse.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/scans.cpp b/src/boost/libs/hana/test/tuple/auto/scans.cpp
new file mode 100644
index 000000000..36dd32437
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/scans.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/scans.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/sequence.cpp b/src/boost/libs/hana/test/tuple/auto/sequence.cpp
new file mode 100644
index 000000000..4ed01e852
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/sequence.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/sequence.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/slice.cpp b/src/boost/libs/hana/test/tuple/auto/slice.cpp
new file mode 100644
index 000000000..3e20df95f
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/slice.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/slice.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/sort.cpp b/src/boost/libs/hana/test/tuple/auto/sort.cpp
new file mode 100644
index 000000000..f639ddeb0
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/sort.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/sort.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/span.cpp b/src/boost/libs/hana/test/tuple/auto/span.cpp
new file mode 100644
index 000000000..297b7f174
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/span.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/span.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/take_back.cpp b/src/boost/libs/hana/test/tuple/auto/take_back.cpp
new file mode 100644
index 000000000..2a91d7d4d
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/take_back.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/take_back.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/take_front.cpp b/src/boost/libs/hana/test/tuple/auto/take_front.cpp
new file mode 100644
index 000000000..9a48d2b8c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/take_front.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/take_front.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/take_while.cpp b/src/boost/libs/hana/test/tuple/auto/take_while.cpp
new file mode 100644
index 000000000..e58c99aca
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/take_while.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/take_while.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/transform.cpp b/src/boost/libs/hana/test/tuple/auto/transform.cpp
new file mode 100644
index 000000000..306c1bc3c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/transform.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/transform.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/unfolds.cpp b/src/boost/libs/hana/test/tuple/auto/unfolds.cpp
new file mode 100644
index 000000000..f8bac9ddc
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/unfolds.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/unfolds.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/unique.cpp b/src/boost/libs/hana/test/tuple/auto/unique.cpp
new file mode 100644
index 000000000..9c1dc7155
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/unique.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/unique.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/auto/zips.cpp b/src/boost/libs/hana/test/tuple/auto/zips.cpp
new file mode 100644
index 000000000..32ec5cc8a
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/auto/zips.cpp
@@ -0,0 +1,8 @@
+// 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 "_specs.hpp"
+#include <auto/zips.hpp>
+
+int main() { }
diff --git a/src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp b/src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp
new file mode 100644
index 000000000..f8cb0d8de
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.convert_copy.cpp
@@ -0,0 +1,93 @@
+// 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/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct A {
+ int id_;
+ constexpr A(int i) : id_(i) {}
+ friend constexpr bool operator==(const A& x, const A& y)
+ { return x.id_ == y.id_; }
+};
+
+struct B {
+ int id_;
+ explicit B(int i) : id_(i) {}
+};
+
+struct C {
+ int id_;
+ constexpr explicit C(int i) : id_(i) {}
+ friend constexpr bool operator==(const C& x, const C& y)
+ { return x.id_ == y.id_; }
+};
+
+struct D : B {
+ explicit D(int i) : B(i) {}
+};
+
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<A>;
+ constexpr T0 t0(2.5);
+ constexpr T1 t1 = t0;
+ static_assert(hana::at_c<0>(t1) == 2, "");
+ }
+ {
+ using T0 = hana::tuple<int>;
+ using T1 = hana::tuple<C>;
+ constexpr T0 t0(2);
+ constexpr T1 t1{t0};
+ static_assert(hana::at_c<0>(t1) == C(2), "");
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1 = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d);
+ T1 t1 = t0;
+ d.id_ = 2;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char, int>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', 3);
+ T1 t1(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp b/src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp
new file mode 100644
index 000000000..f8274429e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.convert_move.cpp
@@ -0,0 +1,68 @@
+// 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/tuple.hpp>
+
+#include <string>
+#include <memory>
+namespace hana = boost::hana;
+
+
+struct B {
+ int id_;
+ explicit B(int i) : id_(i) {}
+ virtual ~B() {}
+};
+
+struct D : B {
+ explicit D(int i) : B(i) {}
+};
+
+int main() {
+ {
+ using T0 = hana::tuple<double>;
+ using T1 = hana::tuple<int>;
+ T0 t0(2.5);
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char>;
+ using T1 = hana::tuple<int, int>;
+ T0 t0(2.5, 'a');
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ }
+ {
+ using T0 = hana::tuple<double, char, D>;
+ using T1 = hana::tuple<int, int, B>;
+ T0 t0(2.5, 'a', D(3));
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 3);
+ }
+ {
+ D d(3);
+ using T0 = hana::tuple<double, char, D&>;
+ using T1 = hana::tuple<int, int, B&>;
+ T0 t0(2.5, 'a', d);
+ T1 t1 = std::move(t0);
+ d.id_ = 2;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1).id_ == 2);
+ }
+ {
+ using T0 = hana::tuple<double, char, std::unique_ptr<D>>;
+ using T1 = hana::tuple<int, int, std::unique_ptr<B>>;
+ T0 t0(2.5, 'a', std::unique_ptr<D>(new D(3)));
+ T1 t1 = std::move(t0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t1) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t1) == int('a'));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t1)->id_ == 3);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.copy.cpp b/src/boost/libs/hana/test/tuple/cnstr.copy.cpp
new file mode 100644
index 000000000..e0d8638f0
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.copy.cpp
@@ -0,0 +1,68 @@
+// 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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+struct Empty { };
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t_implicit = t0;
+ T t_explicit(t0);
+
+ (void)t_explicit;
+ (void)t_implicit;
+ }
+ {
+ using T = hana::tuple<int>;
+ T t0(2);
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ using T = hana::tuple<int, char>;
+ T t0(2, 'a');
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ }
+ {
+ using T = hana::tuple<int, char, std::string>;
+ const T t0(2, 'a', "some text");
+ T t = t0;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 'a');
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "some text");
+ }
+ {
+ using T = hana::tuple<int>;
+ constexpr T t0(2);
+ constexpr T t = t0;
+ static_assert(hana::at_c<0>(t) == 2, "");
+ }
+ {
+ using T = hana::tuple<Empty>;
+ constexpr T t0;
+ constexpr T t = t0;
+ constexpr Empty e = hana::at_c<0>(t); (void)e;
+ }
+ {
+ struct T { };
+ struct U { };
+
+ constexpr hana::tuple<T, U> binary{};
+ constexpr hana::tuple<T, U> copy_implicit = binary;
+ constexpr hana::tuple<T, U> copy_explicit(binary);
+
+ (void)copy_implicit;
+ (void)copy_explicit;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.default.cpp b/src/boost/libs/hana/test/tuple/cnstr.default.cpp
new file mode 100644
index 000000000..5d9af67a2
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.default.cpp
@@ -0,0 +1,138 @@
+// 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/tuple.hpp>
+
+#include <string>
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+struct DefaultOnly {
+ int data_;
+ DefaultOnly(DefaultOnly const&) = delete;
+ DefaultOnly& operator=(DefaultOnly const&) = delete;
+
+ static int count;
+
+ DefaultOnly() : data_(-1) { ++count; }
+ ~DefaultOnly() { data_ = 0; --count; }
+
+ friend bool operator==(DefaultOnly const& x, DefaultOnly const& y)
+ { return x.data_ == y.data_; }
+
+ friend bool operator< (DefaultOnly const& x, DefaultOnly const& y)
+ { return x.data_ < y.data_; }
+};
+
+int DefaultOnly::count = 0;
+
+struct NoDefault {
+ NoDefault() = delete;
+ explicit NoDefault(int) { }
+};
+
+struct IllFormedDefault {
+ IllFormedDefault(int x) : value(x) {}
+ template <bool Pred = false>
+ constexpr IllFormedDefault() {
+ static_assert(Pred,
+ "The default constructor should not be instantiated");
+ }
+ int value;
+};
+
+int main() {
+ {
+ hana::tuple<> t; (void)t;
+ }
+ {
+ hana::tuple<int> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ hana::tuple<int, char*> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ }
+ {
+ hana::tuple<int, char*, std::string> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
+ }
+ {
+ hana::tuple<int, char*, std::string, DefaultOnly> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == DefaultOnly());
+ }
+ {
+ // See LLVM bug #21157.
+ static_assert(!std::is_default_constructible<
+ hana::tuple<NoDefault>
+ >(), "");
+ static_assert(!std::is_default_constructible<
+ hana::tuple<DefaultOnly, NoDefault>
+ >(), "");
+ static_assert(!std::is_default_constructible<
+ hana::tuple<NoDefault, DefaultOnly, NoDefault>
+ >(), "");
+ }
+ {
+ struct T { };
+ struct U { };
+ struct V { };
+
+ constexpr hana::tuple<> z0; (void)z0;
+ constexpr hana::tuple<T> z1; (void)z1;
+ constexpr hana::tuple<T, U> z2; (void)z2;
+ constexpr hana::tuple<T, U, V> z3; (void)z3;
+ }
+ {
+ constexpr hana::tuple<int> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ constexpr hana::tuple<int, char*> t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ }
+
+ // Make sure we can hold non default-constructible elements, and that
+ // it does not trigger an error in the default constructor.
+ {
+ {
+ IllFormedDefault v(0);
+ hana::tuple<IllFormedDefault> t1(v);
+ hana::tuple<IllFormedDefault> t2{v};
+ hana::tuple<IllFormedDefault> t3 = {v};
+ (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
+ }
+ {
+ hana::tuple<NoDefault> t1(0);
+ hana::tuple<NoDefault> t2{0};
+ hana::tuple<NoDefault> t3 = {0};
+ (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
+ }
+ {
+ NoDefault v(0);
+ hana::tuple<NoDefault> t1(v);
+ hana::tuple<NoDefault> t2{v};
+ hana::tuple<NoDefault> t3 = {v};
+ (void)t1;(void)t2;(void)t3; // remove spurious unused variable warning on GCC
+ }
+ }
+
+ // Make sure a tuple_t can be default-constructed
+ {
+ struct T;
+ struct U;
+
+ using Types = decltype(hana::tuple_t<T, U>);
+ Types t{}; (void)t;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.move.cpp b/src/boost/libs/hana/test/tuple/cnstr.move.cpp
new file mode 100644
index 000000000..c9644cbad
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.move.cpp
@@ -0,0 +1,73 @@
+// 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/tuple.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 = 1) : data_(data) { }
+ MoveOnly(MoveOnly&& x) : data_(x.data_) { x.data_ = 0; }
+
+ MoveOnly& operator=(MoveOnly&& x)
+ { data_ = x.data_; x.data_ = 0; return *this; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+int main() {
+ {
+ using T = hana::tuple<>;
+ T t0;
+ T t = std::move(t0); (void)t;
+ }
+ {
+ using T = hana::tuple<MoveOnly>;
+ T t0(MoveOnly(0));
+ T t = std::move(t0); (void)t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1));
+ T t = std::move(t0); (void)t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ }
+ {
+ using T = hana::tuple<MoveOnly, MoveOnly, MoveOnly>;
+ T t0(MoveOnly(0), MoveOnly(1), MoveOnly(2));
+ T t = std::move(t0); (void)t;
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ }
+ {
+ // Check for SFINAE-friendliness
+ static_assert(!std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly const&
+ >{}, "");
+
+ static_assert(!std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly&
+ >{}, "");
+
+ static_assert(std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly
+ >{}, "");
+
+ static_assert(std::is_constructible<
+ hana::tuple<MoveOnly>, MoveOnly&&
+ >{}, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.nested.cpp b/src/boost/libs/hana/test/tuple/cnstr.nested.cpp
new file mode 100644
index 000000000..7cbdb5da6
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.nested.cpp
@@ -0,0 +1,19 @@
+// 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/tuple.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// See this bug: https://llvm.org/bugs/show_bug.cgi?id=24173
+
+template <typename ...Xs>
+constexpr hana::tuple<std::decay_t<Xs>...> f(Xs&& ...xs)
+{ return hana::tuple<std::decay_t<Xs>...>{static_cast<Xs&&>(xs)...}; }
+
+int main() {
+ f(f(f(f(f(f(f(f(f(f(f(f(1))))))))))));
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.trap.cpp b/src/boost/libs/hana/test/tuple/cnstr.trap.cpp
new file mode 100644
index 000000000..a088b9466
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.trap.cpp
@@ -0,0 +1,120 @@
+// 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/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// Make sure that the tuple(Yn&&...) is not preferred over copy constructors
+// in single-element cases and other similar cases.
+
+struct Trap1 {
+ Trap1() = default;
+ Trap1(Trap1 const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap1(Trap1&) = default;
+#endif
+ Trap1(Trap1&&) = default;
+
+ template <typename X>
+ Trap1(X&&) {
+ static_assert(sizeof(X) && false,
+ "this constructor must not be instantiated");
+ }
+};
+
+struct Trap2 {
+ Trap2() = default;
+ Trap2(Trap2 const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap2(Trap2&) = default;
+#endif
+ Trap2(Trap2&&) = default;
+
+ template <typename X>
+ Trap2(X) { // not by reference
+ static_assert(sizeof(X) && false,
+ "this constructor must not be instantiated");
+ }
+};
+
+struct Trap3 {
+ Trap3() = default;
+ Trap3(Trap3 const&) = default;
+#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
+ Trap3(Trap3&) = default;
+#endif
+ Trap3(Trap3&&) = default;
+
+ template <typename X>
+ constexpr explicit Trap3(X&&) { // explicit, and constexpr
+ static_assert(sizeof(X) && false,
+ "this constructor must not be instantiated");
+ }
+};
+
+struct Trap4 {
+ Trap4() = default;
+ template <typename Args>
+ constexpr explicit Trap4(Args&&) {
+ static_assert(sizeof(Args) && false, "must never be instantiated");
+ }
+
+ Trap4(Trap4 const&) = default;
+ Trap4(Trap4&&) = default;
+};
+
+int main() {
+ {
+ hana::tuple<Trap1> tuple{};
+ hana::tuple<Trap1> implicit_copy = tuple;
+ hana::tuple<Trap1> explicit_copy(tuple);
+ hana::tuple<Trap1> implicit_move = std::move(tuple);
+ hana::tuple<Trap1> explicit_move(std::move(tuple));
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+
+ {
+ hana::tuple<Trap2> tuple{};
+ hana::tuple<Trap2> implicit_copy = tuple;
+ hana::tuple<Trap2> explicit_copy(tuple);
+ hana::tuple<Trap2> implicit_move = std::move(tuple);
+ hana::tuple<Trap2> explicit_move(std::move(tuple));
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+
+ {
+ hana::tuple<Trap3> tuple{};
+ hana::tuple<Trap3> implicit_copy = tuple;
+ hana::tuple<Trap3> explicit_copy(tuple);
+ hana::tuple<Trap3> implicit_move = std::move(tuple);
+ hana::tuple<Trap3> explicit_move(std::move(tuple));
+
+ (void)implicit_copy;
+ (void)explicit_copy;
+ (void)implicit_move;
+ (void)explicit_move;
+ }
+
+ // Just defining the structure used to cause a failure, because of the
+ // explicitly defaulted copy-constructor.
+ {
+ struct Foo {
+ Foo() = default;
+ Foo(Foo const&) = default;
+ Foo(Foo&&) = default;
+ hana::tuple<Trap4> t;
+ };
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp b/src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp
new file mode 100644
index 000000000..02338b959
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.variadic_array.cpp
@@ -0,0 +1,19 @@
+// 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/tuple.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+//
+// This test checks that we can NOT construct a tuple holding array members,
+// per the standard.
+//
+
+int main() {
+ static_assert(!std::is_constructible<hana::tuple<int[3]>, int[3]>{}, "");
+ static_assert(!std::is_constructible<hana::tuple<int[3], float[4]>, int[3], float[4]>{}, "");
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp b/src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp
new file mode 100644
index 000000000..44f9f4b8e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.variadic_copy.cpp
@@ -0,0 +1,125 @@
+// 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/tuple.hpp>
+
+#include <string>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct never { static constexpr bool value = false; };
+
+struct NoValueCtor {
+ NoValueCtor() : id(++count) {}
+ NoValueCtor(NoValueCtor const & other) : id(other.id) { ++count; }
+
+ // The constexpr is required to make is_constructible instantiate this
+ // template. The explicit is needed to test-around a similar bug with
+ // is_convertible.
+ template <typename T>
+ constexpr explicit NoValueCtor(T)
+ { static_assert(never<T>::value, "This should not be instantiated"); }
+
+ static int count;
+ int id;
+};
+
+int NoValueCtor::count = 0;
+
+
+struct NoValueCtorEmpty {
+ NoValueCtorEmpty() {}
+ NoValueCtorEmpty(NoValueCtorEmpty const &) {}
+
+ template <typename T>
+ constexpr explicit NoValueCtorEmpty(T)
+ { static_assert(never<T>::value, "This should not be instantiated"); }
+};
+
+int main() {
+ {
+ hana::tuple<int> t(2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ }
+ {
+ constexpr hana::tuple<int> t(2);
+ static_assert(hana::at_c<0>(t) == 2, "");
+ }
+ {
+ constexpr hana::tuple<int> t;
+ static_assert(hana::at_c<0>(t) == 0, "");
+ }
+ {
+ constexpr hana::tuple<int, char*> t(2, nullptr);
+ static_assert(hana::at_c<0>(t) == 2, "");
+ static_assert(hana::at_c<1>(t) == nullptr, "");
+ }
+ {
+ hana::tuple<int, char*> t(2, nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ }
+ {
+ hana::tuple<int, char*, std::string> t(2, nullptr, "text");
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == nullptr);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == "text");
+ }
+ {
+ hana::tuple<int, NoValueCtor, int, int> t(1, NoValueCtor(), 2, 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t).id == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == 3);
+ }
+ {
+ hana::tuple<int, NoValueCtorEmpty, int, int> t(1, NoValueCtorEmpty(), 2, 3);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<3>(t) == 3);
+ }
+ {
+ struct T { };
+ struct U { };
+ struct V { };
+
+ constexpr T t{};
+ constexpr U u{};
+ constexpr V v{};
+
+ constexpr hana::tuple<T> x1{t}; (void)x1;
+ constexpr hana::tuple<T, U> x2{t, u}; (void)x2;
+ constexpr hana::tuple<T, U, V> x3{t, u, v}; (void)x3;
+ }
+ {
+ struct T { };
+ struct U { };
+ struct V { };
+
+ // Check for SFINAE-friendliness
+ static_assert(!std::is_constructible<
+ hana::tuple<T, U>, T
+ >{}, "");
+
+ static_assert(!std::is_constructible<
+ hana::tuple<T, U>, U, T
+ >{}, "");
+
+ static_assert(!std::is_constructible<
+ hana::tuple<T, U>, T, U, V
+ >{}, "");
+ }
+
+ // Make sure we can initialize elements with the brace-init syntax.
+ {
+ struct Member { };
+ struct Element { Member member; };
+
+ hana::tuple<Element, Element> xs{{Member()}, {Member()}};
+ hana::tuple<Element, Element> ys = {{Member()}, {Member()}};
+ (void)xs; (void)ys;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp b/src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp
new file mode 100644
index 000000000..dc69ba738
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/cnstr.variadic_forward.cpp
@@ -0,0 +1,114 @@
+// 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/tuple.hpp>
+
+#include <type_traits>
+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; }
+
+ int get() const {return data_;}
+ bool operator==(const MoveOnly& x) const { return data_ == x.data_; }
+ bool operator< (const MoveOnly& x) const { return data_ < x.data_; }
+};
+
+struct Empty { };
+struct A {
+ int id_;
+ explicit constexpr A(int i) : id_(i) {}
+};
+
+struct NoDefault { NoDefault() = delete; };
+
+int main() {
+ {
+ hana::tuple<MoveOnly> t(MoveOnly(0));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ }
+ {
+ hana::tuple<MoveOnly, MoveOnly> t(MoveOnly(0), MoveOnly(1));
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ }
+ {
+ hana::tuple<MoveOnly, MoveOnly, MoveOnly> t(
+ MoveOnly(0), MoveOnly(1), MoveOnly(2)
+ );
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(t) == 0);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(t) == 1);
+ BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(t) == 2);
+ }
+ {
+ constexpr hana::tuple<Empty> t0{Empty()}; (void)t0;
+ }
+ {
+ constexpr hana::tuple<A, A> t(3, 2);
+ static_assert(hana::at_c<0>(t).id_ == 3, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, NoDefault> Tuple;
+
+ static_assert(!std::is_constructible<
+ Tuple,
+ MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ Tuple,
+ MoveOnly, NoDefault
+ >::value, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
+
+ static_assert(!std::is_constructible<
+ Tuple,
+ MoveOnly, MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ Tuple,
+ MoveOnly, MoveOnly, NoDefault
+ >::value, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, NoDefault> Tuple;
+ typedef hana::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+ static_assert(!std::is_constructible<
+ NestedTuple,
+ MoveOnly, MoveOnly, MoveOnly, MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ NestedTuple,
+ MoveOnly, Tuple, MoveOnly, MoveOnly
+ >::value, "");
+ }
+ {
+ typedef hana::tuple<MoveOnly, int> Tuple;
+ typedef hana::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+ static_assert(!std::is_constructible<
+ NestedTuple,
+ MoveOnly, MoveOnly, MoveOnly, MoveOnly
+ >::value, "");
+
+ static_assert(std::is_constructible<
+ NestedTuple,
+ MoveOnly, Tuple, MoveOnly, MoveOnly
+ >::value, "");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/empty_member.cpp b/src/boost/libs/hana/test/tuple/empty_member.cpp
new file mode 100644
index 000000000..1bab83185
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/empty_member.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/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct A { };
+struct B { };
+
+int main() {
+ {
+ using T = hana::tuple<int, A>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<A, int>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<A, int, B>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<A, B, int>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+ {
+ using T = hana::tuple<int, A, B>;
+ static_assert(sizeof(T) == sizeof(int), "");
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/hold_refs.cpp b/src/boost/libs/hana/test/tuple/hold_refs.cpp
new file mode 100644
index 000000000..fb900194e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/hold_refs.cpp
@@ -0,0 +1,78 @@
+// 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/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// a non-movable, non-copyable type
+struct RefOnly {
+ RefOnly() = default;
+ RefOnly(RefOnly const&) = delete;
+ RefOnly(RefOnly&&) = delete;
+};
+
+struct Empty { };
+
+int main() {
+ // Make sure we can create a tuple of rvalue references
+ {
+ RefOnly e{};
+ hana::tuple<RefOnly&&> xs{std::move(e)};
+ hana::tuple<RefOnly&&, RefOnly&&> ys{std::move(e), std::move(e)};
+ (void)xs; (void)ys;
+
+ hana::tuple<RefOnly&&> xs2 = {std::move(e)};
+ hana::tuple<RefOnly&&, RefOnly&&> ys2 = {std::move(e), std::move(e)};
+ (void)xs2; (void)ys2;
+ }
+
+ // Make sure we can create a tuple of non-const lvalue references
+ {
+ RefOnly e{};
+ hana::tuple<RefOnly&> xs{e};
+ hana::tuple<RefOnly&, RefOnly&> ys{e, e};
+ (void)xs; (void)ys;
+
+ hana::tuple<RefOnly&> xs2 = {e};
+ hana::tuple<RefOnly&, RefOnly&> ys2 = {e, e};
+ (void)xs2; (void)ys2;
+ }
+
+ // Make sure we can create a tuple of const lvalue references
+ {
+ RefOnly const e{};
+ hana::tuple<RefOnly const&> xs{e};
+ hana::tuple<RefOnly const&, RefOnly const&> ys{e, e};
+ (void)xs; (void)ys;
+
+ hana::tuple<RefOnly const&> xs2 = {e};
+ hana::tuple<RefOnly const&, RefOnly const&> ys2 = {e, e};
+ (void)xs2; (void)ys2;
+ }
+
+ // Try to construct tuples with mixed references and non-reference members.
+ {
+ RefOnly r{};
+ Empty e{};
+
+ {
+ hana::tuple<RefOnly const&, Empty> xs{r, e};
+ hana::tuple<RefOnly const&, Empty> ys = {r, e};
+ (void)xs; (void)ys;
+ }
+ {
+ hana::tuple<RefOnly&, Empty> xs{r, e};
+ hana::tuple<RefOnly&, Empty> ys = {r, e};
+ (void)xs; (void)ys;
+ }
+ {
+ hana::tuple<RefOnly&&, Empty> xs{std::move(r), e};
+ hana::tuple<RefOnly&&, Empty> ys = {std::move(r), e};
+ (void)xs; (void)ys;
+ }
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/issue_90.cpp b/src/boost/libs/hana/test/tuple/issue_90.cpp
new file mode 100644
index 000000000..ab78440d0
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/issue_90.cpp
@@ -0,0 +1,72 @@
+// 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/at.hpp>
+#include <boost/hana/at_key.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.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;
+};
+
+template <int i>
+struct RefOnly_i : hana::int_<i> {
+ RefOnly_i() = default;
+ RefOnly_i(RefOnly_i const&) = delete;
+ RefOnly_i(RefOnly_i&&) = delete;
+};
+
+int main() {
+ hana::tuple<RefOnly> t;
+
+ // Make sure that we return the proper reference types from `at`.
+ {
+ RefOnly&& r1 = hana::at_c<0>(std::move(t));
+ RefOnly& r2 = hana::at_c<0>(t);
+ RefOnly const& r3 = hana::at_c<0>(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `front`.
+ {
+ RefOnly&& r1 = hana::front(std::move(t));
+ RefOnly& r2 = hana::front(t);
+ RefOnly const& r3 = hana::front(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `back`.
+ {
+ RefOnly&& r1 = hana::back(std::move(t));
+ RefOnly& r2 = hana::back(t);
+ RefOnly const& r3 = hana::back(cref(t));
+
+ (void)r1; (void)r2; (void)r3;
+ }
+
+ // Make sure we return the proper reference types from `at_key`.
+ {
+ hana::tuple<RefOnly_i<3>> t{};
+ RefOnly_i<3>& r1 = hana::at_key(t, RefOnly_i<3>{});
+ RefOnly_i<3> const& r2 = hana::at_key(cref(t), RefOnly_i<3>{});
+ RefOnly_i<3>&& r3 = hana::at_key(std::move(t), RefOnly_i<3>{});
+
+ (void)r1; (void)r2; (void)r3;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/laws.cpp b/src/boost/libs/hana/test/tuple/laws.cpp
new file mode 100644
index 000000000..fc79fe9af
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/laws.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/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/comparable.hpp>
+#include <laws/foldable.hpp>
+#include <laws/iterable.hpp>
+#include <laws/orderable.hpp>
+#include <laws/sequence.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+using hana::test::ct_ord;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_eq<0>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ );
+
+ auto ord_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_ord<0>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{})
+ , hana::make_tuple(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{}, ct_ord<4>{})
+ );
+
+ hana::test::TestComparable<hana::tuple_tag>{eq_tuples};
+ hana::test::TestOrderable<hana::tuple_tag>{ord_tuples};
+ hana::test::TestFoldable<hana::tuple_tag>{eq_tuples};
+ hana::test::TestIterable<hana::tuple_tag>{eq_tuples};
+ hana::test::TestSequence<hana::tuple_tag>{};
+}
diff --git a/src/boost/libs/hana/test/tuple/laws.functor.cpp b/src/boost/libs/hana/test/tuple/laws.functor.cpp
new file mode 100644
index 000000000..7a72d2d56
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/laws.functor.cpp
@@ -0,0 +1,64 @@
+// 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/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/applicative.hpp>
+#include <laws/base.hpp>
+#include <laws/functor.hpp>
+#include <laws/monad.hpp>
+#include <laws/monad_plus.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_eq<0>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
+ );
+
+ auto eq_values = hana::make_tuple(
+ ct_eq<0>{},
+ ct_eq<2>{},
+ ct_eq<4>{}
+ );
+
+ auto predicates = hana::make_tuple(
+ hana::equal.to(ct_eq<0>{}),
+ hana::equal.to(ct_eq<2>{}),
+ hana::equal.to(ct_eq<4>{}),
+ hana::always(hana::true_c),
+ hana::always(hana::false_c)
+ );
+
+ auto nested_eqs = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(
+ hana::make_tuple(ct_eq<0>{})
+ )
+ , hana::make_tuple(
+ hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{})
+ )
+ , hana::make_tuple(
+ hana::make_tuple(ct_eq<0>{}),
+ hana::make_tuple(ct_eq<1>{}, ct_eq<2>{}),
+ hana::make_tuple(ct_eq<3>{}, ct_eq<4>{})
+ )
+ );
+
+ hana::test::TestFunctor<hana::tuple_tag>{eq_tuples, eq_values};
+ hana::test::TestApplicative<hana::tuple_tag>{eq_tuples};
+ hana::test::TestMonad<hana::tuple_tag>{eq_tuples, nested_eqs};
+ hana::test::TestMonadPlus<hana::tuple_tag>{eq_tuples, predicates, eq_values};
+}
diff --git a/src/boost/libs/hana/test/tuple/laws.searchable.cpp b/src/boost/libs/hana/test/tuple/laws.searchable.cpp
new file mode 100644
index 000000000..6aa096899
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/laws.searchable.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/bool.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <laws/base.hpp>
+#include <laws/searchable.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+int main() {
+ auto eq_tuples = hana::make_tuple(
+ hana::make_tuple()
+ , hana::make_tuple(ct_eq<0>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
+ , hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{})
+ );
+ hana::test::TestSearchable<hana::tuple_tag>{
+ eq_tuples,
+ hana::make_tuple(ct_eq<3>{}, ct_eq<5>{})
+ };
+
+ auto bool_tuples = hana::make_tuple(
+ hana::make_tuple(hana::true_c)
+ , hana::make_tuple(hana::false_c)
+ , hana::make_tuple(hana::true_c, hana::true_c)
+ , hana::make_tuple(hana::true_c, hana::false_c)
+ , hana::make_tuple(hana::false_c, hana::true_c)
+ , hana::make_tuple(hana::false_c, hana::false_c)
+ );
+ hana::test::TestSearchable<hana::tuple_tag>{
+ bool_tuples,
+ hana::make_tuple(hana::true_c, hana::false_c)
+ };
+}
diff --git a/src/boost/libs/hana/test/tuple/move_only.cpp b/src/boost/libs/hana/test/tuple/move_only.cpp
new file mode 100644
index 000000000..3f78316cc
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/move_only.cpp
@@ -0,0 +1,55 @@
+// 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/at.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/tuple.hpp>
+
+#include <utility>
+namespace hana = boost::hana;
+
+
+// This test checks for move-only friendliness and reference semantics.
+
+struct MoveOnly {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly&&) = default;
+ MoveOnly& operator=(MoveOnly&&) = default;
+
+ MoveOnly(MoveOnly const&) = delete;
+ MoveOnly& operator=(MoveOnly const&) = delete;
+};
+
+int main() {
+ {
+ auto xs = hana::make_tuple(MoveOnly{});
+ auto by_val = [](auto) { };
+
+ by_val(std::move(xs));
+ by_val(hana::front(std::move(xs)));
+ by_val(hana::at_c<0>(std::move(xs)));
+ by_val(hana::back(std::move(xs)));
+ }
+
+ {
+ auto const& xs = hana::make_tuple(MoveOnly{});
+ auto by_const_ref = [](auto const&) { };
+
+ by_const_ref(xs);
+ by_const_ref(hana::front(xs));
+ by_const_ref(hana::at_c<0>(xs));
+ by_const_ref(hana::back(xs));
+ }
+
+ {
+ auto xs = hana::make_tuple(MoveOnly{});
+ auto by_ref = [](auto&) { };
+
+ by_ref(xs);
+ by_ref(hana::front(xs));
+ by_ref(hana::at_c<0>(xs));
+ by_ref(hana::back(xs));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/pair_interop.cpp b/src/boost/libs/hana/test/tuple/pair_interop.cpp
new file mode 100644
index 000000000..1e079f437
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/pair_interop.cpp
@@ -0,0 +1,75 @@
+// 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/at.hpp>
+#include <boost/hana/first.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/second.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+// This test makes sure that tuples containing pairs behave properly. It is
+// useful to test this specific case because tuple and pair (may) share a lot
+// of implementation details (for EBO), and that can easily lead to subtle bugs.
+// For example, if both pair and tuple inherit from similar base classes for
+// EBO, accessing a tuple of pairs or a pair of tuples (which requires some
+// base class casting magic) can lead to ambiguous overloads.
+
+int main() {
+ struct empty1 { };
+ struct empty2 { };
+
+ {
+ hana::tuple<hana::pair<empty1, empty2>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+ {
+ hana::tuple<hana::pair<int, empty2>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+ {
+ hana::tuple<hana::pair<int, int>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+ {
+ hana::tuple<hana::pair<empty1, int>> t{};
+ hana::first(hana::at_c<0>(t));
+ hana::second(hana::at_c<0>(t));
+ }
+
+ {
+ hana::pair<hana::tuple<>, hana::tuple<>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<int>, hana::tuple<int>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<>, hana::tuple<int>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<empty1>, hana::tuple<empty2>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<empty1, empty2>, hana::tuple<empty2>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+ {
+ hana::pair<hana::tuple<empty1, empty2>, hana::tuple<empty1, empty2>> p{};
+ hana::first(p);
+ hana::second(p);
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/smart_ptr.cpp b/src/boost/libs/hana/test/tuple/smart_ptr.cpp
new file mode 100644
index 000000000..aea7dc857
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/smart_ptr.cpp
@@ -0,0 +1,23 @@
+// 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/tuple.hpp>
+
+#include <memory>
+namespace hana = boost::hana;
+
+
+// Tuples of smart pointers; based on LLVM bug #18350
+int main() {
+ {
+ hana::tuple<std::unique_ptr<char>> up;
+ hana::tuple<std::shared_ptr<char>> sp;
+ hana::tuple<std::weak_ptr <char>> wp;
+ }
+ {
+ hana::tuple<std::unique_ptr<char[]>> up;
+ hana::tuple<std::shared_ptr<char[]>> sp;
+ hana::tuple<std::weak_ptr <char[]>> wp;
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/special.drop_front_exactly.cpp b/src/boost/libs/hana/test/tuple/special.drop_front_exactly.cpp
new file mode 100644
index 000000000..1092c5216
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.drop_front_exactly.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/drop_front_exactly.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_t<x0>),
+ hana::tuple_t<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_t<x0, x1>),
+ hana::tuple_t<x1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_t<x0, x1, x2>),
+ hana::tuple_t<x1, x2>
+ ));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_c<int, 0>),
+ hana::tuple_c<int>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_c<int, 0, 1>),
+ hana::tuple_c<int, 1>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::drop_front_exactly(hana::tuple_c<int, 0, 1, 2>),
+ hana::tuple_c<int, 1, 2>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.empty.cpp b/src/boost/libs/hana/test/tuple/special.empty.cpp
new file mode 100644
index 000000000..2cbb36d31
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.empty.cpp
@@ -0,0 +1,25 @@
+// 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/empty.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::tuple_tag>(),
+ hana::tuple_c<int>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::tuple_tag>(),
+ hana::tuple_c<long>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::empty<hana::tuple_tag>(),
+ hana::tuple_c<void>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.equal.cpp b/src/boost/libs/hana/test/tuple/special.equal.cpp
new file mode 100644
index 000000000..27694f2bc
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.equal.cpp
@@ -0,0 +1,76 @@
+// 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/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<>,
+ hana::tuple_t<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<x0>,
+ hana::tuple_t<>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<>,
+ hana::tuple_t<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<x0>,
+ hana::tuple_t<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<x0, x1>,
+ hana::tuple_t<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_t<x0>,
+ hana::tuple_t<x0, x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<x0, x1>,
+ hana::tuple_t<x0, x1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_t<x0, x1, x2>,
+ hana::tuple_t<x0, x1, x2>
+ ));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int>,
+ hana::tuple_c<int>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_c<int, 0>,
+ hana::tuple_c<int>
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int, 0>,
+ hana::tuple_c<int, 0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ hana::tuple_c<int, 0, 1>,
+ hana::tuple_c<int, 0>
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int, 0, 1>,
+ hana::tuple_c<int, 0, 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::tuple_c<int, 0, 1, 2>,
+ hana::tuple_c<int, 0, 1, 2>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.fill.cpp b/src/boost/libs/hana/test/tuple/special.fill.cpp
new file mode 100644
index 000000000..d764083fb
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.fill.cpp
@@ -0,0 +1,36 @@
+// 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/fill.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct x1;
+struct x2;
+struct x3;
+struct z;
+
+int main() {
+ // fill a tuple_t with a hana::type
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<>, hana::type_c<z>),
+ hana::tuple_t<>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<x1>, hana::type_c<z>),
+ hana::tuple_t<z>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<x1, x2>, hana::type_c<z>),
+ hana::tuple_t<z, z>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fill(hana::tuple_t<x1, x2, x3>, hana::type_c<z>),
+ hana::tuple_t<z, z, z>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.fold_left.cpp b/src/boost/libs/hana/test/tuple/special.fold_left.cpp
new file mode 100644
index 000000000..cf121ebb8
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.fold_left.cpp
@@ -0,0 +1,68 @@
+// 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/fold_left.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x0;
+struct x1;
+struct x2;
+struct x3;
+
+int main() {
+ // tuple_t and initial state
+ {
+ auto f = hana::metafunction<F>;
+ auto s = hana::type_c<struct initial_state>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<>, s, f),
+ s
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0>, s, f),
+ f(s, hana::type_c<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1>, s, f),
+ f(f(s, hana::type_c<x0>), hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2>, s, f),
+ f(f(f(s, hana::type_c<x0>), hana::type_c<x1>), hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2, x3>, s, f),
+ f(f(f(f(s, hana::type_c<x0>), hana::type_c<x1>), hana::type_c<x2>), hana::type_c<x3>)
+ ));
+ }
+
+ // tuple_t and no initial state
+ {
+ auto f = hana::metafunction<F>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0>, f),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2>, f),
+ f(f(hana::type_c<x0>, hana::type_c<x1>), hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_left(hana::tuple_t<x0, x1, x2, x3>, f),
+ f(f(f(hana::type_c<x0>, hana::type_c<x1>), hana::type_c<x2>), hana::type_c<x3>)
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/special.fold_right.cpp b/src/boost/libs/hana/test/tuple/special.fold_right.cpp
new file mode 100644
index 000000000..a78d40ed3
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.fold_right.cpp
@@ -0,0 +1,68 @@
+// 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/fold_right.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x0;
+struct x1;
+struct x2;
+struct x3;
+
+int main() {
+ // tuple_t and an initial state
+ {
+ auto f = hana::metafunction<F>;
+ auto s = hana::type_c<struct initial_state>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<>, s, f),
+ s
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0>, s, f),
+ f(hana::type_c<x0>, s)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1>, s, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, s))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2>, s, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, f(hana::type_c<x2>, s)))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2, x3>, s, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, f(hana::type_c<x2>, f(hana::type_c<x3>, s))))
+ ));
+ }
+
+ // tuple_t and no initial state
+ {
+ auto f = hana::metafunction<F>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0>, f),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2>, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, hana::type_c<x2>))
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::fold_right(hana::tuple_t<x0, x1, x2, x3>, f),
+ f(hana::type_c<x0>, f(hana::type_c<x1>, f(hana::type_c<x2>, hana::type_c<x3>)))
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/test/tuple/special.front.cpp b/src/boost/libs/hana/test/tuple/special.front.cpp
new file mode 100644
index 000000000..9dc712d5c
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.front.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/equal.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_t<x0>),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_t<x0, x1>),
+ hana::type_c<x0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_t<x0, x1, x2>),
+ hana::type_c<x0>
+ ));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_c<int, 0>),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_c<int, 0, 1>),
+ hana::int_c<0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::front(hana::tuple_c<int, 0, 1, 2>),
+ hana::int_c<0>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.is_empty.cpp b/src/boost/libs/hana/test/tuple/special.is_empty.cpp
new file mode 100644
index 000000000..3bf0cf780
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.is_empty.cpp
@@ -0,0 +1,28 @@
+// 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/is_empty.hpp>
+#include <boost/hana/not.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+struct x0;
+struct x1;
+struct x2;
+
+int main() {
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::tuple_t<>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_t<x0>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_t<x0, x1>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_t<x0, x1, x2>)));
+
+ // tuple_c
+ BOOST_HANA_CONSTANT_CHECK(hana::is_empty(hana::tuple_c<int>));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_c<int, 0>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_c<int, 0, 1>)));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(hana::tuple_c<int, 0, 1, 2>)));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.prepend.cpp b/src/boost/libs/hana/test/tuple/special.prepend.cpp
new file mode 100644
index 000000000..267f7dd4e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.prepend.cpp
@@ -0,0 +1,30 @@
+// 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/integral_constant.hpp>
+#include <boost/hana/prepend.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<long>, hana::long_c<0>),
+ hana::tuple_c<long, 0>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<unsigned int, 1>, hana::uint_c<0>),
+ hana::tuple_c<unsigned int, 0, 1>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<long long, 1, 2>, hana::llong_c<0>),
+ hana::tuple_c<long long, 0, 1, 2>
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::prepend(hana::tuple_c<unsigned long, 1, 2, 3>, hana::ulong_c<0>),
+ hana::tuple_c<unsigned long, 0, 1, 2, 3>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/special.transform.cpp b/src/boost/libs/hana/test/tuple/special.transform.cpp
new file mode 100644
index 000000000..86d141c6e
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/special.transform.cpp
@@ -0,0 +1,52 @@
+// 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/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+namespace hana = boost::hana;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x1;
+struct x2;
+struct x3;
+struct x4;
+
+int main() {
+ // transform with tuple_t and a metafunction
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<>, hana::metafunction<F>),
+ hana::tuple_t<>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type, F<x2>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2, x3>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type, F<x2>::type, F<x3>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2, x3, x4>, hana::metafunction<F>),
+ hana::tuple_t<F<x1>::type, F<x2>::type, F<x3>::type, F<x4>::type>
+ ));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::transform(hana::tuple_t<x1, x2, x3, x4>, hana::template_<F>),
+ hana::tuple_t<F<x1>, F<x2>, F<x3>, F<x4>>
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/to.cpp b/src/boost/libs/hana/test/tuple/to.cpp
new file mode 100644
index 000000000..d0862c3c2
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/to.cpp
@@ -0,0 +1,18 @@
+// 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/to.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/tuple.hpp>
+namespace hana = boost::hana;
+
+
+int main() {
+ // make sure to_tuple == to<tuple_tag>
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::to<hana::tuple_tag>(hana::tuple_t<int, char, void, int(float)>),
+ hana::to_tuple(hana::tuple_t<int, char, void, int(float)>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/unpack.cpp b/src/boost/libs/hana/test/tuple/unpack.cpp
new file mode 100644
index 000000000..3838ea299
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/unpack.cpp
@@ -0,0 +1,89 @@
+// 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/tuple.hpp>
+#include <boost/hana/type.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <laws/base.hpp>
+namespace hana = boost::hana;
+using hana::test::ct_eq;
+
+
+template <typename ...>
+struct F { struct type; };
+
+struct x0;
+struct x1;
+struct x2;
+struct x3;
+
+int main() {
+ hana::test::_injection<0> f{};
+
+ // tuple
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(), f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(ct_eq<0>{}), f),
+ f(ct_eq<0>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}), f),
+ f(ct_eq<0>{}, ct_eq<1>{})
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::make_tuple(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f),
+ f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
+ ));
+
+ // tuple_t
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<>, f),
+ f()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0>, f),
+ f(hana::type_c<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2, x3>, f),
+ f(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>)
+ ));
+
+ // tuple_t with metafunction
+ auto g = hana::metafunction<F>;
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<>, g),
+ g()
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0>, g),
+ g(hana::type_c<x0>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1>, g),
+ g(hana::type_c<x0>, hana::type_c<x1>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2>, g),
+ g(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>)
+ ));
+ BOOST_HANA_CONSTANT_CHECK(hana::equal(
+ hana::unpack(hana::tuple_t<x0, x1, x2, x3>, g),
+ g(hana::type_c<x0>, hana::type_c<x1>, hana::type_c<x2>, hana::type_c<x3>)
+ ));
+}
diff --git a/src/boost/libs/hana/test/tuple/usability_of_types.cpp b/src/boost/libs/hana/test/tuple/usability_of_types.cpp
new file mode 100644
index 000000000..261b47ad0
--- /dev/null
+++ b/src/boost/libs/hana/test/tuple/usability_of_types.cpp
@@ -0,0 +1,41 @@
+// 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/at.hpp>
+#include <boost/hana/back.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/type.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+// The fact that a reference to a `type<...>` is returned from `front(types)`
+// and friends used to break the `decltype(front(types))::type` pattern,
+// because we would be trying to fetch `::type` inside a reference. To work
+// around this, a unary `operator+` turning a lvalue `type` into a rvalue
+// `type` was added.
+
+struct T; struct U; struct V;
+
+int main() {
+ auto check = [](auto types) {
+ static_assert(std::is_same<
+ typename decltype(+hana::front(types))::type, T
+ >{}, "");
+
+ static_assert(std::is_same<
+ typename decltype(+hana::at(types, hana::size_c<1>))::type, U
+ >{}, "");
+
+ static_assert(std::is_same<
+ typename decltype(+hana::back(types))::type, V
+ >{}, "");
+ };
+
+ check(hana::make_tuple(hana::type_c<T>, hana::type_c<U>, hana::type_c<V>));
+ check(hana::tuple_t<T, U, V>);
+}