3#include <mutable/mutable-config.hpp>
28template<
typename ConcreteVisitor,
typename Base>
34 static constexpr bool is_const = std::is_const_v<Base>;
44 using Const = std::conditional_t<is_const, const T, T>;
58template<
typename ConcreteVisitor,
typename Base,
typename Class,
typename... Classes>
63 using super::operator();
67template<
typename ConcreteVisitor,
typename Base,
typename Class>
72 using super::operator();
79template<
typename ConcreteVisitor,
typename Base,
typename... Hierarchy>
84 using super::operator();
90template<
typename Callable,
typename ResultType,
typename Visitor,
typename Class,
typename... Classes>
97 using super::operator();
98 void operator()(
typename Visitor::template Const<Class> &obj)
override {
99 if constexpr (std::is_same_v<void, ResultType>) { this->callable(obj); }
105template<
typename Callable,
typename ResultType,
typename Visitor,
typename Class>
113 using Visitor::operator();
115 if constexpr (std::is_same_v<void, ResultType>) { this->callable(obj); }
137template<
typename Callable,
typename Visitor,
typename Base,
typename... Hierarchy>
141 using result_type = std::common_type_t< std::invoke_result_t<Callable, typename Visitor::template Const<Hierarchy>&>... >;
143 std::optional<some<result_type>> result;
148 if constexpr (not std::is_same_v<void, result_type>) {
149 return std::move(V.result->value);
166#define M_MAKE_STL_VISITABLE(VISITOR, BASE_CLASS, CLASS_LIST) \
167 template<typename Callable> \
168 auto visit(Callable &&callable, BASE_CLASS &obj, m::tag<VISITOR>&& = m::tag<VISITOR>()) { \
169 return m::visit<Callable, VISITOR, BASE_CLASS CLASS_LIST(M_COMMA_PRE)>(std::forward<Callable>(callable), obj); \
181#define M_DECLARE_VISITOR(VISITOR_NAME, BASE_CLASS, CLASS_LIST) \
182 struct VISITOR_NAME : m::detail::VisitorImpl<VISITOR_NAME, BASE_CLASS CLASS_LIST(M_COMMA_PRE)> { \
183 using super = m::detail::VisitorImpl<VISITOR_NAME, BASE_CLASS CLASS_LIST(M_COMMA_PRE)>; \
184 using super::operator(); \
186 M_MAKE_STL_VISITABLE(VISITOR_NAME, BASE_CLASS, CLASS_LIST)
auto visit(Callable &&callable, Base &obj, m::tag< Callable > &&=m::tag< Callable >())
Generic implementation to visit a class hierarchy, with similar syntax as std::visit.
A helper class to define CRTP class hierarchies.
A helper class to define virtual visit methods for all classes in.
typename super::template Const< T > Const
Visitor base class, using CRTP.
virtual ~Visitor()
Make Visitor inheritable from.
virtual void operator()(base_type &obj)
Visit the object obj.
static constexpr bool is_const
Whether the visited objects are const-qualified.
std::conditional_t< is_const, const T, T > Const
A helper type to apply the proper const-qualification to parameters.
ConcreteVisitor visitor_type
The concrete type of the visitor.
Base base_type
The base class of the class hierarchy to visit.
std::optional< some< ResultType > > & result
void operator()(typename Visitor::template Const< Class > &obj) override
stl_visit_helper(Callable &callable, std::optional< some< ResultType > > &result)
This helper class creates a single override of operator() for one subtype in a class hierarchy,...
void operator()(typename Visitor::template Const< Class > &obj) override
stl_visit_helper(Callable &callable, std::optional< some< ResultType > > &result)
virtual void operator()(Const< Class > &)
typename super::template Const< T > Const
This helper class creates a single definition of virtual void operator()(...) for one subtype in a cl...
virtual void operator()(Const< Class > &)
typename super::template Const< T > Const
A helper type to wrap some template type parameter such that it can safely be used to declare a class...
Exception class which can be thrown to skip recursion of the subtree in pre-order visitors.
Exception class which can be thrown to stop entire recursion in visitors.