#ifndef SPROUT_VARIANT_AS_VISITOR_HPP #define SPROUT_VARIANT_AS_VISITOR_HPP #include #include #include #include #include #include #include #include #include #include namespace sprout { namespace detail { template struct result_type_or_void; template struct result_type_or_void< T, typename std::enable_if >::value>::type > { public: typedef typename sprout::weak_result_type::result_type type; }; template struct result_type_or_void< T, typename std::enable_if >::value>::type > { public: typedef void type; }; } // namespace detail // // visitor_wrapper // template< typename Visitor, typename R = typename sprout::detail::result_type_or_void::type > class visitor_wrapper : public sprout::static_visitor { public: typedef Visitor visitor_type; typedef sprout::value_holder holder_type; private: holder_type v_; public: SPROUT_CONSTEXPR explicit visitor_wrapper(typename holder_type::param_type v) : v_(v) {} template SPROUT_CONSTEXPR auto operator()(T&& t) const -> decltype(std::declval().get()(sprout::forward(t))) { return v_.get()(sprout::forward(t)); } }; // // as_visitor // template inline SPROUT_CONSTEXPR sprout::visitor_wrapper::type>::type> as_visitor(Visitor&& visitor) { typedef sprout::visitor_wrapper::type>::type> type; return type(sprout::lvalue_forward(visitor)); } template inline SPROUT_CONSTEXPR sprout::visitor_wrapper::type>::type, R> as_visitor(Visitor&& visitor) { typedef sprout::visitor_wrapper::type>::type, R> type; return type(sprout::lvalue_forward(visitor)); } } // namespace sprout #endif // #ifndef SPROUT_VARIANT_AS_VISITOR_HPP