Program Listing for File visitor.hpp
↰ Return to documentation for file (rcppsw/patterns/visitor/visitor.hpp
)
#pragma once
/*******************************************************************************
* Includes
******************************************************************************/
#include <utility>
#include <boost/variant/static_visitor.hpp>
#include "rcppsw/rcppsw.hpp"
#include "rcppsw/mpl/typelist.hpp"
/*******************************************************************************
* Namespaces/Decls
******************************************************************************/
namespace rcppsw::patterns::visitor {
/*******************************************************************************
* Class Definitions
******************************************************************************/
namespace detail {
template <typename T>
class visit_set_helper {
public:
virtual void visit(T& visitee) = 0;
virtual ~visit_set_helper(void) = default;
};
} /* namespace detail */
template <typename... Ts>
class visit_set {};
template<typename T, typename... Ts>
class visit_set<T, Ts...>: public detail::visit_set_helper<T>,
public visit_set<Ts...> {
public:
using detail::visit_set_helper<T>::visit;
using visit_set<Ts...>::visit;
};
template<typename T>
class visit_set<T>: public detail::visit_set_helper<T> {
public:
using detail::visit_set_helper<T>::visit;
};
template<typename ...Args>
using precise_visit_set = mpl::typelist<Args...>;
template <typename VisitorImpl, typename TypeList>
class precise_visitor : public VisitorImpl,
protected boost::static_visitor<void> {
public:
using VisitorImpl::VisitorImpl;
template <typename... Args>
explicit precise_visitor(Args&&... args)
: VisitorImpl(std::forward<Args>(args)...) {}
template <typename T,
RCPPSW_SFINAE_TYPELIST_REQUIRE(TypeList, T),
typename ...Args>
void visit(T& visitee, Args&&... args) {
VisitorImpl::visit(visitee, std::forward<Args>(args)...);
}
};
template<typename TVisitor>
class filtered_visitor {
public:
using visitor_type = TVisitor;
template<typename...Args>
explicit filtered_visitor(Args&& ...args)
: m_impl(std::forward<Args>(args)...) {}
template<typename TAny, typename ...Args>
void visit(TAny& obj, Args&&... args) {
m_impl.visit(obj, std::forward<Args>(args)...);
}
private:
precise_visitor<TVisitor, typename TVisitor::visit_typelist> m_impl;
};
} /* namespace visitor::patterns::rcppsw */