// Boost.Varaint // Multivisitors defined here // // See http://www.boost.org for most recent version, including documentation. // // Copyright Antony Polukhin, 2013. // // Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). #ifndef BOOST_VARIANT_MULTIVISITORS_HPP #define BOOST_VARIANT_MULTIVISITORS_HPP #if defined(_MSC_VER) # pragma once #endif #include #include #include #include #include #include #ifndef BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS # define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 4 #endif namespace boost { namespace detail { namespace variant { template struct two_variables_holder { private: VisitorT& visitor_; Visitable1T& visitable1_; Visitable2T& visitable2_; // required to supress warnings and enshure that we do not copy // this visitor two_variables_holder& operator=(const two_variables_holder&); public: typedef BOOST_DEDUCED_TYPENAME VisitorT::result_type result_type; explicit two_variables_holder(VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2) BOOST_NOEXCEPT : visitor_(visitor) , visitable1_(visitable1) , visitable2_(visitable2) {} #define BOOST_VARIANT_OPERATOR_BEG() \ return ::boost::apply_visitor( \ ::boost::bind(boost::ref(visitor_), _1, _2 \ /**/ #define BOOST_VARIANT_OPERATOR_END() \ ), visitable1_, visitable2_); \ /**/ #define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data) \ BOOST_PP_COMMA() boost::ref( BOOST_PP_CAT(vis, n) ) \ /**/ #define BOOST_VARIANT_VISIT(z, n, data) \ template \ BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) operator()( \ BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 1), VisitableUnwrapped, & vis) \ ) const \ { \ BOOST_VARIANT_OPERATOR_BEG() \ BOOST_PP_REPEAT(BOOST_PP_ADD(n, 1), BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~) \ BOOST_VARIANT_OPERATOR_END() \ } \ /**/ BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, ~) #undef BOOST_VARIANT_OPERATOR_BEG #undef BOOST_VARIANT_OPERATOR_END #undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER #undef BOOST_VARIANT_VISIT }; template inline two_variables_holder make_two_variables_holder( VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2 ) BOOST_NOEXCEPT { return two_variables_holder(visitor, visitable1, visitable2); } template inline two_variables_holder make_two_variables_holder( const VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2 ) BOOST_NOEXCEPT { return two_variables_holder(visitor, visitable1, visitable2); } }} // namespace detail::variant #define BOOST_VARIANT_APPLY_VISITOR_BEG() \ return ::boost::apply_visitor( \ boost::detail::variant::make_two_variables_holder(visitor, var0 , var1), \ var2 \ /**/ #define BOOST_VARIANT_APPLY_VISITOR_END() \ ); \ /**/ #define BOOST_VARANT_VISITORS_VARIABLES_PRINTER(z, n, data) \ BOOST_PP_COMMA() BOOST_PP_CAT(var, BOOST_PP_ADD(n, 3)) \ /**/ #define BOOST_VARIANT_VISIT(z, n, data) \ template \ inline BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(BOOST_DEDUCED_TYPENAME Visitor::result_type) apply_visitor( \ data BOOST_PP_COMMA() BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ADD(n, 3), T, & var) \ ) \ { \ BOOST_VARIANT_APPLY_VISITOR_BEG() \ BOOST_PP_REPEAT(n, BOOST_VARANT_VISITORS_VARIABLES_PRINTER, ~) \ BOOST_VARIANT_APPLY_VISITOR_END() \ } \ /**/ BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, const Visitor& visitor) BOOST_PP_REPEAT( BOOST_PP_SUB(BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS, 2), BOOST_VARIANT_VISIT, Visitor& visitor) #undef BOOST_VARIANT_APPLY_VISITOR_BEG #undef BOOST_VARIANT_APPLY_VISITOR_END #undef BOOST_VARANT_VISITORS_VARIABLES_PRINTER #undef BOOST_VARIANT_VISIT } // namespace boost #endif // BOOST_VARIANT_MULTIVISITORS_HPP