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