]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // Copyright Louis Dionne 2013-2017 |
7c673cae FG |
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) | |
4 | ||
5 | #ifndef TEST_SUPPORT_SEQ_HPP | |
6 | #define TEST_SUPPORT_SEQ_HPP | |
7 | ||
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> | |
17 | ||
18 | ||
19 | struct Seq; | |
20 | ||
21 | template <typename Storage> | |
22 | struct seq_type { | |
23 | explicit constexpr seq_type(Storage s) : storage(s) { } | |
24 | Storage storage; | |
25 | using hana_tag = Seq; | |
26 | }; | |
27 | ||
28 | struct seq_t { | |
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); | |
33 | } | |
34 | }; | |
35 | constexpr seq_t seq{}; | |
36 | ||
37 | namespace boost { namespace hana { | |
38 | ////////////////////////////////////////////////////////////////////////// | |
39 | // Foldable | |
40 | // | |
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 | |
45 | // | |
46 | // If neither is defined, the MCD used is unspecified. | |
47 | ////////////////////////////////////////////////////////////////////////// | |
48 | #ifdef BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD | |
49 | template <> | |
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); | |
54 | } | |
55 | ||
56 | template <typename Xs, typename F> | |
57 | static constexpr auto apply(Xs xs, F f) { | |
58 | return hana::fold_left(xs.storage, f); | |
59 | } | |
60 | }; | |
61 | #elif defined(BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD) | |
62 | template <> | |
63 | struct length_impl<Seq> { | |
64 | template <typename Xs> | |
65 | static constexpr auto apply(Xs const& xs) { | |
66 | return hana::length(xs.storage); | |
67 | } | |
68 | }; | |
69 | #else | |
70 | template <> | |
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); } | |
75 | }; | |
76 | #endif | |
77 | ||
78 | ////////////////////////////////////////////////////////////////////////// | |
79 | // Iterable | |
80 | ////////////////////////////////////////////////////////////////////////// | |
81 | template <> | |
82 | struct at_impl<Seq> { | |
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); | |
86 | } | |
87 | }; | |
88 | ||
89 | template <> | |
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); | |
94 | } | |
95 | }; | |
96 | ||
97 | template <> | |
98 | struct is_empty_impl<Seq> { | |
99 | template <typename Xs> | |
100 | static constexpr auto apply(Xs xs) { | |
101 | return hana::is_empty(xs.storage); | |
102 | } | |
103 | }; | |
104 | ||
105 | ////////////////////////////////////////////////////////////////////////// | |
106 | // Sequence | |
107 | ////////////////////////////////////////////////////////////////////////// | |
108 | template <> | |
109 | struct Sequence<Seq> { | |
110 | static constexpr bool value = true; | |
111 | }; | |
112 | ||
113 | template <> | |
114 | struct make_impl<Seq> { | |
115 | template <typename ...Xs> | |
116 | static constexpr auto apply(Xs&& ...xs) { | |
117 | return ::seq(static_cast<Xs&&>(xs)...); | |
118 | } | |
119 | }; | |
120 | }} // end namespace boost::hana | |
121 | ||
122 | #endif // !TEST_SUPPORT_SEQ_HPP |