]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
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#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>
15namespace hana = boost::hana;
16
17
18//! [setup]
19template <typename Tag>
20struct print_impl {
21 template <typename X>
22 static void apply(std::ostream&, X const&) {
23 // possibly some default implementation
24 }
25};
26
27template <typename X>
28void 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]
35struct vector_tag;
36
37struct vector0 {
38 using hana_tag = vector_tag;
39 static constexpr std::size_t size = 0;
40};
41
42template <typename T1>
43struct 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
55template <typename T1, typename T2>
56struct 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]
72template <>
73struct print_impl<vector_tag> {
74 template <typename vectorN>
75 static void apply(std::ostream& os, vectorN xs) {
b32b8144 76 auto N = hana::size_c<vectorN::size>;
7c673cae
FG
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]
90template <typename Tag>
91struct 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
100int 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
123namespace old_way {
124//! [old_way]
125void print(std::ostream& os, vector0)
126{ os << "[]"; }
127
128template <typename T1>
129void print(std::ostream& os, vector1<T1> v)
130{ os << "[" << v.t1 << "]"; }
131
132template <typename T1, typename T2>
133void print(std::ostream& os, vector2<T1, T2> v)
134{ os << "[" << v.t1 << ", " << v.t2 << "]"; }
135
136// and so on...
137//! [old_way]
138}
139
140namespace preconditions {
141//! [preconditions]
142template <typename X>
143void 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
155namespace 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.
159struct 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};
166constexpr print_t print{};
167//! [function_objects]
168
169static_assert(sizeof(print) || true, "remove unused variable print warning");
170}