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 
26 // ============================================================================
27 
28 // pre-declaration of GaudiHandles is sufficient
29 template <class T>
30 class ToolHandle;
31 template <class T>
33 template <class T>
35 template <class T>
37 template <class T>
38 class DataObjectHandle;
39 
40 namespace Gaudi
41 {
42  namespace Utils
43  {
45  inline bool iequal( const std::string& v1, const std::string& v2 )
46  {
47  return v1.size() == v2.size() && std::equal( std::begin( v1 ), std::end( v1 ), std::begin( v2 ),
48  []( char c1, char c2 ) { return toupper( c1 ) == toupper( c2 ); } );
49  }
50  }
51 }
72 template <class BASE>
73 class GAUDI_API PropertyHolder : public BASE
74 {
76  "PropertyHolder template argument must inherit from IProperty and INamedInterface" );
77 
78 public:
86 
87  PropertyHolder() = default;
88  ~PropertyHolder() override = default;
89 
92  PropertyHolder( const PropertyHolder& ) = delete;
93  PropertyHolder& operator=( const PropertyHolder& ) = delete;
95 
96 public:
100  {
101  assertUniqueName( prop.name() );
102  m_properties.push_back( &prop );
103  return prop;
104  }
105 
108  template <class TYPE>
109  Gaudi::Details::PropertyBase* declareProperty( const std::string& name, TYPE& value, const std::string& doc = "none" )
110  {
111  assertUniqueName( name );
112  m_todelete.emplace_back( new Gaudi::Property<TYPE&>( name, value ) );
114  p->setDocumentation( doc );
115  m_properties.push_back( p );
116  return p;
117  }
118 
120  template <class TYPE>
121  [[deprecated(
122  "Kept for backward compatibility, use the non-const version instead, will be removed in v28r1" )]] Gaudi::
123  Details::PropertyBase*
124  declareProperty( const std::string& name, TYPE& value, const std::string& doc = "none" ) const
125  {
126  return const_cast<PropertyHolder*>( this )->declareProperty<TYPE>( name, value, doc );
127  }
128 
131  template <class TYPE, class VERIFIER, class HANDLERS>
134  const std::string& doc = "none" )
135  {
136  assertUniqueName( name );
137  Gaudi::Details::PropertyBase* p = &prop;
138  p->setName( name );
139  p->setDocumentation( doc );
140  m_properties.push_back( p );
141  return p;
142  }
143 
147  const std::string& rname = "" )
148  {
149  if ( !rsvc ) {
150  return nullptr;
151  }
152  const std::string& nam = rname.empty() ? name : rname;
154  m_remoteProperties.emplace_back( name, std::make_pair( rsvc, nam ) );
155  return p;
156  }
157 
160  template <class TYPE>
162  const std::string& doc = "none" )
163  {
164  assertUniqueName( name );
165  m_todelete.emplace_back( new GaudiHandleProperty( name, ref ) );
167 
168  p->setDocumentation( doc );
169  m_properties.push_back( p );
170 
171  return p;
172  }
173  template <class TYPE>
175  const std::string& doc = "none" )
176  {
177  assertUniqueName( name );
178  m_todelete.emplace_back( new GaudiHandleProperty( name, ref ) );
180 
181  p->setDocumentation( doc );
182  m_properties.push_back( p );
183 
184  return p;
185  }
186  template <class TYPE>
188  const std::string& doc = "none" )
189  {
190  assertUniqueName( name );
193 
194  p->setDocumentation( doc );
195  m_properties.push_back( p );
196 
197  return p;
198  }
199  template <class TYPE>
201  const std::string& doc = "none" )
202  {
203  assertUniqueName( name );
206 
207  p->setDocumentation( doc );
208  m_properties.push_back( p );
209 
210  return p;
211  }
212  template <class TYPE>
214  const std::string& doc = "none" )
215  {
216  assertUniqueName( name );
219 
220  p->setDocumentation( doc );
221  m_properties.push_back( p );
222 
223  return p;
224  }
226 
227  // ==========================================================================
228  // IProperty implementation
229  // ==========================================================================
234  {
236  try {
237  if ( pp && pp->assign( p ) ) {
238  return StatusCode::SUCCESS;
239  }
240  } catch ( ... ) {
241  }
242  return StatusCode::FAILURE;
243  }
244  // ==========================================================================
248  StatusCode setProperty( const std::string& s ) override
249  {
251  std::string value;
252  StatusCode sc = Gaudi::Parsers::parse( name, value, s );
253  if ( sc.isFailure() ) {
254  return sc;
255  }
256  return setProperty( name, value );
257  }
258  // ==========================================================================
262  StatusCode setProperty( const std::string& n, const std::string& v ) override
263  {
265  return ( p && p->fromString( v ) ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
266  }
307  template <class TYPE>
308  StatusCode setProperty( const std::string& name, const TYPE& value )
309  {
310  return Gaudi::Utils::setProperty( this, name, value );
311  }
312  // ==========================================================================
317  {
318  try {
319  const Gaudi::Details::PropertyBase* pp = property( p->name() );
320  if ( pp && pp->load( *p ) ) return StatusCode::SUCCESS;
321  } catch ( ... ) {
322  }
323  return StatusCode::FAILURE;
324  }
325  // ==========================================================================
330  {
331  const Gaudi::Details::PropertyBase* p = property( name );
332  if ( !p ) throw std::out_of_range( "Property " + name + " not found." );
333  return *p;
334  }
335  // ==========================================================================
339  StatusCode getProperty( const std::string& n, std::string& v ) const override
340  {
341  // get the property
342  const Gaudi::Details::PropertyBase* p = property( n );
343  if ( !p ) {
344  return StatusCode::FAILURE;
345  }
346  // convert the value into the string
347  v = p->toString();
348  return StatusCode::SUCCESS;
349  }
350  // ==========================================================================
355  // ==========================================================================
359  bool hasProperty( const std::string& name ) const override
360  {
361  return any_of( begin( m_properties ), end( m_properties ), [&name]( const Gaudi::Details::PropertyBase* prop ) {
362  return Gaudi::Utils::iequal( prop->name(), name );
363  } );
364  }
365  // ==========================================================================
366 protected:
367  // get local or remote property by name
369  {
370  // local property ?
372  if ( lp ) {
373  return lp;
374  }
375  // look for remote property
376  for ( const auto& it : m_remoteProperties ) {
377  if ( !Gaudi::Utils::iequal( it.first, name ) ) {
378  continue;
379  }
380  const IProperty* p = it.second.first;
381  if ( !p ) {
382  continue;
383  }
384  return property( it.second.second, p->getProperties() );
385  }
386  return nullptr; // RETURN
387  }
388 
389 private:
392  const std::vector<Gaudi::Details::PropertyBase*>& props ) const
393  {
394  auto it = std::find_if( props.begin(), props.end(), [&name]( Gaudi::Details::PropertyBase* p ) {
395  return p && Gaudi::Utils::iequal( p->name(), name );
396  } );
397  return ( it != props.end() ) ? *it : nullptr; // RETURN
398  }
399 
402  void assertUniqueName( const std::string& name ) const
403  {
404  if ( UNLIKELY( hasProperty( name ) ) ) {
405  auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
406  if ( !msgSvc ) {
407  std::cerr << "error: cannot get MessageSvc!" << std::endl;
408  }
409  MsgStream log( msgSvc, this->name() );
410  log << MSG::WARNING << "duplicated property name '" << name << "', see https://its.cern.ch/jira/browse/GAUDI-1023"
411  << endmsg;
412  }
413  }
414 
418 
420  Properties m_properties;
422  RemoteProperties m_remoteProperties;
425 };
426 #endif
Handle to be used in lieu of naked pointers to services.
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:1123
StatusCode getProperty(Gaudi::Details::PropertyBase *p) const override
get the property
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ToolHandle< TYPE > &ref, const std::string &doc="none")
Specializations for various GaudiHandles.
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:313
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
AttribStringParser::Iterator end(const AttribStringParser &)
Properties m_properties
Collection of all declared properties.
GAUDI_API bool hasProperty(const IProperty *p, const std::string &name)
simple function which check the existence of the property with the given name.
Definition: Property.cpp:100
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.
T endl(T...args)
Gaudi::Details::PropertyBase * property(const std::string &name) const
#define UNLIKELY(x)
Definition: Kernel.h:126
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Details::PropertyBase &prop)
Declare a property.
Array of Handles to be used in lieu of vector of naked pointers to tools.
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
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.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
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)...
DataObjectHandleProperty.h GaudiKernel/DataObjectHandleProperty.h.
std::vector< RemProperty > RemoteProperties
PropertyMgr & operator=(const PropertyMgr &)=delete
STL class.
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
Definition: AlgTool.h:25
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ServiceHandleArray< TYPE > &ref, const std::string &doc="none")
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:78
T push_back(T...args)
RemoteProperties m_remoteProperties
Collection of all declared remote properties.
GAUDI_API ISvcLocator * svcLocator()
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
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:57
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ServiceHandle< TYPE > &ref, const std::string &doc="none")
Array of Handles to be used in lieu of vector of naked pointers to tools.
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
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, TYPE &value, const std::string &doc="none") const
virtual const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const =0
Get list of properties.
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ToolHandleArray< TYPE > &ref, const std::string &doc="none")
T get(T...args)
Handle to be used in lieu of naked pointers to tools.
T find_if(T...args)
T size(T...args)
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, DataObjectHandle< TYPE > &ref, const std::string &doc="none")
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:159
Helper class to implement the IProperty interface.
T back(T...args)
string s
Definition: gaudirun.py:245
std::vector< std::unique_ptr< Gaudi::Details::PropertyBase > > m_todelete
Properties to be deleted.
Definition: PropertyMgr.h:163
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:107
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:244
RemoteProperties m_remoteProperties
Collection of all declared remote properties.
Definition: PropertyMgr.h:161
T emplace_back(T...args)