The Gaudi Framework  v30r3 (a5ef0a68)
PropertyHolder.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_PROPERTYHOLDER_H
2 #define GAUDIKERNEL_PROPERTYHOLDER_H
3 // ============================================================================
4 // Include files
5 // ============================================================================
6 // STD & STL
7 // ============================================================================
8 #include <algorithm>
9 #include <functional>
10 #include <iostream>
11 #include <stdexcept>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 // ============================================================================
16 // GaudiKernel
17 // ============================================================================
18 #include "GaudiKernel/Bootstrap.h"
21 #include "GaudiKernel/IProperty.h"
23 #include "GaudiKernel/MsgStream.h"
24 #include "GaudiKernel/Property.h"
25 #include "GaudiKernel/detected.h"
26 
27 // ============================================================================
28 namespace Gaudi
29 {
30  namespace Details
31  {
32 
33  template <typename T>
35  };
36 
37  template <typename TYPE, typename VERIFIER, typename HANDLERS>
38  struct is_gaudi_property<Gaudi::Property<TYPE, VERIFIER, HANDLERS>> : std::true_type {
39  };
40 
41  template <typename T>
43  template <typename T>
44  using PropertyType = Gaudi::cpp17::detected_or_t<Gaudi::Property<T>, PropertyType_t, T>;
45  }
46  namespace Utils
47  {
49  inline bool iequal( const std::string& v1, const std::string& v2 )
50  {
51  return v1.size() == v2.size() && std::equal( std::begin( v1 ), std::end( v1 ), std::begin( v2 ),
52  []( char c1, char c2 ) { return toupper( c1 ) == toupper( c2 ); } );
53  }
54  }
55 }
76 template <class BASE>
77 class GAUDI_API PropertyHolder : public BASE
78 {
80  "PropertyHolder template argument must inherit from IProperty and INamedInterface" );
81 
82 public:
90 
91  PropertyHolder() = default;
92 
95  PropertyHolder( const PropertyHolder& ) = delete;
96  PropertyHolder& operator=( const PropertyHolder& ) = delete;
98 
99 public:
103  {
104  assertUniqueName( prop.name() );
105  m_properties.push_back( &prop );
106  return prop;
107  }
108 
111  template <typename TYPE, typename = std::enable_if_t<!Gaudi::Details::is_gaudi_property<TYPE>::value>>
112  Gaudi::Details::PropertyBase* declareProperty( const std::string& name, TYPE& value, const std::string& doc = "none" )
113  {
114  m_todelete.push_back( std::make_unique<Gaudi::Details::PropertyType<TYPE&>>( name, value ) );
116 
117  p->setDocumentation( doc );
118  return &declareProperty( *p );
119  }
120 
123  template <class TYPE, class VERIFIER, class HANDLERS>
126  const std::string& doc = "none" )
127  {
128  Gaudi::Details::PropertyBase* p = &prop;
129  p->setName( name );
130 
131  p->setDocumentation( doc );
132  return &declareProperty( *p );
133  }
134 
138  const std::string& rname = "" )
139  {
140  if ( !rsvc ) return nullptr;
141  const std::string& nam = rname.empty() ? name : rname;
143  m_remoteProperties.emplace_back( name, std::make_pair( rsvc, nam ) );
144  return p;
145  }
146 
148 
149  // ==========================================================================
150  // IProperty implementation
151  // ==========================================================================
156  {
158  try {
159  if ( pp && pp->assign( p ) ) return StatusCode::SUCCESS;
160  } catch ( ... ) {
161  }
162  return StatusCode::FAILURE;
163  }
164  // ==========================================================================
168  StatusCode setProperty( const std::string& s ) override
169  {
171  std::string value;
172  StatusCode sc = Gaudi::Parsers::parse( name, value, s );
173  if ( sc.isFailure() ) return sc;
174  return setProperty( name, value );
175  }
176  // ==========================================================================
180  StatusCode setProperty( const std::string& n, const std::string& v ) override
181  {
183  return ( p && p->fromString( v ) ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
184  }
225  template <class TYPE>
226  StatusCode setProperty( const std::string& name, const TYPE& value )
227  {
228  return Gaudi::Utils::setProperty( this, name, value );
229  }
230  // ==========================================================================
235  {
236  try {
237  const Gaudi::Details::PropertyBase* pp = property( p->name() );
238  if ( pp && pp->load( *p ) ) return StatusCode::SUCCESS;
239  } catch ( ... ) {
240  }
241  return StatusCode::FAILURE;
242  }
243  // ==========================================================================
248  {
249  const Gaudi::Details::PropertyBase* p = property( name );
250  if ( !p ) throw std::out_of_range( "Property " + name + " not found." );
251  return *p;
252  }
253  // ==========================================================================
257  StatusCode getProperty( const std::string& n, std::string& v ) const override
258  {
259  // get the property
260  const Gaudi::Details::PropertyBase* p = property( n );
261  if ( !p ) return StatusCode::FAILURE;
262  // convert the value into the string
263  v = p->toString();
264  return StatusCode::SUCCESS;
265  }
266  // ==========================================================================
271  // ==========================================================================
275  bool hasProperty( const std::string& name ) const override
276  {
277  return any_of( begin( m_properties ), end( m_properties ), [&name]( const Gaudi::Details::PropertyBase* prop ) {
278  return Gaudi::Utils::iequal( prop->name(), name );
279  } );
280  }
281  // ==========================================================================
282 protected:
283  // get local or remote property by name
285  {
286  // local property ?
288  if ( lp ) return lp;
289  // look for remote property
290  for ( const auto& it : m_remoteProperties ) {
291  if ( !Gaudi::Utils::iequal( it.first, name ) ) continue;
292  const IProperty* p = it.second.first;
293  if ( !p ) continue;
294  return property( it.second.second, p->getProperties() );
295  }
296  return nullptr; // RETURN
297  }
298 
299 private:
302  const std::vector<Gaudi::Details::PropertyBase*>& props ) const
303  {
304  auto it = std::find_if( props.begin(), props.end(), [&name]( Gaudi::Details::PropertyBase* p ) {
305  return p && Gaudi::Utils::iequal( p->name(), name );
306  } );
307  return ( it != props.end() ) ? *it : nullptr; // RETURN
308  }
309 
312  void assertUniqueName( const std::string& name ) const
313  {
314  if ( UNLIKELY( hasProperty( name ) ) ) {
315  auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
316  if ( !msgSvc ) std::cerr << "error: cannot get MessageSvc!" << std::endl;
317  MsgStream log( msgSvc, this->name() );
318  log << MSG::WARNING << "duplicated property name '" << name << "', see https://its.cern.ch/jira/browse/GAUDI-1023"
319  << endmsg;
320  }
321  }
322 
326 
328  Properties m_properties;
330  RemoteProperties m_remoteProperties;
333 };
334 #endif
const Gaudi::Details::PropertyBase & getProperty(const std::string &name) const override
get the property by name
StatusCode setProperty(IProperty *component, const std::string &name, const TYPE &value, const std::string &doc)
simple function to set the property of the given object from the value
Definition: Property.h:1243
StatusCode getProperty(Gaudi::Details::PropertyBase *p) const override
get the property
#define UNLIKELY(x)
Definition: Kernel.h:122
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
T empty(T...args)
void setDocumentation(std::string value)
set the documentation string
Definition: Property.h:92
StatusCode setProperty(const std::string &name, const TYPE &value)
set the property form the value
Gaudi::Details::PropertyBase * property(const std::string &name) const
Implementation of property with value of concrete type.
Definition: Property.h:381
StatusCode setProperty(const Gaudi::Details::PropertyBase &p) override
set the property form another property
virtual bool load(PropertyBase &dest) const =0
export the property value to the destination
const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const override
get all properties
virtual bool assign(const PropertyBase &source)=0
import the property value form the source
const std::string name() const
property name
Definition: Property.h:40
Properties m_properties
Collection of all declared properties.
StatusCode getProperty(const std::string &n, std::string &v) const override
convert the property to the string
bool hasProperty(const std::string &name) const override
Return true if we have a property with the given name.
Gaudi::cpp17::detected_or_t< Gaudi::Property< T >, PropertyType_t, T > PropertyType
T endl(T...args)
Gaudi::Details::PropertyBase * property(const std::string &name) const
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Details::PropertyBase &prop)
Declare a property.
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
Gaudi::Details::PropertyBase * property(const std::string &name, const std::vector< Gaudi::Details::PropertyBase * > &props) const
get the property by name form the proposed list
T end(T...args)
void assertUniqueName(const std::string &name) const
Throw an exception if the name is already present in the list of properties (see GAUDI-1023).
virtual std::string toString() const =0
value -> string
bool isFailure() const
Definition: StatusCode.h:139
std::vector< Gaudi::Details::PropertyBase * > Properties
virtual StatusCode fromString(const std::string &value)=0
string -> value
void assertUniqueName(const std::string &name) const
Issue a runtime warning if the name is already present in the list of properties (see GAUDI-1023)...
std::vector< RemProperty > RemoteProperties
PropertyMgr & operator=(const PropertyMgr &)=delete
STL class.
typename std::remove_reference_t< T >::PropertyType PropertyType_t
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:79
T push_back(T...args)
RemoteProperties m_remoteProperties
Collection of all declared remote properties.
GAUDI_API ISvcLocator * svcLocator()
bool hasProperty(const std::string &name) const override
Return true if we have a property with the given name.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, TYPE &value, const std::string &doc="none")
Declare a property (templated)
bool iequal(const std::string &v1, const std::string &v2)
Helper for case insensitive string comparison.
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, Gaudi::Property< TYPE, VERIFIER, HANDLERS > &prop, const std::string &doc="none")
Declare a PropertyBase instance setting name and documentation.
The IMessage is the interface implemented by the message service.
Definition: IMessageSvc.h:38
T make_pair(T...args)
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:32
std::pair< std::string, std::pair< IProperty *, std::string > > RemProperty
void setName(std::string value)
set the new value for the property name
Definition: Property.h:90
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
virtual const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const =0
Get list of properties.
T get(T...args)
T find_if(T...args)
T size(T...args)
T begin(T...args)
StatusCode setProperty(const std::string &n, const std::string &v) override
set the property from name and the value
Properties m_properties
Collection of all declared properties.
Definition: PropertyMgr.h:138
Helper class to implement the IProperty interface.
T back(T...args)
string s
Definition: gaudirun.py:253
std::vector< std::unique_ptr< Gaudi::Details::PropertyBase > > m_todelete
Properties to be deleted.
Definition: PropertyMgr.h:142
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Gaudi::Details::PropertyBase * declareRemoteProperty(const std::string &name, IProperty *rsvc, const std::string &rname="")
Declare a remote property.
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:20
std::vector< std::unique_ptr< Gaudi::Details::PropertyBase > > m_todelete
Properties owned by PropertyHolder, to be deleted.
#define GAUDI_API
Definition: Kernel.h:104
StatusCode setProperty(const std::string &s) override
set the property from the formatted string
T equal(T...args)
void toupper(std::string &s)
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
RemoteProperties m_remoteProperties
Collection of all declared remote properties.
Definition: PropertyMgr.h:140
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, TYPE &value, const std::string &doc="none")
Helper to wrap a regular data member and use it as a regular property.
T emplace_back(T...args)