MarlinMT  0.1.0
Parameter.h
Go to the documentation of this file.
1 #ifndef MARLINMT_PARAMETER_h
2 #define MARLINMT_PARAMETER_h 1
3 
4 // -- std headers
5 #include <iostream>
6 #include <string>
7 #include <sstream>
8 #include <typeindex>
9 #include <memory>
10 #include <vector>
11 #include <set>
12 #include <any>
13 #include <functional>
14 
15 // -- marlinmt headers
16 #include <marlinmt/Utils.h>
17 #include <marlinmt/Validator.h>
18 
19 namespace marlinmt {
20 
21  class ConfigSection ;
22 
27  enum class EParameterType {
28  eSimple,
29  eVector
30  };
31 
32  //--------------------------------------------------------------------------
33  //--------------------------------------------------------------------------
34 
39  class ParameterImpl {
40  public:
41  using ValidatorFunction = std::any ;
42 
43  public:
44  ParameterImpl() = delete ;
45  ~ParameterImpl() = default ;
46 
55  template <typename T>
56  inline ParameterImpl(
57  EParameterType paramType,
58  const std::string &na,
59  const std::string &desc,
60  std::shared_ptr<T> addr ) :
61  _type(paramType),
62  _name(na),
63  _description(desc),
64  _typeIndex(typeid(T)),
65  _value(addr),
66  _validator(createValidator<T>(nullptr)) {
67  construct<T>() ;
68  }
69 
79  template <typename T>
80  inline ParameterImpl(
81  EParameterType paramType,
82  const std::string &na,
83  const std::string &desc,
84  std::shared_ptr<T> addr,
85  T defVal ) :
86  _type(paramType),
87  _name(na),
88  _description(desc),
89  _typeIndex(typeid(T)),
90  _value(addr),
91  _defaultValue(std::make_shared<T>(std::move(defVal))),
92  _validator(createValidator<T>(nullptr)) {
93  construct<T>() ;
94  }
95 
99  EParameterType type() const ;
100 
104  const std::string& name() const ;
105 
109  const std::string& description() const ;
110 
114  bool isSet() const ;
115 
119  bool hasDefault() const ;
120 
124  std::string str() const ;
125 
129  std::string defaultStr() const ;
130 
134  void str( const std::string &value ) ;
135 
139  std::string typeStr() const ;
140 
144  const std::type_index &typeIndex() const ;
145 
149  template <typename T>
150  inline bool isType() const {
151  return ( std::type_index(typeid(T)) == _typeIndex ) ;
152  }
153 
157  template <typename T>
158  inline void checkType() const {
159  if( not isType<T>() ) {
160  MARLINMT_THROW( "checkType failure. Given: " + std::string(details::type_info<T>::type) + ", stored: " + typeStr() ) ;
161  }
162  }
163 
169  template <typename T>
171  checkType<T>() ;
172  _validator = createValidator( validator ) ;
173  }
174 
181  template <typename T>
182  inline void set( const T &val ) {
183  checkType<T>() ;
184  if( _validator.has_value() ) {
185  auto validatorT = std::any_cast<ValidatorFunctionT<T>>( _validator ) ;
186  if (not validatorT( val ) ) {
187  MARLINMT_THROW( "Parameter '" + name() + "': invalid parameter value" ) ;
188  }
189  }
190  *std::static_pointer_cast<T>( _value ).get() = val ;
191  _isSet = true ;
192  }
193 
198  template <typename T>
199  inline T get() const {
200  checkType<T>() ;
201  if( not isSet() ) {
202  if( not hasDefault() ) {
203  MARLINMT_THROW( "Parameter '" + name() + "' not set" ) ;
204  }
205  return *std::static_pointer_cast<T>( _defaultValue ).get() ;
206  }
207  return *std::static_pointer_cast<T>( _value ).get() ;
208  }
209 
216  template <typename T>
217  inline T get( const T &fallback ) const {
218  try {
219  return get<T>() ;
220  }
221  catch( Exception & ) {
222  return fallback ;
223  }
224  }
225 
230  template <typename T>
231  inline T getDefault() const {
232  if( not hasDefault() ) {
233  MARLINMT_THROW( "Parameter '" + name() + "' has no default value" ) ;
234  }
235  return *std::static_pointer_cast<T>( _defaultValue ).get() ;
236  }
237 
241  void reset() ;
242 
243  private:
244  using ValueType = std::shared_ptr<void> ;
245  using TypeFunction = std::function<std::string()> ;
246  using StrFunction = std::function<std::string(ValueType)> ;
247  using FromStrFunction = std::function<void(ValueType, const std::string &)> ;
248  using ResetFunction = std::function<void()> ;
249 
251  template <typename T>
252  inline void construct() {
253  _typeFunction = [] { return details::type_info<T>::type ; };
254  _resetFunction = [this] { *std::static_pointer_cast<T>( _value ).get() = T() ; };
255  _strFunction = [this]( ValueType ptr ) { return details::convert<T>::to_string( *std::static_pointer_cast<T>( ptr ).get() ) ; };
256  _fromStrFunction = [this] ( ValueType ptr, const std::string &value ) {
257  T valueT = details::convert<T>::from_string( value ) ;
258  if( _validator.has_value() ) {
259  auto validatorT = std::any_cast<ValidatorFunctionT<T>>( _validator ) ;
260  if( not validatorT( valueT ) ) {
261  MARLINMT_THROW( "Parameter '" + name() + "': invalid parameter value" ) ;
262  }
263  }
264  *std::static_pointer_cast<T>( ptr ).get() = valueT ;
265  };
266  }
267 
269  template <typename T>
271  std::any validator {} ;
272  if( nullptr != validatorT ) {
273  validator = validatorT ;
274  }
275  return validator ;
276  }
277 
278  private:
282  std::string _name {} ;
284  std::string _description {} ;
286  TypeFunction _typeFunction {} ;
288  StrFunction _strFunction {} ;
290  FromStrFunction _fromStrFunction {} ;
292  ResetFunction _resetFunction {} ;
294  bool _isSet {false} ;
296  std::type_index _typeIndex ;
298  ValueType _value {nullptr} ;
300  ValueType _defaultValue {nullptr} ;
302  ValidatorFunction _validator {} ;
303  };
304 
305  //--------------------------------------------------------------------------
306  //--------------------------------------------------------------------------
307 
312  class Configurable {
313  public:
314  Configurable() = default ;
315  virtual ~Configurable() = default ;
316 
317  using ParameterMap = std::map<std::string, std::shared_ptr<ParameterImpl>> ;
318  using iterator = ParameterMap::iterator ;
319  using const_iterator = ParameterMap::const_iterator ;
320 
329  template <typename T>
330  inline std::shared_ptr<ParameterImpl> addParameter( EParameterType paramType, const std::string &name, const std::string &desc, std::shared_ptr<T> value ) {
331  checkParameter( name ) ;
332  auto param = std::make_shared<ParameterImpl>( paramType, name, desc, value ) ;
333  _parameters[ name ] = param ;
334  return param ;
335  }
336 
346  template <typename T>
347  inline std::shared_ptr<ParameterImpl> addParameter( EParameterType paramType, const std::string &name, const std::string &desc, std::shared_ptr<T> value, T defVal ) {
348  checkParameter( name ) ;
349  auto param = std::make_shared<ParameterImpl>( paramType, name, desc, value, std::move(defVal) ) ;
350  _parameters[ name ] = param ;
351  return param ;
352  }
353 
359  template <typename T>
360  inline T parameter( const std::string &name ) const {
361  checkParameter( name ) ;
362  return _parameters.find( name )->second->get<T>() ;
363  }
364 
372  template <typename T>
373  inline T parameter( const std::string &name, const T &fallback ) const {
374  checkParameter( name ) ;
375  return _parameters.find( name )->second->get<T>( fallback ) ;
376  }
377 
383  void checkParameter( const std::string &name ) const ;
384 
390  bool exists( const std::string &name ) const ;
391 
397  bool isSet( const std::string &name ) const ;
398 
402  void clear() ;
403 
407  void unset() ;
408 
409  iterator begin() ;
410  const_iterator begin() const ;
411  iterator end() ;
412  const_iterator end() const ;
413 
414  protected:
416  ParameterMap _parameters {} ;
417  };
418 
419  //--------------------------------------------------------------------------
420  //--------------------------------------------------------------------------
421 
426  template <typename T>
428  public:
429  using ValueType = T ;
430 
432  virtual ~ParameterBase() = default ;
433 
441  inline ParameterBase( EParameterType paramType, const std::string &na, const std::string &desc ) {
442  _impl = std::make_shared<ParameterImpl>( paramType, na, desc, _value ) ;
443  }
444 
453  inline ParameterBase( EParameterType paramType, const std::string &na, const std::string &desc, const T &defVal ) {
454  _impl = std::make_shared<ParameterImpl>( paramType, na, desc, _value, defVal ) ;
455  }
456 
465  inline ParameterBase( Configurable &conf, EParameterType paramType, const std::string &na, const std::string &desc ) {
466  _impl = conf.addParameter( paramType, na, desc, _value ) ;
467  }
468 
478  inline ParameterBase( Configurable &conf, EParameterType paramType, const std::string &na, const std::string &desc, const T &defVal ) {
479  _impl = conf.addParameter( paramType, na, desc, _value, defVal ) ;
480  }
481 
485  inline EParameterType type() const {
486  return _impl->type() ;
487  }
488 
492  inline const std::string& name() const {
493  return _impl->name() ;
494  }
495 
499  inline const std::string& description() const {
500  return _impl->description() ;
501  }
502 
506  inline bool isSet() const {
507  return _impl->isSet() ;
508  }
509 
513  inline bool hasDefault() const {
514  return _impl->hasDefault() ;
515  }
516 
520  inline std::string str() const {
521  return _impl->str() ;
522  }
523 
527  inline std::string defaultStr() const {
528  return _impl->defaultStr() ;
529  }
530 
534  inline std::string typeStr() const {
535  return _impl->typeStr() ;
536  }
537 
541  inline const std::type_index &typeIndex() const {
542  return _impl->typeIndex() ;
543  }
544 
548  inline operator T() const {
549  return get() ;
550  }
551 
556  inline T get() const {
557  return _impl->get<T>() ;
558  }
559 
564  inline T get( const T &fallback ) const {
565  return _impl->get<T>( fallback ) ;
566  }
567 
573  inline void set( const T &value ) {
574  _impl->set( value ) ;
575  }
576 
580  inline void reset() {
581  _impl->reset() ;
582  }
583 
589  inline void setValidator( ValidatorFunctionT<T> validator ) {
590  _impl->setValidator( validator ) ;
591  }
592 
593  protected:
595  std::shared_ptr<T> _value { std::make_shared<T>() } ;
597  std::shared_ptr<ParameterImpl> _impl {} ;
598  };
599 
600  //--------------------------------------------------------------------------
601  //--------------------------------------------------------------------------
602 
607  template <typename T>
608  class Parameter : public ParameterBase<T> {
609  public:
611  Parameter() = delete ;
613  Parameter( const Parameter<T> & ) = default ;
615  Parameter<T> &operator=( const Parameter<T> & ) = default ;
617  ~Parameter() = default ;
618 
625  inline Parameter( const std::string &na, const std::string &desc ) :
626  ParameterBase<T>( EParameterType::eSimple, na, desc ) {
627  /* nop */
628  }
629 
637  inline Parameter( const std::string &na, const std::string &desc, const T &defVal ) :
638  ParameterBase<T>( EParameterType::eSimple, na, desc, defVal ) {
639  /* nop */
640  }
641 
649  inline Parameter( Configurable &conf, const std::string &na, const std::string &desc ) :
650  ParameterBase<T>( conf, EParameterType::eSimple, na, desc ) {
651  /* nop */
652  }
653 
662  inline Parameter( Configurable &conf, const std::string &na, const std::string &desc, const T &defVal ) :
663  ParameterBase<T>( conf, EParameterType::eSimple, na, desc, defVal ) {
664  /* nop */
665  }
666  };
667 
668  //--------------------------------------------------------------------------
669  //--------------------------------------------------------------------------
670 
676  template <typename T>
677  class VectorParameter : public ParameterBase<std::vector<T>> {
678  public:
680 
682  VectorParameter() = delete ;
684  VectorParameter( const VectorParameter<T> & ) = default ;
686  VectorParameter<T> &operator=( const VectorParameter<T> & ) = default ;
688  ~VectorParameter() = default ;
689 
697  inline VectorParameter( const std::string &na, const std::string &desc ) :
698  Base( EParameterType::eVector, na, desc ) {
699  /* nop */
700  }
701 
710  inline VectorParameter( const std::string &na, const std::string &desc, const std::vector<T> &defVal ) :
711  Base( EParameterType::eVector, na, desc, defVal ) {
712  /* nop */
713  }
714 
722  inline VectorParameter( Configurable &conf, const std::string &na, const std::string &desc ) :
723  Base( conf, EParameterType::eVector, na, desc ) {
724  /* nop */
725  }
726 
735  inline VectorParameter( Configurable &conf, const std::string &na, const std::string &desc, const std::vector<T> &defVal ) :
736  Base( conf, EParameterType::eVector, na, desc, defVal ) {
737  /* nop */
738  }
739 
740  // vector const (only) interface aliases
741  auto at( typename std::vector<T>::size_type idx ) const { return Base::_value->at(idx) ; }
742  auto operator[]( typename std::vector<T>::size_type idx ) const { return *(Base::_value)[idx] ; }
743  auto front() const { return Base::_value->front() ; }
744  auto back() const { return Base::_value->back() ; }
745  auto data() const { return Base::_value->data() ; }
746  auto begin() const { return Base::_value->begin() ; }
747  auto end() const { return Base::_value->end() ; }
748  auto cbegin() const { return Base::_value->cbegin() ; }
749  auto cend() const { return Base::_value->cend() ; }
750  auto rbegin() const { return Base::_value->rbegin() ; }
751  auto rend() const { return Base::_value->rend() ; }
752  auto crbegin() const { return Base::_value->crbegin() ; }
753  auto crend() const { return Base::_value->crend() ; }
754  auto empty() const { return Base::_value->empty() ; }
755  auto size() const { return Base::_value->size() ; }
756  auto max_size() const { return Base::_value->max_size() ; }
757  };
758 
759  //--------------------------------------------------------------------------
760 
761  template <typename T>
762  inline std::ostream &operator <<( std::ostream &stream, const Parameter<T> &rhs ) {
763  stream << rhs.get() ;
764  return stream ;
765  }
766 
767  //--------------------------------------------------------------------------
768 
769  template <typename T, typename S>
770  inline bool operator ==( const Parameter<T> &lhs, const S &rhs ) {
771  return ( lhs.get() == rhs ) ;
772  }
773 
774  //--------------------------------------------------------------------------
775 
776  template <typename T, typename S>
777  inline bool operator !=( const Parameter<T> &lhs, const S &rhs ) {
778  return ( lhs.get() != rhs ) ;
779  }
780 
781  //--------------------------------------------------------------------------
782 
783  template <typename T, typename S>
784  inline bool operator <( const Parameter<T> &lhs, const S &rhs ) {
785  return ( lhs.get() < rhs ) ;
786  }
787 
788  //--------------------------------------------------------------------------
789 
790  template <typename T, typename S>
791  inline bool operator <=( const Parameter<T> &lhs, const S &rhs ) {
792  return ( lhs.get() <= rhs ) ;
793  }
794 
795  //--------------------------------------------------------------------------
796 
797  template <typename T, typename S>
798  inline bool operator >( const Parameter<T> &lhs, const S &rhs ) {
799  return ( lhs.get() > rhs ) ;
800  }
801 
802  //--------------------------------------------------------------------------
803 
804  template <typename T, typename S>
805  inline bool operator >=( const Parameter<T> &lhs, const S &rhs ) {
806  return ( lhs.get() >= rhs ) ;
807  }
808 
809  //--------------------------------------------------------------------------
810 
811  // helper types
824 
825 } // end namespace marlinmt
826 #endif
bool hasDefault() const
Whether the parameter has a default value.
Definition: Parameter.h:513
bool operator>(const Parameter< T > &lhs, const S &rhs)
Definition: Parameter.h:798
Configurable class Interface for configuring components in the framework.
Definition: Parameter.h:312
Parameter(Configurable &conf, const std::string &na, const std::string &desc, const T &defVal)
Constructor.
Definition: Parameter.h:662
ParameterBase(Configurable &conf, EParameterType paramType, const std::string &na, const std::string &desc, const T &defVal)
Constructor.
Definition: Parameter.h:478
T parameter(const std::string &name) const
Get a parameter value.
Definition: Parameter.h:360
VectorParameter(const std::string &na, const std::string &desc, const std::vector< T > &defVal)
Constructor.
Definition: Parameter.h:710
std::function< std::string()> TypeFunction
Definition: Parameter.h:245
T parameter(const std::string &name, const T &fallback) const
Get a parameter value.
Definition: Parameter.h:373
void construct()
Construct the parameter (called from ctor)
Definition: Parameter.h:252
ParameterMap::const_iterator const_iterator
Definition: Parameter.h:319
ParameterMap::iterator iterator
Definition: Parameter.h:318
EParameterType
EParameterType enumerator Enumerates parameter types supported by Marlin.
Definition: Parameter.h:27
ParameterImpl class Abstract internal implementation of a parameter.
Definition: Parameter.h:39
std::any ValidatorFunction
Definition: Parameter.h:41
std::map< std::string, std::shared_ptr< ParameterImpl > > ParameterMap
Definition: Parameter.h:317
Definition: EntryData.h:93
constexpr unsigned long long value(const Flag_t &flag)
Definition: Flags.h:106
std::function< void()> ResetFunction
Definition: Parameter.h:248
ParameterBase(EParameterType paramType, const std::string &na, const std::string &desc)
Constructor.
Definition: Parameter.h:441
Parameter<T> class High level interface to register simple parameter values (int, float...
Definition: Parameter.h:608
ParameterImpl(EParameterType paramType, const std::string &na, const std::string &desc, std::shared_ptr< T > addr)
Constructor.
Definition: Parameter.h:56
void setValidator(ValidatorFunctionT< T > validator)
Set the validator function.
Definition: Parameter.h:589
const std::string & description() const
Get the parameter description.
Definition: Parameter.h:499
bool operator!=(const Parameter< T > &lhs, const S &rhs)
Definition: Parameter.h:777
const std::type_index & typeIndex() const
Get a type index object of the underlying type.
Definition: Parameter.h:541
std::string str() const
Get the parameter value as string.
Definition: Parameter.h:520
ValidatorFunction createValidator(ValidatorFunctionT< T > validatorT) const
Construct the validator function.
Definition: Parameter.h:270
std::function< void(ValueType, const std::string &)> FromStrFunction
Definition: Parameter.h:247
std::function< bool(const T &)> ValidatorFunctionT
Definition: Validator.h:12
VectorParameter(Configurable &conf, const std::string &na, const std::string &desc)
Constructor.
Definition: Parameter.h:722
std::function< std::string(ValueType)> StrFunction
Definition: Parameter.h:246
std::shared_ptr< ParameterImpl > addParameter(EParameterType paramType, const std::string &name, const std::string &desc, std::shared_ptr< T > value, T defVal)
Add a parameter.
Definition: Parameter.h:347
void checkType() const
Throw an exception if the internal type doesn&#39;t match the template parameter type.
Definition: Parameter.h:158
#define MARLINMT_THROW(message)
Definition: Exceptions.h:8
std::type_index _typeIndex
The type index object of the underlying parameter type.
Definition: Parameter.h:296
Parameter(const std::string &na, const std::string &desc)
Constructor.
Definition: Parameter.h:625
VectorParameter(Configurable &conf, const std::string &na, const std::string &desc, const std::vector< T > &defVal)
Constructor.
Definition: Parameter.h:735
static T from_string(const std::string &str)
Definition: Utils.h:378
auto operator[](typename std::vector< T >::size_type idx) const
Definition: Parameter.h:742
std::shared_ptr< ParameterImpl > addParameter(EParameterType paramType, const std::string &name, const std::string &desc, std::shared_ptr< T > value)
Add a parameter.
Definition: Parameter.h:330
ParameterBase<T> class Base interface for user parameters.
Definition: Parameter.h:427
auto at(typename std::vector< T >::size_type idx) const
Definition: Parameter.h:741
bool isType() const
Check whether the template parameter matches the internal implementation type.
Definition: Parameter.h:150
bool operator==(const Parameter< T > &lhs, const S &rhs)
Definition: Parameter.h:770
T get() const
Get the parameter value.
Definition: Parameter.h:556
Simple (scalar) parameter.
static std::string to_string(const T &value)
Definition: Utils.h:370
EParameterType type() const
Get the parameter type.
Definition: Parameter.h:485
VectorParameter<T> class.
Definition: Parameter.h:677
T getDefault() const
Get the default parameter value if set.
Definition: Parameter.h:231
std::string defaultStr() const
Get the parameter default value as string.
Definition: Parameter.h:527
Parameter(const std::string &na, const std::string &desc, const T &defVal)
Constructor.
Definition: Parameter.h:637
ParameterImpl(EParameterType paramType, const std::string &na, const std::string &desc, std::shared_ptr< T > addr, T defVal)
Constructor.
Definition: Parameter.h:80
Parameter(Configurable &conf, const std::string &na, const std::string &desc)
Constructor.
Definition: Parameter.h:649
void setValidator(ValidatorFunctionT< T > validator)
Set the parameter validator function.
Definition: Parameter.h:170
std::string typeStr() const
Get the parameter type as string.
Definition: Parameter.h:534
bool operator>=(const Parameter< T > &lhs, const S &rhs)
Definition: Parameter.h:805
Exception class.
Definition: Exceptions.h:60
std::shared_ptr< void > ValueType
Definition: Parameter.h:244
ParameterBase(Configurable &conf, EParameterType paramType, const std::string &na, const std::string &desc)
Constructor.
Definition: Parameter.h:465
VectorParameter(const std::string &na, const std::string &desc)
Constructor.
Definition: Parameter.h:697
const std::string & name() const
Get the property name.
Definition: Parameter.h:492
void reset()
Reset the parameter value (only)
Definition: Parameter.h:580
ParameterBase(EParameterType paramType, const std::string &na, const std::string &desc, const T &defVal)
Constructor.
Definition: Parameter.h:453
bool isSet() const
Whether the parameter has been set.
Definition: Parameter.h:506