summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/_include/support
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boost/libs/hana/test/_include/support/cnumeric.hpp66
-rw-r--r--src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp41
-rw-r--r--src/boost/libs/hana/test/_include/support/counter.hpp56
-rw-r--r--src/boost/libs/hana/test/_include/support/equivalence_class.hpp34
-rw-r--r--src/boost/libs/hana/test/_include/support/identity.hpp159
-rw-r--r--src/boost/libs/hana/test/_include/support/minimal_product.hpp61
-rw-r--r--src/boost/libs/hana/test/_include/support/numeric.hpp175
-rw-r--r--src/boost/libs/hana/test/_include/support/seq.hpp122
-rw-r--r--src/boost/libs/hana/test/_include/support/tracked.hpp120
-rw-r--r--src/boost/libs/hana/test/_include/support/tracked_move_only.hpp45
10 files changed, 879 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/_include/support/cnumeric.hpp b/src/boost/libs/hana/test/_include/support/cnumeric.hpp
new file mode 100644
index 000000000..51575a40f
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/cnumeric.hpp
@@ -0,0 +1,66 @@
+// 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 TEST_SUPPORT_CNUMERIC_HPP
+#define TEST_SUPPORT_CNUMERIC_HPP
+
+#include <boost/hana/concept/integral_constant.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/fwd/core/to.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/less.hpp>
+
+
+template <typename T>
+struct CNumeric { using value_type = T; };
+
+template <typename T, T v>
+struct cnumeric_t {
+ static constexpr T value = v;
+ using hana_tag = CNumeric<T>;
+ constexpr operator T() const { return value; }
+};
+
+template <typename T, T v>
+constexpr cnumeric_t<T, v> cnumeric{};
+
+template <typename T, T v>
+constexpr cnumeric_t<T, v> make_cnumeric() { return {}; }
+
+namespace boost { namespace hana {
+ // Constant and IntegralConstant
+ template <typename T>
+ struct IntegralConstant<CNumeric<T>> {
+ static constexpr bool value = true;
+ };
+
+ template <typename T, typename C>
+ struct to_impl<CNumeric<T>, C, when<
+ hana::IntegralConstant<C>::value
+ >>
+ : embedding<is_embedded<typename C::value_type, T>::value>
+ {
+ template <typename N>
+ static constexpr auto apply(N const&)
+ { return cnumeric<T, N::value>; }
+ };
+
+ // Comparable
+ template <typename T, typename U>
+ struct equal_impl<CNumeric<T>, CNumeric<U>> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X const&, Y const&)
+ { return cnumeric<bool, X::value == Y::value>; }
+ };
+
+ // Orderable
+ template <typename T, typename U>
+ struct less_impl<CNumeric<T>, CNumeric<U>> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X const&, Y const&)
+ { return cnumeric<bool, (X::value < Y::value)>; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_CNUMERIC_HPP
diff --git a/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp b/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp
new file mode 100644
index 000000000..bdc234afe
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP
+#define TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/type.hpp>
+
+#include <utility>
+
+
+// A move-only type that's also a literal type. It is also Comparable and
+// Hashable so it can be used in associative containers.
+template <int i>
+struct ConstexprMoveOnly {
+ constexpr ConstexprMoveOnly() { }
+ constexpr ConstexprMoveOnly(ConstexprMoveOnly const&) = delete;
+ constexpr ConstexprMoveOnly& operator=(ConstexprMoveOnly const&) = delete;
+ constexpr ConstexprMoveOnly(ConstexprMoveOnly&&) { }
+};
+
+template <int i, int j>
+constexpr auto operator==(ConstexprMoveOnly<i> const&, ConstexprMoveOnly<j> const&)
+{ return boost::hana::bool_c<i == j>; }
+
+template <int i, int j>
+constexpr auto operator!=(ConstexprMoveOnly<i> const&, ConstexprMoveOnly<j> const&)
+{ return boost::hana::bool_c<i != j>; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<ConstexprMoveOnly<i>> {
+ static constexpr auto apply(ConstexprMoveOnly<i> const&)
+ { return hana::type_c<ConstexprMoveOnly<i>>; };
+ };
+}}
+
+#endif // !TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP
diff --git a/src/boost/libs/hana/test/_include/support/counter.hpp b/src/boost/libs/hana/test/_include/support/counter.hpp
new file mode 100644
index 000000000..4640363d7
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/counter.hpp
@@ -0,0 +1,56 @@
+// 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)
+
+#ifndef TEST_SUPPORT_COUNTER_HPP
+#define TEST_SUPPORT_COUNTER_HPP
+
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/concept/iterable.hpp>
+#include <boost/hana/fwd/drop_front.hpp>
+#include <boost/hana/fwd/is_empty.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+
+// Counter - an infinite iterable for the masses
+
+struct Counter_tag { };
+
+template <std::size_t N = 0>
+struct Counter {
+ using hana_tag = Counter_tag;
+ static constexpr std::size_t value = N;
+};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct at_impl<Counter_tag> {
+ template <typename T, typename N>
+ static constexpr decltype(auto) apply(T, N) {
+ return hana::size_c<T::value + N::value>;
+ }
+ };
+
+ template <>
+ struct drop_front_impl<Counter_tag> {
+ template <typename T, typename N>
+ static constexpr auto apply(T, N) {
+ return Counter<T::value + N::value>{};
+ }
+ };
+
+ template <>
+ struct is_empty_impl<Counter_tag> {
+ template <typename Xs>
+ static constexpr auto apply(Xs)
+ -> hana::false_
+ { return {}; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_COUNTER_HPP
diff --git a/src/boost/libs/hana/test/_include/support/equivalence_class.hpp b/src/boost/libs/hana/test/_include/support/equivalence_class.hpp
new file mode 100644
index 000000000..c5e8d72e6
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/equivalence_class.hpp
@@ -0,0 +1,34 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef TEST_SUPPORT_EQUIVALENCE_CLASS_HPP
+#define TEST_SUPPORT_EQUIVALENCE_CLASS_HPP
+
+#include <boost/hana/fwd/equal.hpp>
+
+
+struct EquivalenceClass { };
+
+template <typename Token, typename T>
+struct equivalence_class_impl {
+ Token equivalence_class;
+ T unwrap;
+ using hana_tag = EquivalenceClass;
+};
+
+template <typename Token, typename X>
+constexpr equivalence_class_impl<Token, X> equivalence_class(Token token, X x) {
+ return {token, x};
+}
+
+namespace boost { namespace hana {
+ template <>
+ struct equal_impl<EquivalenceClass, EquivalenceClass> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return hana::equal(x.equivalence_class, y.equivalence_class); }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_EQUIVALENCE_CLASS_HPP
diff --git a/src/boost/libs/hana/test/_include/support/identity.hpp b/src/boost/libs/hana/test/_include/support/identity.hpp
new file mode 100644
index 000000000..c6799cbe8
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/identity.hpp
@@ -0,0 +1,159 @@
+// 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 TEST_SUPPORT_IDENTITY_HPP
+#define TEST_SUPPORT_IDENTITY_HPP
+
+#include <boost/hana/chain.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/fwd/adjust_if.hpp>
+#include <boost/hana/fwd/ap.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/flatten.hpp>
+#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/fwd/lift.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/transform.hpp>
+
+#include <type_traits>
+
+
+struct Identity;
+
+template <typename T>
+struct identity_t {
+ T value;
+ using hana_tag = Identity;
+};
+
+struct make_identity {
+ template <typename T>
+ constexpr identity_t<typename std::decay<T>::type> operator()(T&& t) const {
+ return {static_cast<T&&>(t)};
+ }
+};
+
+constexpr make_identity identity{};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<Identity, Identity> {
+ template <typename Id1, typename Id2>
+ static constexpr auto apply(Id1 x, Id2 y)
+ { return hana::equal(x.value, y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Orderable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct less_impl<Identity, Identity> {
+ template <typename Id1, typename Id2>
+ static constexpr auto apply(Id1 x, Id2 y)
+ { return hana::less(x.value, y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Functor
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
+ // BOOST_HANA_TEST_FUNCTOR_ADJUST_MCD_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD
+ template <>
+ struct transform_impl<Identity> {
+ template <typename Id, typename F>
+ static constexpr auto apply(Id self, F f)
+ { return ::identity(f(self.value)); }
+ };
+#else
+ template <>
+ struct adjust_if_impl<Identity> {
+ struct get_value {
+ template <typename T>
+ constexpr auto operator()(T t) const { return t.value; }
+ };
+
+ template <typename Id, typename P, typename F>
+ static constexpr auto apply(Id self, P p, F f) {
+ auto x = hana::eval_if(p(self.value),
+ hana::make_lazy(hana::compose(f, get_value{}))(self),
+ hana::make_lazy(get_value{})(self)
+ );
+ return ::identity(x);
+ }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Applicative
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
+ // BOOST_HANA_TEST_APPLICATIVE_MONAD_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct lift_impl<Identity> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return ::identity(x); }
+ };
+#ifdef BOOST_HANA_TEST_APPLICATIVE_FULL_MCD
+ template <>
+ struct ap_impl<Identity> {
+ template <typename F, typename X>
+ static constexpr auto apply(F f, X x)
+ { return ::identity(f.value(x.value)); }
+ };
+#else
+ template <>
+ struct ap_impl<Identity> {
+ template <typename F, typename X>
+ static constexpr decltype(auto) apply(F&& f, X&& x) {
+ return hana::chain(
+ static_cast<F&&>(f),
+ hana::partial(hana::transform, static_cast<X&&>(x))
+ );
+ }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monad
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_MONAD_FLATTEN_MCD
+ // BOOST_HANA_TEST_MONAD_CHAIN_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_MONAD_FLATTEN_MCD
+ template <>
+ struct flatten_impl<Identity> {
+ template <typename Id>
+ static constexpr auto apply(Id self)
+ { return self.value; }
+ };
+#else
+ template <>
+ struct chain_impl<Identity> {
+ template <typename X, typename F>
+ static constexpr auto apply(X x, F f)
+ { return f(x.value); }
+ };
+#endif
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_IDENTITY_HPP
diff --git a/src/boost/libs/hana/test/_include/support/minimal_product.hpp b/src/boost/libs/hana/test/_include/support/minimal_product.hpp
new file mode 100644
index 000000000..1fe39f786
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/minimal_product.hpp
@@ -0,0 +1,61 @@
+// 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 TEST_SUPPORT_MINIMAL_PRODUCT_HPP
+#define TEST_SUPPORT_MINIMAL_PRODUCT_HPP
+
+#include <boost/hana/fwd/core/make.hpp>
+#include <boost/hana/fwd/first.hpp>
+#include <boost/hana/fwd/second.hpp>
+
+#include <type_traits>
+
+
+struct MinimalProduct;
+
+template <typename X, typename Y>
+struct product_t {
+ X fst;
+ Y snd;
+ using hana_tag = MinimalProduct;
+};
+
+struct make_minimal_product {
+ template <typename T, typename U>
+ constexpr product_t<typename std::decay<T>::type,
+ typename std::decay<U>::type>
+ operator()(T&& t, U&& u) const {
+ return {static_cast<T&&>(t), static_cast<U&&>(u)};
+ }
+};
+
+constexpr make_minimal_product minimal_product{};
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Product
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct make_impl<MinimalProduct> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return ::minimal_product(x, y); }
+ };
+
+ template <>
+ struct first_impl<MinimalProduct> {
+ template <typename P>
+ static constexpr decltype(auto) apply(P&& p)
+ { return p.fst; }
+ };
+
+ template <>
+ struct second_impl<MinimalProduct> {
+ template <typename P>
+ static constexpr decltype(auto) apply(P&& p)
+ { return p.snd; }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_MINIMAL_PRODUCT_HPP
diff --git a/src/boost/libs/hana/test/_include/support/numeric.hpp b/src/boost/libs/hana/test/_include/support/numeric.hpp
new file mode 100644
index 000000000..2aebe7664
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/numeric.hpp
@@ -0,0 +1,175 @@
+// 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 TEST_SUPPORT_NUMERIC_HPP
+#define TEST_SUPPORT_NUMERIC_HPP
+
+#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/eval.hpp>
+#include <boost/hana/fwd/div.hpp>
+#include <boost/hana/fwd/equal.hpp>
+#include <boost/hana/fwd/eval_if.hpp>
+#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/fwd/minus.hpp>
+#include <boost/hana/fwd/mod.hpp>
+#include <boost/hana/fwd/mult.hpp>
+#include <boost/hana/fwd/negate.hpp>
+#include <boost/hana/fwd/not.hpp>
+#include <boost/hana/fwd/one.hpp>
+#include <boost/hana/fwd/plus.hpp>
+#include <boost/hana/fwd/while.hpp>
+#include <boost/hana/fwd/zero.hpp>
+
+
+struct numeric_type {
+ constexpr explicit numeric_type(int v) : value(v) { }
+ int value;
+ constexpr operator int() const { return value; }
+};
+
+using Numeric = boost::hana::tag_of_t<numeric_type>;
+
+struct numeric_t {
+ constexpr numeric_type operator()(int x) const {
+ return numeric_type{x};
+ }
+};
+constexpr numeric_t numeric{};
+
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Comparable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct equal_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value == y.value); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Orderable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct less_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y) {
+ // Workaround a _weird_ GCC bug:
+ // error: parse error in template argument list
+ // bool cmp = (x.value < y.value);
+ // ^
+ int xv = x.value, yv = y.value;
+ return numeric(xv < yv);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Logical
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct eval_if_impl<Numeric> {
+ template <typename C, typename T, typename E>
+ static constexpr auto apply(C const& c, T&& t, E&& e) {
+ return c.value ? hana::eval(static_cast<T&&>(t))
+ : hana::eval(static_cast<E&&>(e));
+ }
+ };
+
+ template <>
+ struct not_impl<Numeric> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return numeric(!x.value); }
+ };
+
+ template <>
+ struct while_impl<Numeric> {
+ template <typename Pred, typename State, typename F>
+ static constexpr auto apply(Pred pred, State state, F f)
+ -> decltype(true ? f(state) : state)
+ {
+ if (pred(state))
+ return hana::while_(pred, f(state), f);
+ else
+ return state;
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Monoid
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct plus_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value + y.value); }
+ };
+
+ template <>
+ struct zero_impl<Numeric> {
+ static constexpr auto apply()
+ { return numeric(0); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Group
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_GROUP_NEGATE_MCD
+ // BOOST_HANA_TEST_GROUP_MINUS_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#if defined(BOOST_HANA_TEST_GROUP_NEGATE_MCD)
+ template <>
+ struct negate_impl<Numeric> {
+ template <typename X>
+ static constexpr auto apply(X x)
+ { return numeric(-x.value); }
+ };
+#else
+ template <>
+ struct minus_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value - y.value); }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Ring
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct mult_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value * y.value); }
+ };
+
+ template <>
+ struct one_impl<Numeric> {
+ static constexpr auto apply()
+ { return numeric(1); }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // EuclideanRing
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct div_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value / y.value); }
+ };
+
+ template <>
+ struct mod_impl<Numeric, Numeric> {
+ template <typename X, typename Y>
+ static constexpr auto apply(X x, Y y)
+ { return numeric(x.value % y.value); }
+ };
+}} // end namespace boost::hana
+
+#endif //! TEST_SUPPORT_NUMERIC_HPP
diff --git a/src/boost/libs/hana/test/_include/support/seq.hpp b/src/boost/libs/hana/test/_include/support/seq.hpp
new file mode 100644
index 000000000..ee222dc01
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/seq.hpp
@@ -0,0 +1,122 @@
+// 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 TEST_SUPPORT_SEQ_HPP
+#define TEST_SUPPORT_SEQ_HPP
+
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/concept/sequence.hpp>
+#include <boost/hana/fwd/core/make.hpp>
+#include <boost/hana/fwd/drop_front.hpp>
+#include <boost/hana/fwd/fold_left.hpp>
+#include <boost/hana/fwd/is_empty.hpp>
+#include <boost/hana/fwd/length.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+
+struct Seq;
+
+template <typename Storage>
+struct seq_type {
+ explicit constexpr seq_type(Storage s) : storage(s) { }
+ Storage storage;
+ using hana_tag = Seq;
+};
+
+struct seq_t {
+ template <typename ...Xs>
+ constexpr auto operator()(Xs&& ...xs) const {
+ auto storage = boost::hana::make_tuple(xs...);
+ return seq_type<decltype(storage)>(storage);
+ }
+};
+constexpr seq_t seq{};
+
+namespace boost { namespace hana {
+ //////////////////////////////////////////////////////////////////////////
+ // Foldable
+ //
+ // Define either one to select which MCD is used:
+ // BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+ // BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
+ // BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
+ //
+ // If neither is defined, the MCD used is unspecified.
+ //////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
+ template <>
+ struct fold_left_impl<Seq> {
+ template <typename Xs, typename S, typename F>
+ static constexpr auto apply(Xs xs, S s, F f) {
+ return hana::fold_left(xs.storage, s, f);
+ }
+
+ template <typename Xs, typename F>
+ static constexpr auto apply(Xs xs, F f) {
+ return hana::fold_left(xs.storage, f);
+ }
+ };
+#elif defined(BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD)
+ template <>
+ struct length_impl<Seq> {
+ template <typename Xs>
+ static constexpr auto apply(Xs const& xs) {
+ return hana::length(xs.storage);
+ }
+ };
+#else
+ template <>
+ struct unpack_impl<Seq> {
+ template <typename Xs, typename F>
+ static constexpr auto apply(Xs xs, F f)
+ { return hana::unpack(xs.storage, f); }
+ };
+#endif
+
+ //////////////////////////////////////////////////////////////////////////
+ // Iterable
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct at_impl<Seq> {
+ template <typename Xs, typename N>
+ static constexpr decltype(auto) apply(Xs&& xs, N&& n) {
+ return hana::at(static_cast<Xs&&>(xs).storage, n);
+ }
+ };
+
+ template <>
+ struct drop_front_impl<Seq> {
+ template <typename Xs, typename N>
+ static constexpr auto apply(Xs xs, N n) {
+ return hana::unpack(hana::drop_front(xs.storage, n), ::seq);
+ }
+ };
+
+ template <>
+ struct is_empty_impl<Seq> {
+ template <typename Xs>
+ static constexpr auto apply(Xs xs) {
+ return hana::is_empty(xs.storage);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sequence
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct Sequence<Seq> {
+ static constexpr bool value = true;
+ };
+
+ template <>
+ struct make_impl<Seq> {
+ template <typename ...Xs>
+ static constexpr auto apply(Xs&& ...xs) {
+ return ::seq(static_cast<Xs&&>(xs)...);
+ }
+ };
+}} // end namespace boost::hana
+
+#endif // !TEST_SUPPORT_SEQ_HPP
diff --git a/src/boost/libs/hana/test/_include/support/tracked.hpp b/src/boost/libs/hana/test/_include/support/tracked.hpp
new file mode 100644
index 000000000..215ffba4d
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/tracked.hpp
@@ -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)
+
+#ifndef TEST_SUPPORT_TRACKED_HPP
+#define TEST_SUPPORT_TRACKED_HPP
+
+// Define this if you want Tracked objects to print information to stderr.
+// #define TRACKED_PRINT_STUFF
+
+#include <boost/hana/assert.hpp>
+
+#ifdef TRACKED_PRINT_STUFF
+# include <iostream>
+#endif
+
+#include <iosfwd>
+
+
+struct Tracked {
+ enum class State { CONSTRUCTED, MOVED_FROM, DESTROYED };
+
+ int value;
+ State state;
+
+ explicit Tracked(int k) : value{k}, state{State::CONSTRUCTED} {
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "constructing " << *this << '\n';
+#endif
+ }
+
+ Tracked(Tracked const& t) : value{t.value}, state{State::CONSTRUCTED} {
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
+ "copying a moved-from object");
+
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
+ "copying a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "copying " << *this << '\n';
+#endif
+ }
+
+ Tracked(Tracked&& t) : value{t.value}, state{State::CONSTRUCTED} {
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM &&
+ "double moving from an object");
+
+ BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED &&
+ "moving from a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "moving " << t << '\n';
+#endif
+ t.state = State::MOVED_FROM;
+ }
+
+ Tracked& operator=(Tracked const& other) {
+ BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
+ "assigning to a destroyed object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
+ "assigning a moved-from object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
+ "assigning a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "assigning " << other << " to " << *this << '\n';
+#endif
+ this->value = other.value;
+ return *this;
+ }
+
+ Tracked& operator=(Tracked&& other) {
+ BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED &&
+ "assigning to a destroyed object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM &&
+ "double-moving from an object");
+
+ BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED &&
+ "assigning a destroyed object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "assigning " << other << " to " << *this << '\n';
+#endif
+ this->value = other.value;
+ other.state = State::MOVED_FROM;
+ return *this;
+ }
+
+ ~Tracked() {
+ BOOST_HANA_RUNTIME_CHECK(state != State::DESTROYED &&
+ "double-destroying an object");
+
+#ifdef TRACKED_PRINT_STUFF
+ std::cerr << "destructing " << *this << '\n';
+#endif
+ state = State::DESTROYED;
+ }
+
+ template <typename CharT, typename Traits>
+ friend std::basic_ostream<CharT, Traits>&
+ operator<<(std::basic_ostream<CharT, Traits>& os, Tracked const& t) {
+ os << "Tracked{" << t.value << "}";
+ switch (t.state) {
+ case State::CONSTRUCTED:
+ os << "[ok]"; break;
+ case State::MOVED_FROM:
+ os << "[moved from]"; break;
+ case State::DESTROYED:
+ os << "[destroyed]"; break;
+ default:
+ BOOST_HANA_RUNTIME_CHECK(false && "never reached");
+ }
+ return os;
+ }
+};
+
+#endif // !TEST_SUPPORT_TRACKED_HPP
diff --git a/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp b/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp
new file mode 100644
index 000000000..03e9d5da6
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp
@@ -0,0 +1,45 @@
+// 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 TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP
+#define TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP
+
+#include <boost/hana/bool.hpp>
+#include <boost/hana/fwd/hash.hpp>
+#include <boost/hana/type.hpp>
+
+#include <support/tracked.hpp>
+
+#include <utility>
+
+
+// A move-only type that's Tracked. It is also Comparable and Hashable so it
+// can be used in associative containers.
+template <int i>
+struct TrackedMoveOnly : Tracked {
+ TrackedMoveOnly() : Tracked(i) { }
+ TrackedMoveOnly(TrackedMoveOnly const&) = delete;
+ TrackedMoveOnly& operator=(TrackedMoveOnly const&) = delete;
+ TrackedMoveOnly(TrackedMoveOnly&& x)
+ : Tracked(std::move(x))
+ { }
+};
+
+template <int i, int j>
+constexpr auto operator==(TrackedMoveOnly<i> const&, TrackedMoveOnly<j> const&)
+{ return boost::hana::bool_c<i == j>; }
+
+template <int i, int j>
+constexpr auto operator!=(TrackedMoveOnly<i> const&, TrackedMoveOnly<j> const&)
+{ return boost::hana::bool_c<i != j>; }
+
+namespace boost { namespace hana {
+ template <int i>
+ struct hash_impl<TrackedMoveOnly<i>> {
+ static constexpr auto apply(TrackedMoveOnly<i> const&)
+ { return hana::type_c<TrackedMoveOnly<i>>; };
+ };
+}}
+
+#endif // !TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP