Radium Engine  1.5.0
VariableSet.hpp
1 #pragma once
2 #include <Core/RaCore.hpp>
3 
4 #include <Core/Utils/Log.hpp>
5 #include <Core/Utils/StdExperimentalTypeTraits.hpp>
6 #include <Core/Utils/StdOptional.hpp>
7 #include <Core/Utils/TypesUtils.hpp>
8 
9 #include <any>
10 #include <functional>
11 #include <map>
12 #include <typeindex>
13 #include <unordered_map>
14 #include <vector>
15 
16 namespace Ra {
17 namespace Core {
18 
71 class RA_CORE_API VariableSet
72 {
73  public:
75  template <typename T>
76  using VariableContainer = std::map<std::string, T>;
77 
79  template <typename T>
81 
83  template <typename T>
85 
91  template <typename T>
93 
97  template <typename H>
98  using VariableTypeFromHandle = typename std::iterator_traits<H>::value_type::second_type;
99 
100  // ----------------------------------------------------------
103  VariableSet() : m_vtable( VariableSetFunctions::getInstance() ) {}
104  ~VariableSet() = default;
106  VariableSet( const VariableSet& other ) noexcept :
107  m_vtable( VariableSetFunctions::getInstance() ) {
108  *this = other;
109  }
111  VariableSet( VariableSet&& other ) noexcept : m_vtable( VariableSetFunctions::getInstance() ) {
112  *this = std::move( other );
113  }
115 
116  // ------------------------------------------------------------------------------------------
117  // Global variable set operation
118  // ------------------------------------------------------------------------------------------
122  auto operator=( const VariableSet& other ) -> VariableSet&;
123 
125  auto operator=( VariableSet&& other ) noexcept -> VariableSet&;
126 
128  void clear();
129 
134  void mergeKeepVariables( const VariableSet& from );
135 
140  void mergeReplaceVariables( const VariableSet& from );
141 
143  size_t size() const;
144 
147  auto getStoredTypes() const -> const std::vector<std::type_index>& { return m_storedType; }
148 
150  // ------------------------------------------------------------------------------------------
151  // Per variable operations
152  // ------------------------------------------------------------------------------------------
159  template <typename T>
160  auto insertVariable( const std::string& name, const T& value )
161  -> std::pair<VariableHandle<T>, bool>;
162 
167  template <typename T>
168  auto getVariable( const std::string& name ) const -> T&;
169 
175  template <typename T>
176  auto getVariableHandle( const std::string& name ) const -> VariableHandle<T>;
177 
182  template <typename H>
183  bool isHandleValid( const H& handle ) const;
184 
188  template <typename T>
189  auto insertOrAssignVariable( const std::string& name, const T& value )
190  -> std::pair<VariableHandle<T>, bool>;
191 
196  template <typename T>
197  bool deleteVariable( const std::string& name );
198 
206  template <typename H>
207  bool deleteVariable( H& handle );
208 
212  template <typename T>
213  auto existsVariable( const std::string& name ) const -> Utils::optional<VariableHandle<T>>;
214 
216 
217  // ------------------------------------------------------------------------------------------
218  // Per type access
219  // ------------------------------------------------------------------------------------------
227  template <typename T>
228  auto existsVariableType() const -> Utils::optional<VariableContainer<T>*>;
229 
235  template <typename T>
236  bool deleteAllVariables();
237 
243  template <typename T>
244  auto getAllVariables() const -> VariableContainer<T>&;
245 
252  template <typename H>
253  auto getAllVariablesFromHandle( const H& handle )
254  -> VariableContainer<VariableTypeFromHandle<H>>&;
255 
259  template <typename T>
260  size_t numberOf() const;
262 
265 
270  template <typename... TYPES>
271  struct StaticVisitor {
272  using types = Utils::TypeList<TYPES...>;
273  };
274 
280  {
281  public:
282  virtual ~DynamicVisitorBase() = default;
283 
290  virtual void operator()( std::any&& in, std::any&& userParam ) const = 0;
291 
295  [[nodiscard]] virtual bool accept( const std::type_index& id ) const = 0;
296  };
297 
307  class RA_CORE_API DynamicVisitor : public DynamicVisitorBase
308  {
309  public:
311  ~DynamicVisitor() override = default;
312 
319  void operator()( std::any&& in, std::any&& userParam ) const override;
320 
324  [[nodiscard]] bool accept( const std::type_index& id ) const override;
325 
333  template <typename T, typename F>
334  bool addOperator( F&& f );
335 
339  template <typename T>
340  bool hasOperator();
341 
348  template <typename T, typename F>
349  void addOrReplaceOperator( F&& f );
350 
355  template <typename T>
356  bool removeOperator();
357 
358  private:
360  using CallbackFunction = std::function<void( std::any&, std::any&& )>;
361 
363  using OperatorsStorageType = std::unordered_map<std::type_index, CallbackFunction>;
364 
366  template <typename T, typename F, bool WithUserParam>
367  struct MakeVisitOperatorHelper {
368  auto makeOperator( F& f ) -> OperatorsStorageType::value_type;
369  };
370 
373  template <typename T, typename F>
374  auto makeVisitorOperator( F& f ) -> OperatorsStorageType::value_type;
375 
377  OperatorsStorageType m_visitorOperator;
378  };
379 
390  template <typename F>
391  void visit( F&& visitor ) const;
392 
394  template <typename F, typename T>
395  void visit( F&& visitor, T& userParams ) const;
396 
398  template <typename F, typename T>
399  void visit( F&& visitor, T&& userParams ) const;
400 
401  private:
425  template <typename P = bool>
426  void visitDynamic( DynamicVisitorBase& visitor, P&& params = P {} ) const;
427 
445  template <typename F>
446  void visitStatic( F&& visitor ) const;
447 
449  template <typename F, typename T>
450  void visitStatic( F&& visitor, T& userParams ) const;
451 
453  template <typename F, typename T>
454  void visitStatic( F&& visitor, T&& userParams ) const;
455 
459  template <typename T>
460  static auto getVariableVisitTypeIndex() -> std::type_index;
461 
467  template <typename T>
468  auto addVariableType() -> Utils::optional<VariableContainer<T>*>;
469 
473  template <typename F, typename T>
474  using VisitFunction =
475  decltype( std::declval<F>().operator()( std::declval<const std::string&>(),
476  std::declval<T&>() ) );
477 
479  template <typename F, typename T, typename U>
480  using VisitFunctionWithUserParam =
481  decltype( std::declval<F>().operator()( std::declval<const std::string&>(),
482  std::declval<T&>(),
483  std::declval<U&&>() ) );
484 
486  template <typename F, typename T>
487  static constexpr bool has_visit_callable_v =
488  Ra::Core::Utils::is_detected<VisitFunction, F, T>::value;
489 
491  template <typename F, typename T, typename U>
492  static constexpr bool has_visit_callable_with_user_param_v =
493  Ra::Core::Utils::is_detected<VisitFunctionWithUserParam, F, T, U>::value;
494 
496  template <typename F, template <typename...> typename TYPESLIST, typename... TYPES>
497  void visitImpl( F&& visitor, TYPESLIST<TYPES...> ) const;
498 
499  template <typename F, typename T>
500  void visitImplHelper( F& visitor ) const;
501 
503  template <typename F, typename U, template <typename...> typename TYPESLIST, typename... TYPES>
504  void visitImplUserParam( F&& visitor, U&& userParam, TYPESLIST<TYPES...> ) const;
505 
506  template <typename F, typename U, typename T>
507  void visitImplHelperUserParam( F& visitor, U&& userParams ) const;
508 
510 
514 
516  class VariableSetFunctions
517  {
518  public:
519  using ClearFunctionType = std::function<void( VariableSet& )>;
520  using MergeFunctionType = std::function<void( const VariableSet&, VariableSet& )>;
521  using SizeFunctionType = std::function<size_t( const VariableSet& )>;
522  // Should be these simplified ????
523  using VisitFunctorType =
524  std::function<std::pair<bool, std::function<void( DynamicVisitorBase&, std::any&& )>>(
525  const VariableSet&,
526  const DynamicVisitorBase& )>;
527 
528  VariableSetFunctions( const VariableSetFunctions& ) = delete;
529  void operator=( const VariableSetFunctions& ) = delete;
530 
531  protected:
532  VariableSetFunctions() = default;
533  ~VariableSetFunctions() = default;
534 
535  public:
536  // static variable ref singleton implementation.
537  static auto getInstance() -> VariableSetFunctions*;
538 
539  std::vector<MergeFunctionType> m_mergeKeepFunctions;
540  std::vector<MergeFunctionType> m_mergeReplaceFunctions;
541  std::vector<SizeFunctionType> m_sizeFunctions;
542  std::vector<VisitFunctorType> m_visitFunctions;
543  std::vector<std::type_index> m_storedType;
544  };
545 
546  VariableSetFunctions* m_vtable;
547 
549 
552  // Storage of the variable in a type-erased associative container
553  mutable std::unordered_map<std::type_index, std::any> m_variables;
554  std::unordered_map<std::type_index, size_t> m_typeIndexToVtableIndex;
556  std::vector<std::type_index> m_storedType;
557 
561  template <typename T>
562  auto createVariableStorage() -> VariableContainer<T>*;
563 
566  template <typename T>
567  auto getVariableStorage() const -> VariableContainer<T>&;
568 
571  template <typename T>
572  void removeVariableStorage();
573 
575 };
576 
577 // ------------------------------------------------------------------------------------------
578 // Storage management
579 // ------------------------------------------------------------------------------------------
580 
581 template <typename T>
582 auto VariableSet::createVariableStorage() -> VariableContainer<T>* {
583  m_variables[std::type_index { typeid( T ) }].emplace<VariableContainer<T>>();
584  return std::any_cast<VariableContainer<T>>( &( m_variables[std::type_index { typeid( T ) }] ) );
585 }
586 
587 template <typename T>
588 auto VariableSet::getVariableStorage() const -> VariableContainer<T>& {
589  return std::any_cast<VariableContainer<T>&>( m_variables[std::type_index { typeid( T ) }] );
590 }
591 
592 template <typename T>
593 void VariableSet::removeVariableStorage() {
594  auto type = std::type_index { typeid( T ) };
595  m_variables.erase( type );
596  m_typeIndexToVtableIndex.erase( type );
597 
598  auto newEnd = std::remove( m_storedType.begin(), m_storedType.end(), type );
599  m_storedType.erase( newEnd, m_storedType.end() );
600 }
601 
602 // ------------------------------------------------------------------------------------------
603 // Templated methods definition
604 // ------------------------------------------------------------------------------------------
605 template <typename T>
606 auto VariableSet::insertVariable( const std::string& name, const T& value )
607  -> std::pair<VariableHandle<T>, bool> {
608  auto typeAccess = existsVariableType<T>();
609  // If it is the first parameter of the given type, first register the type
610  if ( !typeAccess ) { typeAccess = addVariableType<T>(); }
611  // insert the parameter.
612  return ( *typeAccess )->insert( { name, value } );
613 }
614 
615 template <typename T>
616 auto VariableSet::getVariable( const std::string& name ) const -> T& {
617  assert( existsVariable<T>( name ) );
618  return getVariableHandle<T>( name )->second;
619 }
620 
621 template <typename T>
622 auto VariableSet::getVariableHandle( const std::string& name ) const -> VariableHandle<T> {
623  assert( existsVariableType<T>() );
624  return getVariableStorage<T>().find( name );
625 }
626 
627 template <typename H>
628 bool VariableSet::isHandleValid( const H& handle ) const {
629  if ( !existsVariableType<VariableTypeFromHandle<H>>() ) { return false; }
630  return handle != getVariableStorage<VariableTypeFromHandle<H>>().end();
631 }
632 
633 template <typename T>
634 auto VariableSet::insertOrAssignVariable( const std::string& name, const T& value )
635  -> std::pair<VariableHandle<T>, bool> {
636  auto typeAccess = existsVariableType<T>();
637  // If it is the first parameter of the given type, first register the type
638  if ( !typeAccess ) { typeAccess = addVariableType<T>(); }
639  // insert the parameter.
640  return ( *typeAccess )->insert_or_assign( name, value );
641 }
642 
643 template <typename T>
644 bool VariableSet::deleteVariable( const std::string& name ) {
645  if ( auto typeAccess = existsVariableType<T>(); typeAccess ) {
646  auto removed = ( *typeAccess )->erase( name );
647  // remove the type related function when the container has no more data of this type
648  if ( numberOf<T>() == 0 ) { deleteAllVariables<T>(); }
649  return removed > 0;
650  }
651  return false;
652 }
653 
654 template <typename H>
655 bool VariableSet::deleteVariable( H& handle ) {
656  assert( isHandleValid( handle ) );
657  auto varname = handle->first;
658  handle = getVariableStorage<VariableTypeFromHandle<H>>().end();
659  return deleteVariable<VariableTypeFromHandle<H>>( varname );
660 }
661 
662 template <typename T>
663 auto VariableSet::existsVariable( const std::string& name ) const
664  -> Utils::optional<VariableHandle<T>> {
665  if ( auto typeAccess = existsVariableType<T>(); typeAccess ) {
666  auto itr = ( *typeAccess )->find( name );
667  if ( itr != ( *typeAccess )->cend() ) { return itr; }
668  }
669  return {};
670 }
671 
672 template <typename T>
673 auto VariableSet::getVariableVisitTypeIndex() -> std::type_index {
674  static std::type_index idT(
675  typeid( std::reference_wrapper<typename VariableSet::VariableContainer<T>::value_type> ) );
676  return idT;
677 }
678 
679 template <typename T>
680 auto VariableSet::addVariableType() -> Utils::optional<VariableContainer<T>*> {
681  auto storage = createVariableStorage<T>();
682 
683  auto tidx = std::type_index( typeid( T ) );
684  auto it = std::find( m_vtable->m_storedType.begin(), m_vtable->m_storedType.end(), tidx );
685 
686  // remember the stored type and its rank for the instance
687  m_typeIndexToVtableIndex[tidx] = it - m_vtable->m_storedType.begin();
688  m_storedType.push_back( tidx );
689 
690  // If the type is not already there, add type operations and identifier in the global vtable
691  if ( it == m_vtable->m_storedType.end() ) {
692  // remember the stored type in the global vtable
693  m_vtable->m_storedType.emplace_back( tidx );
694  // used to merge (keep) the stored data from container "from" to container "to"
695  m_vtable->m_mergeKeepFunctions.emplace_back(
696  []( const VariableSet& from, VariableSet& to ) {
697  auto toStorageAccess = to.existsVariableType<T>();
698  if ( !toStorageAccess ) { toStorageAccess = to.addVariableType<T>(); }
699  auto& toStorage = *( toStorageAccess.value() );
700  auto& fromStorage = from.getVariableStorage<T>();
701  for ( const auto& t : fromStorage ) {
702  toStorage.insert( t );
703  }
704  } );
705  // used to merge (replace) the stored data from container "from" to container "to"
706  m_vtable->m_mergeReplaceFunctions.emplace_back(
707  []( const VariableSet& from, VariableSet& to ) {
708  auto toStorageAccess = to.existsVariableType<T>();
709  if ( !toStorageAccess ) { toStorageAccess = to.addVariableType<T>(); }
710  auto& toStorage = *( toStorageAccess.value() );
711  auto& fromStorage = from.getVariableStorage<T>();
712  for ( const auto& t : fromStorage ) {
713  toStorage.insert_or_assign( t.first, t.second );
714  }
715  } );
716  // use to compute gauge on the stored data
717  m_vtable->m_sizeFunctions.emplace_back(
718  []( const VariableSet& c ) { return c.getVariableStorage<T>().size(); } );
719  // used to visit the variableSet with a dynamic visitor
720  m_vtable->m_visitFunctions.emplace_back(
721  []( const VariableSet& c, const DynamicVisitorBase& v )
722  -> std::pair<bool, std::function<void( DynamicVisitorBase&, std::any && )>> {
723  auto id = getVariableVisitTypeIndex<T>();
724  if ( v.accept( id ) ) {
725  auto& storage = c.getVariableStorage<T>();
726  auto coll = std::ref( storage );
727  return { true, [coll]( DynamicVisitorBase& visitor, std::any&& userParam ) {
728  for ( auto&& t : coll.get() ) {
729  visitor( { std::ref( t ) },
730  std::forward<std::any>( userParam ) );
731  }
732  } };
733  }
734  else { return { false, nullptr }; }
735  } );
736  }
737  return storage;
738 }
739 
740 template <typename T>
741 auto VariableSet::existsVariableType() const -> Utils::optional<VariableContainer<T>*> {
742  auto iter = m_variables.find( std::type_index { typeid( T ) } );
743  if ( iter == m_variables.cend() ) { return {}; }
744  else { return std::any_cast<VariableSet::VariableContainer<T>>( &( iter->second ) ); }
745 }
746 
747 template <typename T>
749  if ( existsVariableType<T>() ) {
750  removeVariableStorage<T>();
751  return true;
752  }
753  return false;
754 }
755 
756 template <typename T>
758  // just assert on the existence of the type to prevent undefined behavior when dereferencing
759  // the optional
760  assert( existsVariableType<T>() );
761  // trows std::bad_any_cast if type does not exist
762  return getVariableStorage<T>();
763 }
764 
765 template <typename H>
768  assert( existsVariableType<VariableTypeFromHandle<H>>() );
769  return getVariableStorage<VariableTypeFromHandle<H>>();
770 }
771 
772 template <typename T>
773 size_t VariableSet::numberOf() const {
774  if ( auto variables = existsVariableType<T>(); variables ) { return ( *variables )->size(); }
775  return 0;
776 }
777 
778 template <typename P>
779 void VariableSet::visitDynamic( DynamicVisitorBase& visitor, P&& params ) const {
780  for ( const auto& [type, index] : m_typeIndexToVtableIndex ) {
781  auto [accepted, loop] = m_vtable->m_visitFunctions[index]( *this, visitor );
782  if ( accepted ) { loop( visitor, std::forward<P>( params ) ); }
783  }
784 }
785 
786 template <typename F>
787 void VariableSet::visitStatic( F&& visitor ) const {
788  visitImpl( visitor, typename std::decay_t<F>::types {} );
789 }
790 
791 template <typename F, template <typename...> typename TYPESLIST, typename... TYPES>
792 void VariableSet::visitImpl( F&& visitor, TYPESLIST<TYPES...> ) const {
793  ( ..., visitImplHelper<std::decay_t<F>, TYPES>( visitor ) );
794 }
795 
796 template <typename F, typename T>
797 void VariableSet::visitImplHelper( F& visitor ) const {
798  static_assert( has_visit_callable_v<F, T>,
799  "Static visitors must provide a function with profile "
800  "void( const std::string& name, [const ]T[&] value) for each "
801  "declared visitable type T" );
802  if ( auto variables = existsVariableType<T>(); variables ) {
803  for ( auto& element : *( variables.value() ) ) {
804  visitor( element.first, element.second );
805  }
806  }
807 }
808 
809 template <typename F, typename U>
810 void VariableSet::visitStatic( F&& visitor, U& userParams ) const {
811  visitImplUserParam(
812  visitor, std::forward<U>( userParams ), typename std::decay_t<F>::types {} );
813 }
814 
815 template <typename F, typename U>
816 void VariableSet::visitStatic( F&& visitor, U&& userParams ) const {
817  visitImplUserParam(
818  visitor, std::forward<U>( userParams ), typename std::decay_t<F>::types {} );
819 }
820 
821 template <typename F, typename U, template <typename...> typename TYPESLIST, typename... TYPES>
822 void VariableSet::visitImplUserParam( F&& visitor, U&& userParam, TYPESLIST<TYPES...> ) const {
823  ( ...,
824  visitImplHelperUserParam<std::decay_t<F>, U, TYPES>( visitor,
825  std::forward<U>( userParam ) ) );
826 }
827 
828 template <typename F, typename U, typename T>
829 void VariableSet::visitImplHelperUserParam( F& visitor, U&& userParams ) const {
830  static_assert( has_visit_callable_with_user_param_v<F, T, U>,
831  "Static visitors must provide a function with profile "
832  "void( const std::string& name, [const ]T[&] value, [const] U&&) for each "
833  "declared visitable type T" );
834  if ( auto variables = existsVariableType<T>(); variables ) {
835  for ( auto& element : *( variables.value() ) ) {
836  visitor( element.first, element.second, std::forward<U>( userParams ) );
837  }
838  }
839 }
840 
841 template <typename T, typename F>
843  auto [it, inserted] = m_visitorOperator.insert( makeVisitorOperator<T, F>( f ) );
844  return inserted;
845 }
846 
847 template <typename T>
849  return m_visitorOperator.find( getVariableVisitTypeIndex<T>() ) != m_visitorOperator.end();
850 }
851 
852 template <typename T, typename F>
854  auto op = makeVisitorOperator<T, F>( f );
855  m_visitorOperator.insert_or_assign( op.first, op.second );
856 }
857 
858 template <typename T>
860  assert( hasOperator<T>() );
861  auto res = m_visitorOperator.erase( getVariableVisitTypeIndex<T>() ) > 0;
862  return res;
863 }
864 
865 template <typename T, typename F>
866 struct VariableSet::DynamicVisitor::MakeVisitOperatorHelper<T, F, true> {
867  inline auto makeOperator( F& f ) -> OperatorsStorageType::value_type {
868  return { getVariableVisitTypeIndex<T>(), [&f]( std::any& a, std::any&& userParam ) {
869  auto rp = std::any_cast<std::reference_wrapper<VariableSet::Variable<T>>&>( a );
870  auto& p = rp.get();
871  f( p.first, p.second, std::forward<std::any>( userParam ) );
872  } };
873  }
874 };
875 
876 template <typename T, typename F>
877 struct VariableSet::DynamicVisitor::MakeVisitOperatorHelper<T, F, false> {
878  inline auto makeOperator( F& f ) -> OperatorsStorageType::value_type {
879  return { getVariableVisitTypeIndex<T>(), [&f]( std::any& a, std::any&& ) {
880  auto rp = std::any_cast<std::reference_wrapper<VariableSet::Variable<T>>&>( a );
881  auto& p = rp.get();
882  f( p.first, p.second );
883  } };
884  }
885 };
886 
887 template <class T, class F>
888 inline auto VariableSet::DynamicVisitor::makeVisitorOperator( F& f )
889  -> OperatorsStorageType::value_type {
890  auto opBuilder = MakeVisitOperatorHelper < T, F,
891  std::is_invocable<F, const std::string&, T, std::any&&>::value ||
892  std::is_invocable<F, const std::string&, T&, std::any&&>::value > {};
893  return opBuilder.makeOperator( f );
894 }
895 
896 template <typename F>
897 inline void VariableSet::visit( F&& visitor ) const {
898  if constexpr ( std::is_base_of<DynamicVisitorBase, std::decay_t<F>>::value ) {
899  visitDynamic( visitor );
900  }
901  else { visitStatic( visitor ); }
902 }
903 
904 template <typename F, typename T>
905 inline void VariableSet::visit( F&& visitor, T& userParams ) const {
906  if constexpr ( std::is_base_of<DynamicVisitorBase, std::decay_t<F>>::value ) {
907  visitDynamic( visitor, std::forward<T&>( userParams ) );
908  }
909  else { visitStatic( visitor, std::forward<T&>( userParams ) ); }
910 }
911 
912 template <typename F, typename T>
913 inline void VariableSet::visit( F&& visitor, T&& userParams ) const {
914  if constexpr ( std::is_base_of<DynamicVisitorBase, std::decay_t<F>>::value ) {
915  visitDynamic( visitor, std::forward<T&&>( userParams ) );
916  }
917  else { visitStatic( visitor, std::forward<T&&>( userParams ) ); }
918 }
919 
920 } // namespace Core
921 } // namespace Ra
Base class for dynamically configurable visitors Users can implement this interface to build custom v...
virtual bool accept(const std::type_index &id) const =0
Acceptance function for the visitor.
virtual void operator()(std::any &&in, std::any &&userParam) const =0
Execute a visiting operator on accepted types.
Base class for visitors with configurable per-type callbacks. Visiting will be prepared at running ti...
bool removeOperator()
Remove a visiting operator.
~DynamicVisitor() override=default
allows the class to be derived
bool hasOperator()
Test the existence of an operator associated with a type.
void addOrReplaceOperator(F &&f)
Add or replace a visiting operator.
bool addOperator(F &&f)
Add a visiting operator.
Heterogeneous container storing "Variables", that maps a name (std::string) to a value (of any type T...
Definition: VariableSet.hpp:72
auto getStoredTypes() const -> const std::vector< std::type_index > &
Gets the stored data type.
auto getVariable(const std::string &name) const -> T &
get the value of the given variable
typename VariableContainer< T >::iterator VariableHandle
Handle of a variable A handle on a variable with type T is an iterator into the BaseContainer....
Definition: VariableSet.hpp:92
auto insertOrAssignVariable(const std::string &name, const T &value) -> std::pair< VariableHandle< T >, bool >
reset (or set if the variable does not exist yet) the value of the variable.
bool isHandleValid(const H &handle) const
Test the validity of a handle.
auto getVariableHandle(const std::string &name) const -> VariableHandle< T >
get the handle on the variable with the given name
bool deleteAllVariables()
Removes all variables of the given type.
auto existsVariable(const std::string &name) const -> Utils::optional< VariableHandle< T >>
test the existence of the given variable
bool deleteVariable(const std::string &name)
Remove a variable, i.e. a name->value association.
typename Variable< T >::second_type VariableType
Type of the variable value.
Definition: VariableSet.hpp:84
auto getAllVariables() const -> VariableContainer< T > &
Get the whole container for variables of a given type.
std::map< std::string, T > VariableContainer
Container type for the mapping name->value of variables with type T.
Definition: VariableSet.hpp:76
VariableSet(const VariableSet &other) noexcept
A VariableSet is copyable.
typename VariableContainer< T >::value_type Variable
Variable type as stored in the VariableSet.
Definition: VariableSet.hpp:80
size_t numberOf() const
Get the number of variables of the given type.
VariableSet(VariableSet &&other) noexcept
A VariableSet is movable.
auto getAllVariablesFromHandle(const H &handle) -> VariableContainer< VariableTypeFromHandle< H >> &
Get the whole container for variables of the same type than the given handled variable.
auto existsVariableType() const -> Utils::optional< VariableContainer< T > * >
Test if the storage supports a given variable type.
auto insertVariable(const std::string &name, const T &value) -> std::pair< VariableHandle< T >, bool >
Add a variable, i.e. an association name->value, into the container.
void visit(F &&visitor) const
Visit the container using a user defined visitor.
typename std::iterator_traits< H >::value_type::second_type VariableTypeFromHandle
Type of the variable referenced by a VariableHandle.
Definition: VariableSet.hpp:98
Definition: Cage.cpp:3
Base class for visitors with static supported types. Visiting will be prepared at compile time by unf...