]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/variant/include/boost/variant/detail/multivisitors_cpp11_based.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / variant / include / boost / variant / detail / multivisitors_cpp11_based.hpp
1 // Boost.Varaint
2 // Contains multivisitors that are implemented via variadic templates and std::tuple
3 //
4 // See http://www.boost.org for most recent version, including documentation.
5 //
6 // Copyright Antony Polukhin, 2013-2014.
7 //
8 // Distributed under the Boost
9 // Software License, Version 1.0. (See accompanying file
10 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
11
12 #ifndef BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
13 #define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
14
15 #if defined(_MSC_VER)
16 # pragma once
17 #endif
18
19 #include <boost/variant/detail/apply_visitor_unary.hpp>
20 #include <boost/variant/variant_fwd.hpp> // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
21
22 #if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_HDR_TUPLE)
23 # error "This file requires <tuple> and variadic templates support"
24 #endif
25
26 #include <tuple>
27
28 namespace boost {
29
30 namespace detail { namespace variant {
31
32 // Implementing some of the C++14 features in C++11
33 template <std::size_t... I> class index_sequence {};
34
35 template <std::size_t N, std::size_t... I>
36 struct make_index_sequence
37 : make_index_sequence<N-1, N-1, I...>
38 {};
39 template <std::size_t... I>
40 struct make_index_sequence<0, I...>
41 : index_sequence<I...>
42 {};
43
44 template <class... Types>
45 std::tuple<Types&...> forward_as_tuple_simple(Types&... args) BOOST_NOEXCEPT
46 {
47 return std::tuple<Types&...>(args...);
48 }
49
50 // Implementing some of the helper tuple methods
51 template <std::size_t... I, typename Tuple>
52 std::tuple<typename std::tuple_element<I + 1, Tuple>::type...>
53 tuple_tail_impl(const Tuple& tpl, index_sequence<I...>)
54 {
55 return std::tuple<
56 typename std::tuple_element<I + 1, Tuple>::type...
57 > (std::get<I + 1>(tpl)...);
58 }
59
60 template <typename Head, typename... Tail>
61 std::tuple<Tail...> tuple_tail(const std::tuple<Head, Tail...>& tpl)
62 {
63 return tuple_tail_impl(tpl, make_index_sequence<sizeof...(Tail)>());
64 }
65
66
67
68 // Forward declaration
69 template <typename Visitor, typename Visitables, typename... Values>
70 class one_by_one_visitor_and_value_referer;
71
72 template <typename Visitor, typename Visitables, typename... Values>
73 inline one_by_one_visitor_and_value_referer<Visitor, Visitables, Values... >
74 make_one_by_one_visitor_and_value_referer(
75 Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
76 )
77 {
78 return one_by_one_visitor_and_value_referer<Visitor, Visitables, Values... > (
79 visitor, visitables, values
80 );
81 }
82
83 template <typename Visitor, typename Visitables, typename... Values>
84 class one_by_one_visitor_and_value_referer
85 {
86 Visitor& visitor_;
87 std::tuple<Values&...> values_;
88 Visitables visitables_;
89
90 public: // structors
91 one_by_one_visitor_and_value_referer(
92 Visitor& visitor, Visitables visitables, std::tuple<Values&...> values
93 ) BOOST_NOEXCEPT
94 : visitor_(visitor)
95 , values_(values)
96 , visitables_(visitables)
97 {}
98
99 public: // visitor interfaces
100 typedef typename Visitor::result_type result_type;
101
102 template <typename Value>
103 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(Value& value) const
104 {
105 return ::boost::apply_visitor(
106 make_one_by_one_visitor_and_value_referer(
107 visitor_,
108 tuple_tail(visitables_),
109 std::tuple_cat(values_, std::tuple<Value&>(value))
110 )
111 , std::get<0>(visitables_) // getting Head element
112 );
113 }
114
115 private:
116 one_by_one_visitor_and_value_referer& operator=(const one_by_one_visitor_and_value_referer&);
117 };
118
119 template <typename Visitor, typename... Values>
120 class one_by_one_visitor_and_value_referer<Visitor, std::tuple<>, Values...>
121 {
122 Visitor& visitor_;
123 std::tuple<Values&...> values_;
124
125 public:
126 one_by_one_visitor_and_value_referer(
127 Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values&...> values
128 ) BOOST_NOEXCEPT
129 : visitor_(visitor)
130 , values_(values)
131 {}
132
133 typedef typename Visitor::result_type result_type;
134
135 template <class Tuple, std::size_t... I>
136 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) do_call(Tuple t, index_sequence<I...>) const {
137 return visitor_(std::get<I>(t)...);
138 }
139
140 template <typename Value>
141 BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()(Value& value) const
142 {
143 return do_call(
144 std::tuple_cat(values_, std::tuple<Value&>(value)),
145 make_index_sequence<sizeof...(Values) + 1>()
146 );
147 }
148 };
149
150 }} // namespace detail::variant
151
152 template <class Visitor, class T1, class T2, class T3, class... TN>
153 inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
154 apply_visitor(const Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn)
155 {
156 return ::boost::apply_visitor(
157 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer(
158 visitor,
159 ::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
160 std::tuple<>()
161 ),
162 v1
163 );
164 }
165
166 template <class Visitor, class T1, class T2, class T3, class... TN>
167 inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
168 apply_visitor(Visitor& visitor, T1& v1, T2& v2, T3& v3, TN&... vn)
169 {
170 return ::boost::apply_visitor(
171 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer(
172 visitor,
173 ::boost::detail::variant::forward_as_tuple_simple(v2, v3, vn...),
174 std::tuple<>()
175 ),
176 v1
177 );
178 }
179
180 } // namespace boost
181
182 #endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP11_BASED_HPP
183