]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/variant/detail/multivisitors_cpp14_based.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / variant / detail / multivisitors_cpp14_based.hpp
1 // Boost.Varaint
2 // Contains multivisitors that are implemented via variadic templates, std::tuple
3 // and decltype(auto)
4 //
5 // See http://www.boost.org for most recent version, including documentation.
6 //
7 // Copyright Antony Polukhin, 2013-2014.
8 //
9 // Distributed under the Boost
10 // Software License, Version 1.0. (See accompanying file
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
12
13 #ifndef BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
14 #define BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
15
16 #if defined(_MSC_VER)
17 # pragma once
18 #endif
19
20 #include <boost/variant/detail/multivisitors_cpp14_based.hpp>
21 #include <tuple>
22
23 namespace boost {
24
25 namespace detail { namespace variant {
26
27 // Forward declaration
28 template <typename Visitor, typename Visitables, typename... Values>
29 class one_by_one_visitor_and_value_referer_cpp14;
30
31 template <typename Visitor, typename Visitables, typename... Values>
32 inline one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... >
33 make_one_by_one_visitor_and_value_referer_cpp14(
34 Visitor& visitor, Visitables visitables, std::tuple<Values...> values
35 )
36 {
37 return one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... > (
38 visitor, visitables, values
39 );
40 }
41
42 template <typename Visitor, typename Visitables, typename... Values>
43 class one_by_one_visitor_and_value_referer_cpp14
44 {
45 Visitor& visitor_;
46 std::tuple<Values...> values_;
47 Visitables visitables_;
48
49 public: // structors
50 one_by_one_visitor_and_value_referer_cpp14(
51 Visitor& visitor, Visitables visitables, std::tuple<Values...> values
52 ) BOOST_NOEXCEPT
53 : visitor_(visitor)
54 , values_(values)
55 , visitables_(visitables)
56 {}
57
58 public: // visitor interfaces
59 template <typename Value>
60 decltype(auto) operator()(Value&& value) const
61 {
62 return ::boost::apply_visitor(
63 make_one_by_one_visitor_and_value_referer_cpp14(
64 visitor_,
65 tuple_tail(visitables_),
66 std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value)))
67 )
68 , unwrap(std::get<0>(visitables_)) // getting Head element
69 );
70 }
71
72 private:
73 one_by_one_visitor_and_value_referer_cpp14& operator=(const one_by_one_visitor_and_value_referer_cpp14&);
74 };
75
76 template <typename Visitor, typename... Values>
77 class one_by_one_visitor_and_value_referer_cpp14<Visitor, std::tuple<>, Values...>
78 {
79 Visitor& visitor_;
80 std::tuple<Values...> values_;
81
82 public:
83 one_by_one_visitor_and_value_referer_cpp14(
84 Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values...> values
85 ) BOOST_NOEXCEPT
86 : visitor_(visitor)
87 , values_(values)
88 {}
89
90 template <class Tuple, std::size_t... I>
91 decltype(auto) do_call(Tuple t, index_sequence<I...>) const {
92 return visitor_(unwrap(std::get<I>(t))...);
93 }
94
95 template <typename Value>
96 decltype(auto) operator()(Value&& value) const
97 {
98 return do_call(
99 std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value))),
100 make_index_sequence<sizeof...(Values) + 1>()
101 );
102 }
103 };
104
105 }} // namespace detail::variant
106
107 template <class Visitor, class T1, class T2, class T3, class... TN>
108 inline decltype(auto) apply_visitor(const Visitor& visitor, T1&& v1, T2&& v2, T3&& v3, TN&&... vn,
109 typename boost::disable_if<
110 boost::detail::variant::has_result_type<Visitor>,
111 bool
112 >::type = true)
113 {
114 return boost::apply_visitor(
115 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
116 visitor,
117 std::make_tuple(
118 ::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
119 ::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
120 ::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
121 ),
122 std::tuple<>()
123 ),
124 ::boost::forward<T1>(v1)
125 );
126 }
127
128
129 template <class Visitor, class T1, class T2, class T3, class... TN>
130 inline decltype(auto) apply_visitor(Visitor& visitor, T1&& v1, T2&& v2, T3&& v3, TN&&... vn,
131 typename boost::disable_if<
132 boost::detail::variant::has_result_type<Visitor>,
133 bool
134 >::type = true)
135 {
136 return ::boost::apply_visitor(
137 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
138 visitor,
139 std::make_tuple(
140 ::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
141 ::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
142 ::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
143 ),
144 std::tuple<>()
145 ),
146 ::boost::forward<T1>(v1)
147 );
148 }
149
150 } // namespace boost
151
152 #endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
153