File indexing completed on 2025-01-30 10:02:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
0014 #define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
0015
0016 #include <boost/config.hpp>
0017
0018 #include <boost/variant/detail/apply_visitor_unary.hpp>
0019
0020 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
0021 # include <boost/variant/detail/has_result_type.hpp>
0022 #endif
0023
0024 #include <boost/core/enable_if.hpp>
0025 #include <boost/type_traits/is_lvalue_reference.hpp>
0026 #include <boost/type_traits/is_same.hpp>
0027 #include <utility>
0028
0029 namespace boost {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 namespace detail { namespace variant {
0040
0041 template <typename Visitor, typename Value1, bool MoveSemantics>
0042 class apply_visitor_binary_invoke
0043 {
0044 public:
0045
0046 typedef typename Visitor::result_type
0047 result_type;
0048
0049 private:
0050
0051 Visitor& visitor_;
0052 Value1& value1_;
0053
0054 public:
0055
0056 apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
0057 : visitor_(visitor)
0058 , value1_(value1)
0059 {
0060 }
0061
0062 public:
0063
0064 template <typename Value2>
0065 typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
0066 operator()(Value2&& value2)
0067 {
0068 return visitor_(std::move(value1_), std::forward<Value2>(value2));
0069 }
0070
0071 template <typename Value2>
0072 typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, result_type>::type
0073 operator()(Value2&& value2)
0074 {
0075 return visitor_(value1_, std::forward<Value2>(value2));
0076 }
0077
0078 private:
0079 apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
0080 };
0081
0082 template <typename Visitor, typename Visitable2, bool MoveSemantics>
0083 class apply_visitor_binary_unwrap
0084 {
0085 public:
0086
0087 typedef typename Visitor::result_type
0088 result_type;
0089
0090 private:
0091
0092 Visitor& visitor_;
0093 Visitable2& visitable2_;
0094
0095 public:
0096
0097 apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
0098 : visitor_(visitor)
0099 , visitable2_(visitable2)
0100 {
0101 }
0102
0103 public:
0104
0105 template <typename Value1>
0106 typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
0107 operator()(Value1&& value1)
0108 {
0109 apply_visitor_binary_invoke<
0110 Visitor
0111 , Value1
0112 , ! ::boost::is_lvalue_reference<Value1>::value
0113 > invoker(visitor_, value1);
0114
0115 return boost::apply_visitor(invoker, std::move(visitable2_));
0116 }
0117
0118 template <typename Value1>
0119 typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, result_type>::type
0120 operator()(Value1&& value1)
0121 {
0122 apply_visitor_binary_invoke<
0123 Visitor
0124 , Value1
0125 , ! ::boost::is_lvalue_reference<Value1>::value
0126 > invoker(visitor_, value1);
0127
0128 return boost::apply_visitor(invoker, visitable2_);
0129 }
0130
0131 private:
0132 apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
0133
0134 };
0135
0136 }}
0137
0138
0139
0140
0141
0142 template <typename Visitor, typename Visitable1, typename Visitable2>
0143 inline typename Visitor::result_type
0144 apply_visitor( Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2)
0145 {
0146 ::boost::detail::variant::apply_visitor_binary_unwrap<
0147 Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
0148 > unwrapper(visitor, visitable2);
0149
0150 return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
0151 }
0152
0153
0154
0155
0156
0157
0158 template <typename Visitor, typename Visitable1, typename Visitable2>
0159 inline typename Visitor::result_type
0160 apply_visitor( const Visitor& visitor , Visitable1&& visitable1 , Visitable2&& visitable2)
0161 {
0162 ::boost::detail::variant::apply_visitor_binary_unwrap<
0163 const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
0164 > unwrapper(visitor, visitable2);
0165
0166 return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
0167 }
0168
0169
0170 #if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
0171
0172
0173
0174
0175
0176
0177
0178 namespace detail { namespace variant {
0179
0180 template <typename Visitor, typename Value1, bool MoveSemantics>
0181 class apply_visitor_binary_invoke_cpp14
0182 {
0183 Visitor& visitor_;
0184 Value1& value1_;
0185
0186 public:
0187
0188 apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
0189 : visitor_(visitor)
0190 , value1_(value1)
0191 {
0192 }
0193
0194 public:
0195
0196 template <typename Value2>
0197 decltype(auto) operator()(Value2&& value2, typename enable_if_c<MoveSemantics && is_same<Value2, Value2>::value, bool>::type = true)
0198 {
0199 return visitor_(std::move(value1_), std::forward<Value2>(value2));
0200 }
0201
0202 template <typename Value2>
0203 decltype(auto) operator()(Value2&& value2, typename disable_if_c<MoveSemantics && is_same<Value2, Value2>::value, bool>::type = true)
0204 {
0205 return visitor_(value1_, std::forward<Value2>(value2));
0206 }
0207
0208 private:
0209 apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
0210 };
0211
0212 template <typename Visitor, typename Visitable2, bool MoveSemantics>
0213 class apply_visitor_binary_unwrap_cpp14
0214 {
0215 Visitor& visitor_;
0216 Visitable2& visitable2_;
0217
0218 public:
0219
0220 apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
0221 : visitor_(visitor)
0222 , visitable2_(visitable2)
0223 {
0224 }
0225
0226 public:
0227
0228 template <typename Value1>
0229 decltype(auto) operator()(Value1&& value1, typename enable_if_c<MoveSemantics && is_same<Value1, Value1>::value, bool>::type = true)
0230 {
0231 apply_visitor_binary_invoke_cpp14<
0232 Visitor
0233 , Value1
0234 , ! ::boost::is_lvalue_reference<Value1>::value
0235 > invoker(visitor_, value1);
0236
0237 return boost::apply_visitor(invoker, std::move(visitable2_));
0238 }
0239
0240 template <typename Value1>
0241 decltype(auto) operator()(Value1&& value1, typename disable_if_c<MoveSemantics && is_same<Value1, Value1>::value, bool>::type = true)
0242 {
0243 apply_visitor_binary_invoke_cpp14<
0244 Visitor
0245 , Value1
0246 , ! ::boost::is_lvalue_reference<Value1>::value
0247 > invoker(visitor_, value1);
0248
0249 return boost::apply_visitor(invoker, visitable2_);
0250 }
0251
0252 private:
0253 apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&);
0254 };
0255
0256 }}
0257
0258 template <typename Visitor, typename Visitable1, typename Visitable2>
0259 inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
0260 typename boost::disable_if<
0261 boost::detail::variant::has_result_type<Visitor>,
0262 bool
0263 >::type = true)
0264 {
0265 ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
0266 Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
0267 > unwrapper(visitor, visitable2);
0268
0269 return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
0270 }
0271
0272 template <typename Visitor, typename Visitable1, typename Visitable2>
0273 inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1&& visitable1, Visitable2&& visitable2,
0274 typename boost::disable_if<
0275 boost::detail::variant::has_result_type<Visitor>,
0276 bool
0277 >::type = true)
0278 {
0279 ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
0280 const Visitor, Visitable2, ! ::boost::is_lvalue_reference<Visitable2>::value
0281 > unwrapper(visitor, visitable2);
0282
0283 return boost::apply_visitor(unwrapper, std::forward<Visitable1>(visitable1));
0284 }
0285
0286
0287 #endif
0288
0289 }
0290
0291 #endif