102 template <
typename T>
106 template <
typename T>
114 template <
typename T>
120 template <
typename H>
126 VariableSet() : m_vtable( VariableSetFunctions::getInstance() ) {}
130 m_vtable( VariableSetFunctions::getInstance() ) {
157 void mergeKeepVariables(
const VariableSet& from );
163 void mergeReplaceVariables(
const VariableSet& from );
182 template <
typename T>
183 auto insertVariable(
const std::string& name,
const T& value )
190 template <
typename T>
191 auto getVariable(
const std::string& name )
const ->
const T&;
192 template <
typename T>
200 template <
typename T>
201 auto getVariableHandle(
const std::string& name )
const ->
const VariableHandle<T>;
207 template <
typename H>
208 bool isHandleValid(
const H& handle )
const;
213 template <
typename T>
221 template <
typename T>
231 template <
typename H>
232 bool deleteVariable( H& handle );
237 template <
typename T>
238 auto existsVariable(
const std::string& name )
const -> Utils::optional<VariableHandle<T>>;
252 template <
typename T>
260 template <typename T>
261 bool deleteAllVariables();
268 template <typename T>
277 template <typename H>
278 auto getAllVariablesFromHandle( const H& handle )
284 template <typename T>
285 size_t numberOf() const;
295 template <typename... TYPES>
297 using types = Utils::TypeList<TYPES...>;
310 template <
typename F>
311 void visit( F&& visitor )
const;
314 template <
typename F,
typename T>
315 void visit( F&& visitor, T& userParams )
const;
318 template <
typename F,
typename T>
319 void visit( F&& visitor, T&& userParams )
const;
345 template <
typename P =
bool>
365 template <
typename F>
366 void visitStatic( F&& visitor )
const;
369 template <
typename F,
typename T>
370 void visitStatic( F&& visitor, T& userParams )
const;
373 template <
typename F,
typename T>
374 void visitStatic( F&& visitor, T&& userParams )
const;
382 template <
typename T>
384 template <
typename VariableType>
395 template <
typename T>
396 auto addVariableType() -> Utils::optional<VariableContainer<T>*>;
401 template <
typename F,
typename T>
402 using VisitFunction =
407 template <
typename F,
typename T,
typename U>
408 using VisitFunctionWithUserParam =
414 template <
typename F,
typename T>
415 static constexpr bool has_visit_callable_v =
416 Ra::Core::Utils::is_detected<VisitFunction, F, T>::value;
419 template <
typename F,
typename T,
typename U>
420 static constexpr bool has_visit_callable_with_user_param_v =
421 Ra::Core::Utils::is_detected<VisitFunctionWithUserParam, F, T, U>::value;
424 template <
typename F,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
425 void visitImpl( F&& visitor, TYPESLIST<TYPES...> )
const;
427 template <
typename F,
typename T>
428 void visitImplHelper( F& visitor )
const;
431 template <
typename F,
typename U,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
432 void visitImplUserParam( F&& visitor, U&& userParam, TYPESLIST<TYPES...> )
const;
434 template <
typename F,
typename U,
typename T>
435 void visitImplHelperUserParam( F& visitor, U&& userParams )
const;
444 class VariableSetFunctions
451 using VisitFunctorType =
456 VariableSetFunctions(
const VariableSetFunctions& ) =
delete;
457 void operator=(
const VariableSetFunctions& ) =
delete;
460 VariableSetFunctions() =
default;
461 ~VariableSetFunctions() =
default;
465 static auto getInstance() -> VariableSetFunctions*;
474 VariableSetFunctions* m_vtable;
489 template <
typename T>
490 auto createVariableStorage() -> VariableContainer<T>*;
495 template <
typename T>
496 auto getVariableStorage() const -> VariableContainer<T>&;
500 template <typename T>
501 void removeVariableStorage();
512auto
VariableSet::createVariableStorage() -> VariableContainer<T>* {
514 return std::any_cast<VariableContainer<T>>( &( m_variables[
std::type_index {
typeid( T ) }] ) );
518auto VariableSet::getVariableStorage() const -> VariableContainer<T>& {
519 assert( existsVariableType<T>() );
520 return std::any_cast<VariableContainer<T>&>( m_variables[
std::type_index {
typeid( T ) }] );
524void VariableSet::removeVariableStorage() {
526 m_variables.
erase( type );
527 m_typeIndexToVtableIndex.
erase( type );
530 m_storedType.
erase( newEnd, m_storedType.
end() );
537auto VariableSet::insertVariable(
const std::string& name,
const T& value )
539 auto typeAccess = existsVariableType<T>();
541 if ( !typeAccess ) { typeAccess = addVariableType<T>(); }
543 return ( *typeAccess )->insert( { name, value } );
537auto VariableSet::insertVariable(
const std::string& name,
const T& value ) {
…}
547auto VariableSet::getVariable(
const std::string& name ) -> T& {
552auto VariableSet::getVariable(
const std::string& name )
const ->
const T& {
553 return getVariableHandle<T>( name )->second;
552auto VariableSet::getVariable(
const std::string& name )
const ->
const T& {
…}
558 assert( existsVariableType<T>() );
559 return getVariableStorage<T>().find( name );
563bool VariableSet::isHandleValid(
const H& handle )
const {
565 return handle != getVariableStorage<VariableTypeFromHandle<H>>().end();
563bool VariableSet::isHandleValid(
const H& handle )
const {
…}
569auto VariableSet::setVariable(
const std::string& name,
const T& value )
571 auto typeAccess = existsVariableType<T>();
573 if ( !typeAccess ) { typeAccess = addVariableType<T>(); }
576 return ( *typeAccess )->insert_or_assign( name, value );
569auto VariableSet::setVariable(
const std::string& name,
const T& value ) {
…}
581 if (
auto typeAccess = existsVariableType<T>(); typeAccess ) {
582 auto removed = ( *typeAccess )->erase( name );
584 if ( numberOf<T>() == 0 ) { deleteAllVariables<T>(); }
591bool VariableSet::deleteVariable( H& handle ) {
592 assert( isHandleValid( handle ) );
593 auto varname = handle->first;
594 handle = getVariableStorage<VariableTypeFromHandle<H>>().end();
595 return deleteVariable<VariableTypeFromHandle<H>>( varname );
591bool VariableSet::deleteVariable( H& handle ) {
…}
600 -> Utils::optional<VariableHandle<T>> {
601 if (
auto typeAccess = existsVariableType<T>(); typeAccess ) {
602 auto itr = ( *typeAccess )->find( name );
603 if ( itr != ( *typeAccess )->cend() ) {
return itr; }
614auto VariableSet::addVariableType() -> Utils::optional<VariableContainer<T>*> {
615 auto storage = createVariableStorage<T>();
618 auto it =
std::find( m_vtable->m_storedType.begin(), m_vtable->m_storedType.end(), tidx );
621 m_typeIndexToVtableIndex[tidx] = it - m_vtable->m_storedType.begin();
625 if ( it == m_vtable->m_storedType.end() ) {
627 m_vtable->m_storedType.emplace_back( tidx );
629 m_vtable->m_mergeKeepFunctions.emplace_back(
632 if ( !toStorageAccess ) { toStorageAccess = to.addVariableType<T>(); }
633 auto& toStorage = *( toStorageAccess.value() );
634 auto& fromStorage = from.getVariableStorage<T>();
635 for (
const auto& t : fromStorage ) {
636 toStorage.insert( t );
640 m_vtable->m_mergeReplaceFunctions.emplace_back(
641 [](
const VariableSet& from, VariableSet& to ) {
642 auto toStorageAccess = to.existsVariableType<T>();
643 if ( !toStorageAccess ) { toStorageAccess = to.addVariableType<T>(); }
644 auto& toStorage = *( toStorageAccess.value() );
645 auto& fromStorage = from.getVariableStorage<T>();
646 for (
const auto& t : fromStorage ) {
647 toStorage.insert_or_assign( t.first, t.second );
651 m_vtable->m_sizeFunctions.emplace_back( [](
const VariableSet& c ) {
652 if (
auto cs = c.existsVariableType<T>(); cs )
return ( *cs )->size();
656 m_vtable->m_visitFunctions.emplace_back(
657 [](
const VariableSet& c,
const DynamicVisitorBase& v )
659 auto id = getVariableVisitTypeIndex<T>();
660 if ( v.accept(
id ) ) {
661 auto coll =
std::ref( c.getVariableStorage<T>() );
662 return {
true, [coll]( DynamicVisitorBase& visitor, std::any&& userParam ) {
663 for (
auto&& t : coll.get() ) {
665 std::any { std::ref( t.second ) },
670 else {
return {
false,
nullptr }; }
679 if ( iter == m_variables.
cend() ) {
return {}; }
680 else {
return std::any_cast<VariableSet::VariableContainer<T>>( &( iter->second ) ); }
684bool VariableSet::deleteAllVariables() {
685 if ( existsVariableType<T>() ) {
686 removeVariableStorage<T>();
684bool VariableSet::deleteAllVariables() {
…}
696 assert( existsVariableType<T>() );
698 return getVariableStorage<T>();
702auto VariableSet::getAllVariablesFromHandle(
const H& )
705 return getVariableStorage<VariableTypeFromHandle<H>>();
702auto VariableSet::getAllVariablesFromHandle(
const H& ) {
…}
709size_t VariableSet::numberOf()
const {
710 if (
auto variables = existsVariableType<T>(); variables ) {
return ( *variables )->size(); }
709size_t VariableSet::numberOf()
const {
…}
718 for (
const auto& [type, index] : m_typeIndexToVtableIndex ) {
719 auto [accepted, loop] = m_vtable->m_visitFunctions[index]( *
this, visitor );
725void VariableSet::visitStatic( F&& visitor )
const {
726 visitImpl( visitor,
typename std::decay_t<F>::types {} );
729template <
typename F,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
730void VariableSet::visitImpl( F&& visitor, TYPESLIST<TYPES...> )
const {
731 ( ..., visitImplHelper<std::decay_t<F>, TYPES>( visitor ) );
734template <
typename F,
typename T>
735void VariableSet::visitImplHelper( F& visitor )
const {
736 static_assert( has_visit_callable_v<F, T>,
737 "Static visitors must provide a function with profile "
738 "void( const std::string& name, [const ]T[&] value) for each "
739 "declared visitable type T" );
740 if (
auto variables = existsVariableType<T>() ) {
741 for (
auto& element : *( variables.value() ) ) {
742 visitor( element.first, element.second );
746 for (
auto& element : *( variables.value() ) ) {
747 visitor( element.first, element.second.get() );
752template <
typename F,
typename U>
753void VariableSet::visitStatic( F&& visitor, U& userParams )
const {
755 visitor,
std::forward<U>( userParams ),
typename std::decay_t<F>::types {} );
758template <
typename F,
typename U>
759void VariableSet::visitStatic( F&& visitor, U&& userParams )
const {
761 visitor,
std::forward<U>( userParams ),
typename std::decay_t<F>::types {} );
764template <
typename F,
typename U,
template <
typename...>
typename TYPESLIST,
typename... TYPES>
765void VariableSet::visitImplUserParam( F&& visitor, U&& userParam, TYPESLIST<TYPES...> )
const {
767 visitImplHelperUserParam<std::decay_t<F>, U, TYPES>( visitor,
771template <
typename F,
typename U,
typename T>
772void VariableSet::visitImplHelperUserParam( F& visitor, U&& userParams )
const {
773 static_assert( has_visit_callable_with_user_param_v<F, T, U>,
774 "Static visitors must provide a function with profile "
775 "void( const std::string& name, [const ]T[&] value, [const] U&&) for each "
776 "declared visitable type T" );
777 if (
auto variables = existsVariableType<T>(); variables ) {
778 for (
auto& element : *( variables.value() ) ) {
779 visitor( element.first, element.second,
std::forward<U>( userParams ) );
783 for (
auto& element : *( variables.value() ) ) {
784 visitor( element.first, element.second.get(),
std::forward<U>( userParams ) );
790inline void VariableSet::visit( F&& visitor )
const {
792 visitDynamic( visitor );
794 else { visitStatic( visitor ); }
790inline void VariableSet::visit( F&& visitor )
const {
…}
797template <
typename F,
typename T>
798inline void VariableSet::visit( F&& visitor, T& userParams )
const {
798inline void VariableSet::visit( F&& visitor, T& userParams )
const {
…}
805template <
typename F,
typename T>
806inline void VariableSet::visit( F&& visitor, T&& userParams )
const {
806inline void VariableSet::visit( F&& visitor, T&& userParams )
const {
…}