diff options
Diffstat (limited to 'boost/variant/multivisitors.hpp')
-rw-r--r-- | boost/variant/multivisitors.hpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/boost/variant/multivisitors.hpp b/boost/variant/multivisitors.hpp new file mode 100644 index 0000000000..0f1988c00b --- /dev/null +++ b/boost/variant/multivisitors.hpp @@ -0,0 +1,143 @@ +// 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 <boost/variant.hpp> +#include <boost/bind.hpp> + +#include <boost/preprocessor/repetition.hpp> +#include <boost/preprocessor/punctuation/comma_if.hpp> +#include <boost/preprocessor/arithmetic/add.hpp> +#include <boost/preprocessor/arithmetic/sub.hpp> + +#ifndef BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS +# define BOOST_VARAINT_MAX_MULTIVIZITOR_PARAMS 4 +#endif + +namespace boost { + +namespace detail { namespace variant { + + template <class VisitorT, class Visitable1T, class Visitable2T> + 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<result_type>(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_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 1), class VisitableUnwrapped)> \ + 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 <class VisitorT, class Visitable1T, class Visitable2T> + inline two_variables_holder<VisitorT, Visitable1T, Visitable2T> make_two_variables_holder( + VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2 + ) BOOST_NOEXCEPT + { + return two_variables_holder<VisitorT, Visitable1T, Visitable2T>(visitor, visitable1, visitable2); + } + + template <class VisitorT, class Visitable1T, class Visitable2T> + inline two_variables_holder<const VisitorT, Visitable1T, Visitable2T> make_two_variables_holder( + const VisitorT& visitor, Visitable1T& visitable1, Visitable2T& visitable2 + ) BOOST_NOEXCEPT + { + return two_variables_holder<const VisitorT, Visitable1T, Visitable2T>(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 <class Visitor BOOST_PP_COMMA() BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n, 3), class T)> \ + 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 + |