]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/example/tutorial/tag_dispatching.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / tag_dispatching.cpp
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 #include <boost/hana/assert.hpp>
6 #include <boost/hana/core/tag_of.hpp>
7 #include <boost/hana/integral_constant.hpp>
8 #include <boost/hana/minus.hpp>
9 #include <boost/hana/not_equal.hpp>
10 #include <boost/hana/tuple.hpp>
11
12 #include <cstddef>
13 #include <iostream>
14 #include <sstream>
15 namespace hana = boost::hana;
16
17
18 //! [setup]
19 template <typename Tag>
20 struct print_impl {
21 template <typename X>
22 static void apply(std::ostream&, X const&) {
23 // possibly some default implementation
24 }
25 };
26
27 template <typename X>
28 void print(std::ostream& os, X x) {
29 using Tag = typename hana::tag_of<X>::type;
30 print_impl<Tag>::apply(os, x);
31 }
32 //! [setup]
33
34 //! [vector]
35 struct vector_tag;
36
37 struct vector0 {
38 using hana_tag = vector_tag;
39 static constexpr std::size_t size = 0;
40 };
41
42 template <typename T1>
43 struct vector1 {
44 T1 t1;
45 using hana_tag = vector_tag;
46 static constexpr std::size_t size = 1;
47
48 template <typename Index>
49 auto const& operator[](Index i) const {
50 static_assert(i == 0u, "index out of bounds");
51 return t1;
52 }
53 };
54
55 template <typename T1, typename T2>
56 struct vector2 {
57 T1 t1; T2 t2;
58 using hana_tag = vector_tag;
59 static constexpr std::size_t size = 2;
60
61 // Using Hana as a backend to simplify the example.
62 template <typename Index>
63 auto const& operator[](Index i) const {
64 return *hana::make_tuple(&t1, &t2)[i];
65 }
66 };
67
68 // and so on...
69 //! [vector]
70
71 //! [customize]
72 template <>
73 struct print_impl<vector_tag> {
74 template <typename vectorN>
75 static void apply(std::ostream& os, vectorN xs) {
76 auto N = hana::size_c<vectorN::size>;
77
78 os << "[";
79 N.times.with_index([&](auto i) {
80 os << xs[i];
81 if (i != N - hana::size_c<1>) os << ", ";
82 });
83 os << "]";
84 }
85 };
86 //! [customize]
87
88 #if 0
89 //! [customize-when]
90 template <typename Tag>
91 struct print_impl<Tag, hana::when<Tag represents some kind of sequence>> {
92 template <typename Seq>
93 static void apply(std::ostream& os, Seq xs) {
94 // Some implementation for any sequence
95 }
96 };
97 //! [customize-when]
98 #endif
99
100 int main() {
101 {
102 std::stringstream ss;
103 vector0 v0;
104 print(ss, v0);
105 BOOST_HANA_RUNTIME_CHECK(ss.str() == "[]");
106 }
107
108 {
109 std::stringstream ss;
110 vector1<int> v1{1};
111 print(ss, v1);
112 BOOST_HANA_RUNTIME_CHECK(ss.str() == "[1]");
113 }
114
115 {
116 std::stringstream ss;
117 vector2<int, char> v2{1, 'x'};
118 print(ss, v2);
119 BOOST_HANA_RUNTIME_CHECK(ss.str() == "[1, x]");
120 }
121 }
122
123 namespace old_way {
124 //! [old_way]
125 void print(std::ostream& os, vector0)
126 { os << "[]"; }
127
128 template <typename T1>
129 void print(std::ostream& os, vector1<T1> v)
130 { os << "[" << v.t1 << "]"; }
131
132 template <typename T1, typename T2>
133 void print(std::ostream& os, vector2<T1, T2> v)
134 { os << "[" << v.t1 << ", " << v.t2 << "]"; }
135
136 // and so on...
137 //! [old_way]
138 }
139
140 namespace preconditions {
141 //! [preconditions]
142 template <typename X>
143 void print(std::ostream& os, X x) {
144 // **** check some precondition ****
145
146 // The precondition only has to be checked here; implementations
147 // can assume their arguments to always be sane.
148
149 using Tag = typename hana::tag_of<X>::type;
150 print_impl<Tag>::apply(os, x);
151 }
152 //! [preconditions]
153 }
154
155 namespace function_objects {
156 //! [function_objects]
157 // Defining a function object is only needed once and implementations do not
158 // have to worry about static initialization and other painful tricks.
159 struct print_t {
160 template <typename X>
161 void operator()(std::ostream& os, X x) const {
162 using Tag = typename hana::tag_of<X>::type;
163 print_impl<Tag>::apply(os, x);
164 }
165 };
166 constexpr print_t print{};
167 //! [function_objects]
168
169 static_assert(sizeof(print) || true, "remove unused variable print warning");
170 }