]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/variant/detail/multivisitors_cpp14_based.hpp
update source to Ceph Pacific 16.2.2
[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
22 namespace boost {
23
24 namespace detail { namespace variant {
25
26 // Forward declaration
27 template <typename Visitor, typename Visitables, typename... Values>
28 class one_by_one_visitor_and_value_referer_cpp14;
29
30 template <typename Visitor, typename Visitables, typename... Values>
31 inline one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... >
32 make_one_by_one_visitor_and_value_referer_cpp14(
33 Visitor& visitor, Visitables visitables, std::tuple<Values...> values
34 )
35 {
36 return one_by_one_visitor_and_value_referer_cpp14<Visitor, Visitables, Values... > (
37 visitor, visitables, values
38 );
39 }
40
41 template <typename Visitor, typename Visitables, typename... Values>
42 class one_by_one_visitor_and_value_referer_cpp14
43 {
44 Visitor& visitor_;
45 std::tuple<Values...> values_;
46 Visitables visitables_;
47
48 public: // structors
49 one_by_one_visitor_and_value_referer_cpp14(
50 Visitor& visitor, Visitables visitables, std::tuple<Values...> values
51 ) BOOST_NOEXCEPT
52 : visitor_(visitor)
53 , values_(values)
54 , visitables_(visitables)
55 {}
56
57 public: // visitor interfaces
58 template <typename Value>
59 decltype(auto) operator()(Value&& value) const
60 {
61 return ::boost::apply_visitor(
62 make_one_by_one_visitor_and_value_referer_cpp14(
63 visitor_,
64 tuple_tail(visitables_),
65 std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value)))
66 )
67 , unwrap(std::get<0>(visitables_)) // getting Head element
68 );
69 }
70
71 private:
72 one_by_one_visitor_and_value_referer_cpp14& operator=(const one_by_one_visitor_and_value_referer_cpp14&);
73 };
74
75 template <typename Visitor, typename... Values>
76 class one_by_one_visitor_and_value_referer_cpp14<Visitor, std::tuple<>, Values...>
77 {
78 Visitor& visitor_;
79 std::tuple<Values...> values_;
80
81 public:
82 one_by_one_visitor_and_value_referer_cpp14(
83 Visitor& visitor, std::tuple<> /*visitables*/, std::tuple<Values...> values
84 ) BOOST_NOEXCEPT
85 : visitor_(visitor)
86 , values_(values)
87 {}
88
89 template <class Tuple, std::size_t... I>
90 decltype(auto) do_call(Tuple t, index_sequence<I...>) const {
91 return visitor_(unwrap(std::get<I>(t))...);
92 }
93
94 template <typename Value>
95 decltype(auto) operator()(Value&& value) const
96 {
97 return do_call(
98 std::tuple_cat(values_, std::make_tuple(wrap<Value, ! ::boost::is_lvalue_reference<Value>::value>(value))),
99 make_index_sequence<sizeof...(Values) + 1>()
100 );
101 }
102 };
103
104 }} // namespace detail::variant
105
106 template <class Visitor, class T1, class T2, class T3, class... TN>
107 inline decltype(auto) apply_visitor(const Visitor& visitor, T1&& v1, T2&& v2, T3&& v3, TN&&... vn,
108 typename boost::disable_if<
109 boost::detail::variant::has_result_type<Visitor>,
110 bool
111 >::type = true)
112 {
113 return boost::apply_visitor(
114 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
115 visitor,
116 std::make_tuple(
117 ::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
118 ::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
119 ::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
120 ),
121 std::tuple<>()
122 ),
123 ::boost::forward<T1>(v1)
124 );
125 }
126
127
128 template <class Visitor, class T1, class T2, class T3, class... TN>
129 inline decltype(auto) apply_visitor(Visitor& visitor, T1&& v1, T2&& v2, T3&& v3, TN&&... vn,
130 typename boost::disable_if<
131 boost::detail::variant::has_result_type<Visitor>,
132 bool
133 >::type = true)
134 {
135 return ::boost::apply_visitor(
136 ::boost::detail::variant::make_one_by_one_visitor_and_value_referer_cpp14(
137 visitor,
138 std::make_tuple(
139 ::boost::detail::variant::wrap<T2, ! ::boost::is_lvalue_reference<T2>::value>(v2),
140 ::boost::detail::variant::wrap<T3, ! ::boost::is_lvalue_reference<T3>::value>(v3),
141 ::boost::detail::variant::wrap<TN, ! ::boost::is_lvalue_reference<TN>::value>(vn)...
142 ),
143 std::tuple<>()
144 ),
145 ::boost::forward<T1>(v1)
146 );
147 }
148
149 } // namespace boost
150
151 #endif // BOOST_VARIANT_DETAIL_MULTIVISITORS_CPP14_BASED_HPP
152