diff options
Diffstat (limited to 'src/boost/libs/hana/test/_include/support')
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 |