#ifndef RFL_VISIT_HPP_ #define RFL_VISIT_HPP_ #include #include "Literal.hpp" #include "TaggedUnion.hpp" #include "internal/StringLiteral.hpp" #include "internal/VisitTree.hpp" #include "internal/VisitorWrapper.hpp" namespace rfl { template inline auto visit(const Visitor& _visitor, const Literal<_fields...> _literal, const Args&... _args) { constexpr int size = sizeof...(_fields); using WrapperType = internal::VisitorWrapper; const auto wrapper = WrapperType{&_visitor}; return internal::VisitTree::visit<0, size, WrapperType>( wrapper, _literal.value(), _args...); } template inline auto visit(F&& _f, V&& _v) -> decltype(std::declval().visit(std::declval())) { return std::forward(_v).visit(std::forward(_f)); } template inline auto visit(F&& _f, T&& _tagged_union) -> decltype(std::declval().variant().visit(std::declval())) { return std::forward(_tagged_union).variant().visit(std::forward(_f)); } template inline auto visit(F&& _f, Head&& _head, Tail&&... _tail) { const auto f_outer = [&](auto& _h) { const auto f_inner = [&](auto&... _t) { return std::forward(_f)(_h, _t...); }; return visit(f_inner, std::forward(_tail)...); }; return std::forward(_head).visit(f_outer); } } // namespace rfl #endif // RFL_VISIT_HPP_