1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
|