The Gaudi Framework  v37r0 (b608885e)
Property.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "COPYING". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #pragma once
12 
16 #include <Gaudi/PropertyFwd.h>
17 #include <GaudiKernel/TaggedBool.h>
18 #include <GaudiKernel/ToStream.h>
19 #include <string>
20 #include <utility>
21 
24 
25  // ==========================================================================
26  // The following code is going to be a bit unpleasant, but as far as its
27  // author can tell, it is as simple as the design constraints and C++'s
28  // implementation constraints will allow. If you disagree, please submit
29  // a patch which simplifies it. Here is the underlying design rationale:
30  //
31  // - For any given type T used in a Property, we want to have an
32  // associated StringConverter<T> struct which explains how to convert a
33  // value of that type into a string (toString) and parse that string
34  // back (fromString).
35  // - There is a default implementation, called DefaultStringConverter<T>,
36  // which is based on the overloadable parse() and toStream() global
37  // methods of Gaudi. Its exact behaviour varies depending on whether T
38  // is default-constructible or only copy-constructible, which requires a
39  // layer of SFINAE indirection.
40  // - Some people want to be able to specialize StringConverter as an
41  // alternative to defining parse/toStream overloads. This interferes
42  // with the SFINAE tricks used by DefaultStringConverter, so we cannot
43  // just call a DefaultStringConverter a StringConverter and must add one
44  // more layer to the StringConverter type hierarchy.
45 
46  // This class factors out commonalities between DefaultStringConverters
47  template <class TYPE>
49  public:
50  virtual ~DefaultStringConverterImpl() = default;
51  std::string toString( const TYPE& v ) {
53  return toString( v );
54  }
55 
56  // Implementation of fromString depends on whether TYPE is default-
57  // constructible (fastest, easiest) or only copy-constructible (still
58  // doable as long as the caller can provide a valid value of TYPE)
59  virtual TYPE fromString( const TYPE& ref_value, const std::string& s ) = 0;
60 
61  protected:
62  void fromStringImpl( TYPE& buffer, const std::string& s ) {
64  if ( !parse( buffer, InputData{ s } ).isSuccess() ) {
65  throw std::invalid_argument( "cannot parse '" + s + "' to " + System::typeinfoName( typeid( TYPE ) ) );
66  }
67  }
68  };
69 
70  // Specialization of toString for strings (identity function)
71  template <>
73  return v;
74  }
75 
76  // This class provides a default implementation of StringConverter based
77  // on the overloadable parse() and toStream() global Gaudi methods.
78  //
79  // It leverages the fact that TYPE is default-constructible if it can, and
80  // falls back fo a requirement of copy-constructibility if it must. So
81  // here is the "default" implementation for copy-constructible types...
82  //
83  template <typename TYPE, typename Enable = void>
85  TYPE fromString( const TYPE& ref_value, const std::string& s ) final override {
86  TYPE buffer = ref_value;
87  this->fromStringImpl( buffer, s );
88  return buffer;
89  }
90  };
91  // ...and here is the preferred impl for default-constructible types:
92  template <class TYPE>
93  struct DefaultStringConverter<TYPE, std::enable_if_t<std::is_default_constructible_v<TYPE>>>
95  TYPE fromString( const TYPE& /* ref_value */, const std::string& s ) final override {
96  TYPE buffer{};
97  this->fromStringImpl( buffer, s );
98  return buffer;
99  }
100  };
101 
102  // Specializable StringConverter struct with a default implementation
103  template <typename TYPE>
105 
106  struct NullVerifier {
107  template <class TYPE>
108  void operator()( const TYPE& ) const {}
109  };
110  template <class TYPE>
112  void operator()( const TYPE& value ) const {
114  // throw the exception if the limit is defined and value is outside
115  if ( ( m_hasLowerBound && ( value < m_lowerBound ) ) || ( m_hasUpperBound && ( m_upperBound < value ) ) )
116  throw std::out_of_range( "value " + toString( value ) + " outside range" );
117  }
118 
120  bool hasLower() const { return m_hasLowerBound; }
122  bool hasUpper() const { return m_hasUpperBound; }
124  const TYPE& lower() const { return m_lowerBound; }
126  const TYPE& upper() const { return m_upperBound; }
127 
129  void setLower( const TYPE& value ) {
130  m_hasLowerBound = true;
131  m_lowerBound = value;
132  }
134  void setUpper( const TYPE& value ) {
135  m_hasUpperBound = true;
136  m_upperBound = value;
137  }
139  void clearLower() {
140  m_hasLowerBound = false;
141  m_lowerBound = TYPE();
142  }
144  void clearUpper() {
145  m_hasUpperBound = false;
146  m_upperBound = TYPE();
147  }
148 
150  void setBounds( const TYPE& lower, const TYPE& upper ) {
151  setLower( lower );
152  setUpper( upper );
153  }
154 
156  void clearBounds() {
157  clearLower();
158  clearUpper();
159  }
160 
161  private:
163  bool m_hasLowerBound{ false };
164  bool m_hasUpperBound{ false };
165  TYPE m_lowerBound{};
166  TYPE m_upperBound{};
167  };
168 
170  struct SwapCall {
173  SwapCall( callback_t& input ) : orig( input ) { tmp.swap( orig ); }
174  ~SwapCall() { orig.swap( tmp ); }
175  void operator()( PropertyBase& p ) const { tmp( p ); }
176  };
177 
178  struct NoHandler {
179  void useReadHandler( const PropertyBase& ) const {}
181  throw std::logic_error( "setReadHandler not implemented for this class" );
182  }
183  std::function<void( PropertyBase& )> getReadHandler() const { return nullptr; }
184  void useUpdateHandler( const PropertyBase& ) const {}
186  throw std::logic_error( "setUpdateHandler not implemented for this class" );
187  }
188  std::function<void( PropertyBase& )> getUpdateHandler() const { return nullptr; }
189  };
192  void useReadHandler( const PropertyBase& p ) const {
193  if ( m_readCallBack ) { SwapCall{ m_readCallBack }( const_cast<PropertyBase&>( p ) ); }
194  }
197  };
201  if ( m_updateCallBack ) {
202  try {
203  SwapCall{ m_updateCallBack }( p );
204  } catch ( const std::exception& x ) {
205  throw std::invalid_argument( "failure in update handler of '" + p.name() + "': " + x.what() );
206  }
207  }
208  }
211  };
219  };
220 
224 } // namespace Gaudi::Details::Property
Gaudi::Details::Property::NoHandler
Definition: Property.h:178
Gaudi::Details::PropertyBase
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: PropertyBase.h:35
Gaudi::Details::Property::NoHandler::getReadHandler
std::function< void(PropertyBase &)> getReadHandler() const
Definition: Property.h:183
Gaudi::Details::PropertyBase::name
const std::string name() const
property name
Definition: PropertyBase.h:39
Gaudi::Details::Property::BoundedVerifier::setBounds
void setBounds(const TYPE &lower, const TYPE &upper)
Set both bounds (lower and upper) at the same time.
Definition: Property.h:150
std::string
STL class.
std::exception
STL class.
Gaudi::Details::Property::DefaultStringConverter< TYPE, std::enable_if_t< std::is_default_constructible_v< TYPE > > >::fromString
TYPE fromString(const TYPE &, const std::string &s) final override
Definition: Property.h:95
std::move
T move(T... args)
Gaudi::Details::Property::BoundedVerifier::setUpper
void setUpper(const TYPE &value)
Set upper bound value.
Definition: Property.h:134
Gaudi::Details::Property::UpdateHandler::m_updateCallBack
std::function< void(PropertyBase &)> m_updateCallBack
Definition: Property.h:199
Gaudi::Details::Property::DefaultStringConverterImpl::~DefaultStringConverterImpl
virtual ~DefaultStringConverterImpl()=default
Gaudi::Details::Property::BoundedVerifier::clearBounds
void clearBounds()
Clear both bounds (lower and upper) at the same time.
Definition: Property.h:156
Gaudi::Details::Property::NoHandler::setUpdateHandler
void setUpdateHandler(std::function< void(PropertyBase &)>)
Definition: Property.h:185
gaudirun.s
string s
Definition: gaudirun.py:348
PropertyBase.h
Gaudi::Details::Property::BoundedVerifier::clearLower
void clearLower()
Clear lower bound value.
Definition: Property.h:139
Gaudi::Details::Property::BoundedVerifier::upper
const TYPE & upper() const
Return the upper bound value.
Definition: Property.h:126
Gaudi::Details::Property::DefaultStringConverterImpl::fromStringImpl
void fromStringImpl(TYPE &buffer, const std::string &s)
Definition: Property.h:62
std::function< void(PropertyBase &)>
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:313
Gaudi::Details::Property::ReadHandler::getReadHandler
std::function< void(PropertyBase &)> getReadHandler() const
Definition: Property.h:196
Gaudi::Details::Property::BoundedVerifier
Definition: Property.h:111
Gaudi::Details::Property::SwapCall
helper to disable a while triggering it, to avoid infinite recursion
Definition: Property.h:170
Gaudi::Details::Property::SwapCall::SwapCall
SwapCall(callback_t &input)
Definition: Property.h:173
ToStream.h
Gaudi::Details::Property::ReadHandler::setReadHandler
void setReadHandler(std::function< void(PropertyBase &)> fun)
Definition: Property.h:195
Gaudi::Details::Property::ReadHandler::useReadHandler
void useReadHandler(const PropertyBase &p) const
Definition: Property.h:192
Gaudi::Details::Property::SwapCall::~SwapCall
~SwapCall()
Definition: Property.h:174
Gaudi::Details::Property::ParsingErrorPolicy
ParsingErrorPolicy
Definition: Property.h:221
Gaudi::Parsers::InputData
Helper class to enable ADL for parsers.
Definition: InputData.h:18
Gaudi::Details::Property::BoundedVerifier::m_lowerBound
TYPE m_lowerBound
Definition: Property.h:165
Gaudi::Details::Property::NullVerifier::operator()
void operator()(const TYPE &) const
Definition: Property.h:108
Gaudi::Details::Property::BoundedVerifier::m_hasUpperBound
bool m_hasUpperBound
Definition: Property.h:164
Gaudi::tagged_bool_ns::tagged_bool
Definition: TaggedBool.h:16
TaggedBool.h
Gaudi::Details::Property::NoHandler::useUpdateHandler
void useUpdateHandler(const PropertyBase &) const
Definition: Property.h:184
Gaudi::Details::Property::BoundedVerifier::lower
const TYPE & lower() const
Return the lower bound value.
Definition: Property.h:124
Gaudi::Details::Property::BoundedVerifier::m_hasLowerBound
bool m_hasLowerBound
Data members.
Definition: Property.h:163
Gaudi::Details::Property::DefaultStringConverter::fromString
TYPE fromString(const TYPE &ref_value, const std::string &s) final override
Definition: Property.h:85
PropertyFwd.h
Gaudi::Details::Property::StringConverter
Definition: Property.h:104
Gaudi::Details::Property::ParsingErrorPolicy::Warning
@ Warning
Gaudi::Details::Property::DefaultStringConverter
Definition: Property.h:84
Gaudi::Details::Property::ParsingErrorPolicy::Abort
@ Abort
Gaudi::Details::Property::ReadUpdateHandler
Definition: Property.h:212
std::logic_error
STL class.
std::invalid_argument
STL class.
Gaudi::Details::Property::UpdateHandler::useUpdateHandler
void useUpdateHandler(PropertyBase &p)
Definition: Property.h:200
Gaudi::Details::Property::parsingErrorPolicy
ParsingErrorPolicy parsingErrorPolicy()
Definition: Property.cpp:522
Gaudi::Details::Property::BoundedVerifier::hasLower
bool hasLower() const
Return if it has a lower bound.
Definition: Property.h:120
Gaudi::Details::Property::setParsingErrorPolicy
ParsingErrorPolicy setParsingErrorPolicy(ParsingErrorPolicy p)
Definition: Property.cpp:523
std::function::swap
T swap(T... args)
Gaudi::Details::Property::UpdateHandler::getUpdateHandler
std::function< void(PropertyBase &)> getUpdateHandler() const
Definition: Property.h:210
Gaudi::Utils::toString
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:353
Gaudi::Details::Property::BoundedVerifier::setLower
void setLower(const TYPE &value)
Set lower bound value.
Definition: Property.h:129
Gaudi::Details::Property::DefaultStringConverterImpl::fromString
virtual TYPE fromString(const TYPE &ref_value, const std::string &s)=0
Gaudi::Details::Property::BoundedVerifier::m_upperBound
TYPE m_upperBound
Definition: Property.h:166
CommonParsers.h
Gaudi::Details::Property::UpdateHandler::setUpdateHandler
void setUpdateHandler(std::function< void(PropertyBase &)> fun)
Definition: Property.h:209
Gaudi::Details::Property::SwapCall::tmp
callback_t tmp
Definition: Property.h:172
std
STL namespace.
Gaudi::Details::Property::BoundedVerifier::clearUpper
void clearUpper()
Clear upper bound value.
Definition: Property.h:144
parse
StatusCode parse(DataObjID &dest, const std::string &src)
Definition: DataObjID.cpp:57
Gaudi::Details::Property::SwapCall::orig
callback_t & orig
Definition: Property.h:172
Gaudi::Details::Property::BoundedVerifier::operator()
void operator()(const TYPE &value) const
Definition: Property.h:112
Gaudi::Details::Property::ReadHandler::m_readCallBack
std::function< void(PropertyBase &)> m_readCallBack
Definition: Property.h:191
Gaudi::Details::Property::NullVerifier
Definition: Property.h:106
Gaudi::Details::Property::BoundedVerifier::hasUpper
bool hasUpper() const
Return if it has a lower bound.
Definition: Property.h:122
Properties.v
v
Definition: Properties.py:123
std::out_of_range
STL class.
Gaudi::Details::Property::ParsingErrorPolicy::Ignore
@ Ignore
Gaudi::Details::Property::SwapCall::operator()
void operator()(PropertyBase &p) const
Definition: Property.h:175
Gaudi::Details::Property::NoHandler::useReadHandler
void useReadHandler(const PropertyBase &) const
Definition: Property.h:179
InputData.h
Gaudi::Details::Property::NoHandler::getUpdateHandler
std::function< void(PropertyBase &)> getUpdateHandler() const
Definition: Property.h:188
Gaudi::Details::Property::ParsingErrorPolicy::Exception
@ Exception
Gaudi::Details::Property::NoHandler::setReadHandler
void setReadHandler(std::function< void(PropertyBase &)>)
Definition: Property.h:180
Gaudi::Details::Property::DefaultStringConverterImpl::toString
std::string toString(const TYPE &v)
Definition: Property.h:51
Gaudi::Details::Property
Definition: Property.h:22
Gaudi::Details::Property::DefaultStringConverterImpl
Definition: Property.h:48
std::exception::what
T what(T... args)
Gaudi::Details::Property::ReadHandler
Definition: Property.h:190
Gaudi::Details::Property::UpdateHandler
Definition: Property.h:198