• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
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 {
seq_typeseq_type23     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>
operator ()seq_t30     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>
applyboost::hana::fold_left_impl52         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>
applyboost::hana::fold_left_impl57         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>
applyboost::hana::at_impl84         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>
applyboost::hana::drop_front_impl92         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>
applyboost::hana::is_empty_impl100         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>
applyboost::hana::make_impl116         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
123