103 template <
typename T>
107 template <
typename T>
115 template <
typename T>
121 template <
typename H>
127 VariableSet() : m_vtable( VariableSetFunctions::getInstance() ) {}
131 m_vtable( VariableSetFunctions::getInstance() ) {
158 void mergeKeepVariables(
const VariableSet& from );
164 void mergeReplaceVariables(
const VariableSet& from );
183 template <
typename T>
184 auto insertVariable(
const std::string& name,
const T& value )
191 template <
typename T>
192 auto getVariable(
const std::string& name )
const ->
const T&;
193 template <
typename T>
201 template <
typename T>
202 auto getVariableHandle(
const std::string& name )
const ->
const VariableHandle<T>;
208 template <
typename H>
209 bool isHandleValid(
const H& handle )
const;
214 template <
typename T>
222 template <
typename T>
232 template <
typename H>
233 bool deleteVariable( H& handle );
238 template <
typename T>
239 auto existsVariable(
const std::string& name )
const -> Utils::optional<VariableHandle<T>>;
253 template <
typename T>
261 template <typename T>
262 bool deleteAllVariables();
269 template <typename T>
278 template <typename H>
279 auto getAllVariablesFromHandle( const H& handle )
285 template <typename T>
286 size_t numberOf() const;
296 template <typename... TYPES>
298 using types = Utils::TypeList<TYPES...>;
311 template <
typename F>
312 void visit( F&& visitor )
const;
315 template <
typename F,
typename T>
316 void visit( F&& visitor, T& userParams )
const;
319 template <
typename F,
typename T>
320 void visit( F&& visitor, T&& userParams )
const;
346 template <
typename P =
bool>
366 template <
typename F>
367 void visitStatic( F&& visitor )
const;
370 template <
typename F,
typename T>
371 void visitStatic( F&& visitor, T& userParams )
const;
374 template <
typename F,
typename T>
375 void visitStatic( F&& visitor, T&& userParams )
const;
383 template <
typename T>
385 template <
typename VariableType>
396 template <
typename T>
397 auto addVariableType() -> Utils::optional<VariableContainer<T>*>;
402 template <
typename F,
typename T>
403 using VisitFunction =
408 template <
typename F,
typename T,
typename U>
409 using VisitFunctionWithUserParam =
415 template <
typename F,
typename T>
416 static constexpr bool has_visit_callable_v =
417 Ra::Core::Utils::is_detected<VisitFunction, F, T>::value;
420 template <
typename F,
typename T,
typename U>
421 static constexpr bool has_visit_callable_with_user_param_v =
422 Ra::Core::Utils::is_detected<VisitFunctionWithUserParam, F, T, U>::value;
425 template <
typename F,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
426 void visitImpl( F&& visitor, TYPESLIST<TYPES...> )
const;
428 template <
typename F,
typename T>
429 void visitImplHelper( F& visitor )
const;
432 template <
typename F,
typename U,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
433 void visitImplUserParam( F&& visitor, U&& userParam, TYPESLIST<TYPES...> )
const;
435 template <
typename F,
typename U,
typename T>
436 void visitImplHelperUserParam( F& visitor, U&& userParams )
const;
445 class VariableSetFunctions
452 using VisitFunctorType =
457 VariableSetFunctions(
const VariableSetFunctions& ) =
delete;
458 void operator=(
const VariableSetFunctions& ) =
delete;
461 VariableSetFunctions() =
default;
462 ~VariableSetFunctions() =
default;
466 static auto getInstance() -> VariableSetFunctions*;
475 VariableSetFunctions* m_vtable;
490 template <
typename T>
491 auto createVariableStorage() -> VariableContainer<T>*;
496 template <
typename T>
497 auto getVariableStorage() const -> VariableContainer<T>&;
501 template <typename T>
502 void removeVariableStorage();
513auto
VariableSet::createVariableStorage() -> VariableContainer<T>* {
515 return std::any_cast<VariableContainer<T>>( &( m_variables[
std::type_index {
typeid( T ) }] ) );
519auto VariableSet::getVariableStorage() const -> VariableContainer<T>& {
520 assert( existsVariableType<T>() );
521 return std::any_cast<VariableContainer<T>&>( m_variables[
std::type_index {
typeid( T ) }] );
525void VariableSet::removeVariableStorage() {
527 m_variables.
erase( type );
528 m_typeIndexToVtableIndex.
erase( type );
531 m_storedType.
erase( newEnd, m_storedType.
end() );
538auto VariableSet::insertVariable(
const std::string& name,
const T& value )
540 auto typeAccess = existsVariableType<T>();
542 if ( !typeAccess ) { typeAccess = addVariableType<T>(); }
544 return ( *typeAccess )->insert( { name, value } );
548auto VariableSet::getVariable(
const std::string& name ) -> T& {
553auto VariableSet::getVariable(
const std::string& name )
const ->
const T& {
554 return getVariableHandle<T>( name )->second;
559 assert( existsVariableType<T>() );
560 return getVariableStorage<T>().find( name );
564bool VariableSet::isHandleValid(
const H& handle )
const {
566 return handle != getVariableStorage<VariableTypeFromHandle<H>>().end();
570auto VariableSet::setVariable(
const std::string& name,
const T& value )
572 auto typeAccess = existsVariableType<T>();
574 if ( !typeAccess ) { typeAccess = addVariableType<T>(); }
577 return ( *typeAccess )->insert_or_assign( name, value );
582 if (
auto typeAccess = existsVariableType<T>(); typeAccess ) {
583 auto removed = ( *typeAccess )->erase( name );
585 if ( numberOf<T>() == 0 ) { deleteAllVariables<T>(); }
592bool VariableSet::deleteVariable( H& handle ) {
593 assert( isHandleValid( handle ) );
594 auto varname = handle->first;
595 handle = getVariableStorage<VariableTypeFromHandle<H>>().end();
596 return deleteVariable<VariableTypeFromHandle<H>>( varname );
601 -> Utils::optional<VariableHandle<T>> {
602 if (
auto typeAccess = existsVariableType<T>(); typeAccess ) {
603 auto itr = ( *typeAccess )->find( name );
604 if ( itr != ( *typeAccess )->cend() ) {
return itr; }
615auto VariableSet::addVariableType() -> Utils::optional<VariableContainer<T>*> {
616 auto storage = createVariableStorage<T>();
619 auto it =
std::find( m_vtable->m_storedType.begin(), m_vtable->m_storedType.end(), tidx );
622 m_typeIndexToVtableIndex[tidx] = it - m_vtable->m_storedType.begin();
626 if ( it == m_vtable->m_storedType.end() ) {
628 m_vtable->m_storedType.emplace_back( tidx );
630 m_vtable->m_mergeKeepFunctions.emplace_back(
633 if ( !toStorageAccess ) { toStorageAccess = to.addVariableType<T>(); }
634 auto& toStorage = *( toStorageAccess.value() );
635 auto& fromStorage = from.getVariableStorage<T>();
636 for (
const auto& t : fromStorage ) {
637 toStorage.insert( t );
641 m_vtable->m_mergeReplaceFunctions.emplace_back(
642 [](
const VariableSet& from, VariableSet& to ) {
643 auto toStorageAccess = to.existsVariableType<T>();
644 if ( !toStorageAccess ) { toStorageAccess = to.addVariableType<T>(); }
645 auto& toStorage = *( toStorageAccess.value() );
646 auto& fromStorage = from.getVariableStorage<T>();
647 for (
const auto& t : fromStorage ) {
648 toStorage.insert_or_assign( t.first, t.second );
652 m_vtable->m_sizeFunctions.emplace_back( [](
const VariableSet& c ) {
653 if (
auto cs = c.existsVariableType<T>(); cs )
return ( *cs )->size();
657 m_vtable->m_visitFunctions.emplace_back(
658 [](
const VariableSet& c,
const DynamicVisitorBase& v )
660 auto id = getVariableVisitTypeIndex<T>();
661 if ( v.accept(
id ) ) {
662 auto coll =
std::ref( c.getVariableStorage<T>() );
663 return {
true, [coll]( DynamicVisitorBase& visitor, std::any&& userParam ) {
664 for (
auto&& t : coll.get() ) {
666 std::any { std::ref( t.second ) },
671 else {
return {
false,
nullptr }; }
680 if ( iter == m_variables.
cend() ) {
return {}; }
681 else {
return std::any_cast<VariableSet::VariableContainer<T>>( &( iter->second ) ); }
685bool VariableSet::deleteAllVariables() {
686 if ( existsVariableType<T>() ) {
687 removeVariableStorage<T>();
697 assert( existsVariableType<T>() );
699 return getVariableStorage<T>();
703auto VariableSet::getAllVariablesFromHandle(
const H& )
706 return getVariableStorage<VariableTypeFromHandle<H>>();
710size_t VariableSet::numberOf()
const {
711 if (
auto variables = existsVariableType<T>(); variables ) {
return ( *variables )->size(); }
719 for (
const auto& [type, index] : m_typeIndexToVtableIndex ) {
720 auto [accepted, loop] = m_vtable->m_visitFunctions[index]( *
this, visitor );
726void VariableSet::visitStatic( F&& visitor )
const {
727 visitImpl( visitor,
typename std::decay_t<F>::types {} );
730template <
typename F,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
731void VariableSet::visitImpl( F&& visitor, TYPESLIST<TYPES...> )
const {
732 ( ..., visitImplHelper<std::decay_t<F>, TYPES>( visitor ) );
735template <
typename F,
typename T>
736void VariableSet::visitImplHelper( F& visitor )
const {
737 static_assert( has_visit_callable_v<F, T>,
738 "Static visitors must provide a function with profile "
739 "void( const std::string& name, [const ]T[&] value) for each "
740 "declared visitable type T" );
741 if (
auto variables = existsVariableType<T>() ) {
742 for (
auto& element : *( variables.value() ) ) {
743 visitor( element.first, element.second );
747 for (
auto& element : *( variables.value() ) ) {
748 visitor( element.first, element.second.get() );
753template <
typename F,
typename U>
754void VariableSet::visitStatic( F&& visitor, U& userParams )
const {
756 visitor,
std::forward<U>( userParams ),
typename std::decay_t<F>::types {} );
759template <
typename F,
typename U>
760void VariableSet::visitStatic( F&& visitor, U&& userParams )
const {
762 visitor,
std::forward<U>( userParams ),
typename std::decay_t<F>::types {} );
765template <
typename F,
typename U,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
766void VariableSet::visitImplUserParam( F&& visitor, U&& userParam, TYPESLIST<TYPES...> )
const {
768 visitImplHelperUserParam<std::decay_t<F>, U, TYPES>( visitor,
772template <
typename F,
typename U,
typename T>
773void VariableSet::visitImplHelperUserParam( F& visitor, U&& userParams )
const {
774 static_assert( has_visit_callable_with_user_param_v<F, T, U>,
775 "Static visitors must provide a function with profile "
776 "void( const std::string& name, [const ]T[&] value, [const] U&&) for each "
777 "declared visitable type T" );
778 if (
auto variables = existsVariableType<T>(); variables ) {
779 for (
auto& element : *( variables.value() ) ) {
780 visitor( element.first, element.second,
std::forward<U>( userParams ) );
784 for (
auto& element : *( variables.value() ) ) {
785 visitor( element.first, element.second.get(),
std::forward<U>( userParams ) );
791inline void VariableSet::visit( F&& visitor )
const {
793 visitDynamic( visitor );
795 else { visitStatic( visitor ); }
798template <
typename F,
typename T>
799inline void VariableSet::visit( F&& visitor, T& userParams )
const {
806template <
typename F,
typename T>
807inline void VariableSet::visit( F&& visitor, T&& userParams )
const {