1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
5 #ifndef TEST_SUPPORT_SEQ_HPP
6 #define TEST_SUPPORT_SEQ_HPP
8 #include <boost/hana/fwd/at.hpp>
9 #include <boost/hana/fwd/concept/sequence.hpp>
10 #include <boost/hana/fwd/core/make.hpp>
11 #include <boost/hana/fwd/drop_front.hpp>
12 #include <boost/hana/fwd/fold_left.hpp>
13 #include <boost/hana/fwd/is_empty.hpp>
14 #include <boost/hana/fwd/length.hpp>
15 #include <boost/hana/tuple.hpp>
16 #include <boost/hana/unpack.hpp>
21 template <typename Storage>
23 explicit constexpr seq_type(Storage s) : storage(s) { }
29 template <typename ...Xs>
30 constexpr auto operator()(Xs&& ...xs) const {
31 auto storage = boost::hana::make_tuple(xs...);
32 return seq_type<decltype(storage)>(storage);
35 constexpr seq_t seq{};
37 namespace boost { namespace hana {
38 //////////////////////////////////////////////////////////////////////////
41 // Define either one to select which MCD is used:
42 // BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
43 // BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD
44 // BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD
46 // If neither is defined, the MCD used is unspecified.
47 //////////////////////////////////////////////////////////////////////////
48 #ifdef BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD
50 struct fold_left_impl<Seq> {
51 template <typename Xs, typename S, typename F>
52 static constexpr auto apply(Xs xs, S s, F f) {
53 return hana::fold_left(xs.storage, s, f);
56 template <typename Xs, typename F>
57 static constexpr auto apply(Xs xs, F f) {
58 return hana::fold_left(xs.storage, f);
61 #elif defined(BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD)
63 struct length_impl<Seq> {
64 template <typename Xs>
65 static constexpr auto apply(Xs const& xs) {
66 return hana::length(xs.storage);
71 struct unpack_impl<Seq> {
72 template <typename Xs, typename F>
73 static constexpr auto apply(Xs xs, F f)
74 { return hana::unpack(xs.storage, f); }
78 //////////////////////////////////////////////////////////////////////////
80 //////////////////////////////////////////////////////////////////////////
83 template <typename Xs, typename N>
84 static constexpr decltype(auto) apply(Xs&& xs, N&& n) {
85 return hana::at(static_cast<Xs&&>(xs).storage, n);
90 struct drop_front_impl<Seq> {
91 template <typename Xs, typename N>
92 static constexpr auto apply(Xs xs, N n) {
93 return hana::unpack(hana::drop_front(xs.storage, n), ::seq);
98 struct is_empty_impl<Seq> {
99 template <typename Xs>
100 static constexpr auto apply(Xs xs) {
101 return hana::is_empty(xs.storage);
105 //////////////////////////////////////////////////////////////////////////
107 //////////////////////////////////////////////////////////////////////////
109 struct Sequence<Seq> {
110 static constexpr bool value = true;
114 struct make_impl<Seq> {
115 template <typename ...Xs>
116 static constexpr auto apply(Xs&& ...xs) {
117 return ::seq(static_cast<Xs&&>(xs)...);
120 }} // end namespace boost::hana
122 #endif // !TEST_SUPPORT_SEQ_HPP