Loading [MathJax]/extensions/tex2jax.js
Radium Engine  1.5.28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DynamicVisitor.hpp
1#pragma once
2#include <Core/RaCore.hpp>
3
4#include <Core/Containers/DynamicVisitorBase.hpp>
5#include <Core/Containers/VariableSet.hpp>
6#include <Core/Utils/Log.hpp>
7#include <Core/Utils/StdExperimentalTypeTraits.hpp>
8#include <Core/Utils/StdOptional.hpp>
9#include <Core/Utils/TypesUtils.hpp>
10
11#include <any>
12#include <functional>
13#include <typeindex>
14#include <unordered_map>
15
16namespace Ra {
17namespace Core {
18
28class RA_CORE_API DynamicVisitor : public DynamicVisitorBase
29{
30 public:
32 ~DynamicVisitor() override = default;
33
40 void operator()( const std::string& name, std::any&& in, std::any&& userParam ) const override;
41
45 [[nodiscard]] bool accept( const std::type_index& id ) const override;
46
54 template <typename T, typename F>
55 bool addOperator( F&& f );
56
60 template <typename T>
61 bool hasOperator();
62
69 template <typename T, typename F>
70 void addOrReplaceOperator( F&& f );
71
76 template <typename T>
77 bool removeOperator();
78
79 private:
81 using CallbackFunction = std::function<void( const std::string& name, std::any&, std::any&& )>;
82
85
86 template <typename T, typename F>
87 using WithParam =
88 std::enable_if_t<std::is_invocable<F, const std::string&, T&, std::any&&>::value, bool>;
89 template <typename T, typename F>
90 using WithoutParam =
91 std::enable_if_t<std::is_invocable<F, const std::string&, T&>::value, bool>;
92
95 template <typename T, typename F, WithParam<T, F> = true>
96 auto makeVisitorOperator( F& f ) -> OperatorsStorageType::value_type;
97 template <typename T, typename F, WithoutParam<T, F> = true>
98 auto makeVisitorOperator( F& f ) -> OperatorsStorageType::value_type;
99
101 OperatorsStorageType m_visitorOperator;
102};
103
104template <typename T, typename F>
106 auto [it, inserted] = m_visitorOperator.insert( makeVisitorOperator<T, F>( f ) );
107 return inserted;
108}
109
110template <typename T>
112 return m_visitorOperator.find( VariableSet::getVariableVisitTypeIndex<T>() ) !=
113 m_visitorOperator.end();
114}
115
116template <typename T, typename F>
118 auto op = makeVisitorOperator<T, F>( f );
119 m_visitorOperator.insert_or_assign( op.first, op.second );
120}
121
122template <typename T>
124 assert( hasOperator<T>() );
125 auto res = m_visitorOperator.erase( VariableSet::getVariableVisitTypeIndex<T>() ) > 0;
126 return res;
127}
128
129template <typename T, typename F, DynamicVisitor::WithParam<T, F>>
130auto DynamicVisitor::makeVisitorOperator( F& f ) -> OperatorsStorageType::value_type {
131 return { // type index
132 VariableSet::getVariableVisitTypeIndex<T>(),
133 // callback
134 [&f]( const std::string& name, std::any& a, std::any&& userParam ) {
135 auto rp = std::any_cast<std::reference_wrapper<T>>( a );
136 auto& p = rp.get();
137 f( name, p, std::forward<std::any>( userParam ) );
138 } };
139}
140template <typename T, typename F, DynamicVisitor::WithoutParam<T, F>>
141auto DynamicVisitor::makeVisitorOperator( F& f ) -> OperatorsStorageType::value_type {
142 return { // type index
143 VariableSet::getVariableVisitTypeIndex<T>(),
144 // callback
145 [&f]( const std::string& name, std::any& a, std::any&& ) {
146 auto rp = std::any_cast<std::reference_wrapper<T>>( a );
147 auto& p = rp.get();
148 f( name, p );
149 } };
150}
151} // namespace Core
152} // namespace Ra
Base class for dynamically configurable visitors Users can implement this interface to build custom v...
Base class for visitors with configurable per-type callbacks. Visiting will be prepared at running ti...
bool addOperator(F &&f)
Add a visiting operator.
~DynamicVisitor() override=default
allows the class to be derived
void addOrReplaceOperator(F &&f)
Add or replace a visiting operator.
bool removeOperator()
Remove a visiting operator.
bool hasOperator()
Test the existence of an operator associated with a type.
T end(T... args)
T erase(T... args)
T find(T... args)
T forward(T... args)
T insert(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4