The Gaudi Framework  master (42b00024)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PropertyHolder.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 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 "LICENSE". *
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 #ifndef GAUDIKERNEL_PROPERTYHOLDER_H
12 #define GAUDIKERNEL_PROPERTYHOLDER_H
13 // ============================================================================
14 // Include files
15 // ============================================================================
16 // STD & STL
17 // ============================================================================
18 #include <algorithm>
19 #include <functional>
20 #include <iostream>
21 #include <stdexcept>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 // ============================================================================
26 // GaudiKernel
27 // ============================================================================
28 #include <Gaudi/Property.h>
29 #include <GaudiKernel/Bootstrap.h>
32 #include <GaudiKernel/IProperty.h>
34 #include <GaudiKernel/MsgStream.h>
35 
37 // ============================================================================
38 namespace Gaudi {
39  namespace Details {
40 
41  template <typename T>
42  constexpr bool is_gaudi_property_v = false;
43 
44  template <typename TYPE, typename VERIFIER, typename HANDLERS>
45  constexpr bool is_gaudi_property_v<Gaudi::Property<TYPE, VERIFIER, HANDLERS>> = true;
46 
47  } // namespace Details
48  namespace Utils {
50  inline bool iequal( std::string_view v1, std::string_view v2 ) {
51  return std::equal( begin( v1 ), end( v1 ), begin( v2 ), end( v2 ),
52  []( char c1, char c2 ) { return toupper( c1 ) == toupper( c2 ); } );
53  }
54  } // namespace Utils
55 } // namespace Gaudi
76 template <class BASE>
77 class GAUDI_API PropertyHolder : public BASE {
78  static_assert( std::is_base_of_v<IProperty, BASE> && std::is_base_of_v<INamedInterface, BASE>,
79  "PropertyHolder template argument must inherit from IProperty and INamedInterface" );
80 
81 public:
89 
90  PropertyHolder() = default;
91 
94  PropertyHolder( const PropertyHolder& ) = delete;
97 
98 public:
102  assertUniqueName( prop.name() );
103  m_properties.push_back( &prop );
104  return prop;
105  }
106 
109  template <typename TYPE>
110  requires( !Gaudi::Details::is_gaudi_property_v<TYPE> )
111  Gaudi::Details::PropertyBase* declareProperty( const std::string& name, TYPE& value,
112  const std::string& doc = "none" ) {
113  auto make_property = [&]( const std::string& n, TYPE& v ) {
114  if constexpr ( requires { typename TYPE::PropertyType; } ) {
115  return std::make_unique<typename TYPE::PropertyType>( n, v );
116  } else {
117  return std::make_unique<Gaudi::Property<TYPE&>>( n, v );
118  }
119  };
120  m_todelete.push_back( make_property( name, value ) );
121  Gaudi::Details::PropertyBase* p = m_todelete.back().get();
122 
123  p->setDocumentation( doc );
124  return &declareProperty( *p );
125  }
126 
129  template <class TYPE, class VERIFIER, class HANDLERS>
132  const std::string& doc = "none" ) {
133  Gaudi::Details::PropertyBase* p = &prop;
134  p->setName( name );
135 
136  p->setDocumentation( doc );
137  return &declareProperty( *p );
138  }
139 
143  const std::string& rname = "" ) {
144  if ( !rsvc ) return nullptr;
145  const std::string& nam = rname.empty() ? name : rname;
146  Gaudi::Details::PropertyBase* p = property( nam, rsvc->getProperties() );
147  m_remoteProperties.emplace_back( RemProperty{ name, rsvc, nam } );
148  return p;
149  }
150 
152 
153  // ==========================================================================
154  // IProperty implementation
155  // ==========================================================================
160  StatusCode setProperty( const std::string& name, const Gaudi::Details::PropertyBase& p ) override {
161  Gaudi::Details::PropertyBase* pp = property( name );
162  if ( pp && pp->assign( p ) ) return StatusCode::SUCCESS;
163  return StatusCode::FAILURE;
164  }
165  // ==========================================================================
169  StatusCode setProperty( const std::string& s ) override {
170  std::string name;
171  std::string value;
172  StatusCode sc = Gaudi::Parsers::parse( name, value, s );
173  if ( sc.isFailure() ) return sc;
174  return setPropertyRepr( name, value );
175  }
176  // ==========================================================================
180  StatusCode setPropertyRepr( const std::string& n, const std::string& r ) override {
181  try {
182  Gaudi::Details::PropertyBase* p = property( n );
184  return ( p && p->fromString( r ) ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
185  } catch ( const std::invalid_argument& err ) {
186  throw GaudiException{ "error setting property " + n, this->name(), StatusCode::FAILURE, err };
187  }
188  }
189  // ==========================================================================
194  try {
195  const Gaudi::Details::PropertyBase* pp = property( p->name() );
196  if ( pp && pp->load( *p ) ) return StatusCode::SUCCESS;
197  } catch ( ... ) {}
198  return StatusCode::FAILURE;
199  }
200  // ==========================================================================
204  const Gaudi::Details::PropertyBase& getProperty( std::string_view name ) const override {
205  const Gaudi::Details::PropertyBase* p = property( name );
206  if ( !p ) throw std::out_of_range( "Property " + std::string{ name } + " not found." );
207  return *p;
208  }
209  // ==========================================================================
213  StatusCode getProperty( std::string_view n, std::string& v ) const override {
214  // get the property
215  const Gaudi::Details::PropertyBase* p = property( n );
216  if ( !p ) return StatusCode::FAILURE;
217  // convert the value into the string
218  v = p->toString();
219  return StatusCode::SUCCESS;
220  }
221  // ==========================================================================
225  const std::vector<Gaudi::Details::PropertyBase*>& getProperties() const override { return m_properties; }
226  // ==========================================================================
230  bool hasProperty( std::string_view name ) const override {
231  return any_of( begin( m_properties ), end( m_properties ),
232  [&name]( const Gaudi::Details::PropertyBase* prop ) {
233  return Gaudi::Utils::iequal( prop->name(), name );
234  } ) ||
235  any_of( begin( m_remoteProperties ), end( m_remoteProperties ),
236  [&name]( const auto& prop ) { return Gaudi::Utils::iequal( prop.name, name ); } );
237  }
238  // ==========================================================================
240  // get local or remote property by name
241  Gaudi::Details::PropertyBase* property( std::string_view name ) const {
242  // local property ?
243  Gaudi::Details::PropertyBase* lp = property( name, m_properties );
244  if ( lp ) return lp;
245  // look for remote property
246  for ( const auto& it : m_remoteProperties ) {
247  if ( !Gaudi::Utils::iequal( it.name, name ) ) continue;
248  const IProperty* p = it.owner;
249  if ( !p ) continue;
250  return property( it.remName, p->getProperties() );
251  }
252  return nullptr; // RETURN
253  }
254 
256  auto set_prop = [&optsSvc, this]( auto prop ) { optsSvc.bind( this->name(), prop ); };
257  std::for_each( begin( m_properties ), end( m_properties ), set_prop );
258  std::for_each( begin( m_remoteProperties ), end( m_remoteProperties ), [&set_prop, this]( auto& rem ) {
259  if ( rem.owner ) set_prop( this->property( rem.remName, rem.owner->getProperties() ) );
260  } );
261  }
262 
263 private:
266  const std::vector<Gaudi::Details::PropertyBase*>& props ) const {
267  auto it = std::find_if( props.begin(), props.end(), [name]( Gaudi::Details::PropertyBase* p ) {
268  return p && Gaudi::Utils::iequal( p->name(), name );
269  } );
270  return ( it != props.end() ) ? *it : nullptr; // RETURN
271  }
272 
275  void assertUniqueName( std::string_view name ) const {
276  if ( hasProperty( name ) ) {
277  auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
278  if ( !msgSvc ) std::cerr << "error: cannot get MessageSvc!" << std::endl;
279  MsgStream log( msgSvc, this->name() );
280  log << MSG::WARNING << "duplicated property name '" << name << "', see https://its.cern.ch/jira/browse/GAUDI-1023"
281  << endmsg;
282  }
283  }
284 
285  typedef std::vector<Gaudi::Details::PropertyBase*> Properties;
286  struct RemProperty {
287  std::string name;
288  IProperty* owner = nullptr;
289  std::string remName;
290  };
291  typedef std::vector<RemProperty> RemoteProperties;
292 
298  std::vector<std::unique_ptr<Gaudi::Details::PropertyBase>> m_todelete;
299 };
300 #endif
Gaudi::Details::PropertyBase
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: PropertyBase.h:35
Gaudi::Details::PropertyBase::name
const std::string name() const
property name
Definition: PropertyBase.h:39
toupper
void toupper(std::string &s)
Definition: ExceptionSvc.cpp:36
PropertyHolder::declareProperty
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.
Definition: PropertyHolder.h:130
IMessageSvc
Definition: IMessageSvc.h:47
Gaudi.Configuration.log
log
Definition: Configuration.py:28
GaudiPartProp.tests.v1
v1
Definition: tests.py:39
DataHandleProperty.h
Gaudi::Parsers::parse
StatusCode parse(GaudiUtils::HashMap< K, V > &result, std::string_view input)
Basic parser for the types of HashMap used in DODBasicMapper.
Definition: DODBasicMapper.cpp:21
gaudirun.s
string s
Definition: gaudirun.py:346
PropertyHolder::RemProperty
Definition: PropertyHolder.h:286
check_ParticleID.props
props
Definition: check_ParticleID.py:21
GaudiException
Definition: GaudiException.h:32
PropertyHolder::setProperty
StatusCode setProperty(const std::string &name, const Gaudi::Details::PropertyBase &p) override
set the property from another property with a different name
Definition: PropertyHolder.h:160
MSG::WARNING
@ WARNING
Definition: IMessageSvc.h:25
PropertyHolder::getProperty
StatusCode getProperty(Gaudi::Details::PropertyBase *p) const override
get the property
Definition: PropertyHolder.h:193
PropertyHolder
Helper class to implement the IProperty interface.
Definition: PropertyHolder.h:77
Gaudi::Functional::details::detail2::requires
requires requires
Definition: details.h:433
Gaudi::Details::PropertyBase::fromString
virtual StatusCode fromString(const std::string &value)=0
string -> value
PropertyHolder::assertUniqueName
void assertUniqueName(std::string_view name) const
Issue a runtime warning if the name is already present in the list of properties (see GAUDI-1023).
Definition: PropertyHolder.h:275
PropertyHolder::m_todelete
std::vector< std::unique_ptr< Gaudi::Details::PropertyBase > > m_todelete
Properties owned by PropertyHolder, to be deleted.
Definition: PropertyHolder.h:298
PropertyHolder::RemProperty::name
std::string name
Definition: PropertyHolder.h:287
PropertyHolder::declareRemoteProperty
Gaudi::Details::PropertyBase * declareRemoteProperty(const std::string &name, IProperty *rsvc, const std::string &rname="")
Declare a remote property.
Definition: PropertyHolder.h:142
PropertyHolder::bindPropertiesTo
void bindPropertiesTo(Gaudi::Interfaces::IOptionsSvc &optsSvc)
Definition: PropertyHolder.h:255
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
PropertyHolder::property
Gaudi::Details::PropertyBase * property(std::string_view name) const
\fixme property and bindPropertiesTo should be protected
Definition: PropertyHolder.h:241
Properties
Definition: Properties.py:1
PropertyHolder::getProperties
const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const override
get all properties
Definition: PropertyHolder.h:225
PropertyHolder::property
Gaudi::Details::PropertyBase * property(std::string_view name, const std::vector< Gaudi::Details::PropertyBase * > &props) const
get the property by name form the proposed list
Definition: PropertyHolder.h:265
IProperty
Definition: IProperty.h:33
Gaudi::svcLocator
GAUDI_API ISvcLocator * svcLocator()
ISvcLocator::service
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
Gaudi::Interfaces::IOptionsSvc::bind
virtual void bind(const std::string &prefix, Gaudi::Details::PropertyBase *property)=0
Register a Gaudi::Property instance to the option service.
INamedInterface.h
Gaudi::Details::PropertyBase::setDocumentation
void setDocumentation(std::string value)
set the documentation string
Definition: PropertyBase.h:91
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:136
StatusCode
Definition: StatusCode.h:65
Gaudi::cxx::for_each
void for_each(ContainerOfSynced &c, Fun &&f)
Definition: SynchronizedValue.h:98
PropertyHolder::setProperty
StatusCode setProperty(const std::string &s) override
set the property from the formatted string
Definition: PropertyHolder.h:169
PropertyHolder::setPropertyRepr
StatusCode setPropertyRepr(const std::string &n, const std::string &r) override
set the property from name and value string representation
Definition: PropertyHolder.h:180
GaudiPartProp.tests.v2
v2
Definition: tests.py:59
Gaudi::Utils::iequal
bool iequal(std::string_view v1, std::string_view v2)
Helper for case insensitive string comparison.
Definition: PropertyHolder.h:50
Gaudi::Utils::end
AttribStringParser::Iterator end(const AttribStringParser &)
Definition: AttribStringParser.h:139
PropertyHolder::PropertyHolder
PropertyHolder(const PropertyHolder &)=delete
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
MsgStream
Definition: MsgStream.h:33
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
cpluginsvc.n
n
Definition: cpluginsvc.py:234
PropertyHolder::PropertyHolder
PropertyHolder()=default
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:130
PropertyHolder::requires
requires(!Gaudi::Details::is_gaudi_property_v< TYPE >) Gaudi
Helper to wrap a regular data member and use it as a regular property.
Definition: PropertyHolder.h:110
PropertyHolder::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Details::PropertyBase &prop)
Declare a property.
Definition: PropertyHolder.h:101
PropertyHolder::m_properties
Properties m_properties
Collection of all declared properties.
Definition: PropertyHolder.h:294
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
IProperty::getProperties
virtual const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const =0
Get list of properties.
PropertyHolder::getProperty
const Gaudi::Details::PropertyBase & getProperty(std::string_view name) const override
get the property by name
Definition: PropertyHolder.h:204
Gaudi::Details::PropertyBase::toString
virtual std::string toString() const =0
value -> string
AlgSequencer.c1
c1
Definition: AlgSequencer.py:32
Bootstrap.h
PropertyHolder::Properties
std::vector< Gaudi::Details::PropertyBase * > Properties
Definition: PropertyHolder.h:285
Properties.v
v
Definition: Properties.py:122
AlgSequencer.c2
c2
Definition: AlgSequencer.py:33
Gaudi::Details::PropertyBase::setName
void setName(std::string value)
set the new value for the property name
Definition: PropertyBase.h:89
PropertyHolder::RemoteProperties
std::vector< RemProperty > RemoteProperties
Definition: PropertyHolder.h:291
PropertyHolder::getProperty
StatusCode getProperty(std::string_view n, std::string &v) const override
convert the property to the string
Definition: PropertyHolder.h:213
PropertyHolder::RemProperty::remName
std::string remName
Definition: PropertyHolder.h:289
IProperty.h
IOTest.end
end
Definition: IOTest.py:125
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
ISvcLocator.h
compareOutputFiles.pp
pp
Definition: compareOutputFiles.py:507
Gaudi::Interfaces::IOptionsSvc
Interface for a component that manages application configuration options.
Definition: IOptionsSvc.h:46
IOptionsSvc.h
Gaudi::Details::is_gaudi_property_v
constexpr bool is_gaudi_property_v
Definition: PropertyHolder.h:42
GAUDI_API
#define GAUDI_API
Definition: Kernel.h:84
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:37
PropertyHolder::operator=
PropertyHolder & operator=(const PropertyHolder &)=delete
Gaudi::Utils::hasProperty
GAUDI_API bool hasProperty(const IProperty *p, std::string_view name)
simple function which check the existence of the property with the given name.
Definition: Property.cpp:106
Property.h
MsgStream.h
PropertyHolder::m_remoteProperties
RemoteProperties m_remoteProperties
Collection of all declared remote properties.
Definition: PropertyHolder.h:296
PropertyHolder::hasProperty
bool hasProperty(std::string_view name) const override
Return true if we have a property with the given name.
Definition: PropertyHolder.h:230
IProperty::setProperty
StatusCode setProperty(const Gaudi::Details::PropertyBase &p)
Set the property from a property.
Definition: IProperty.h:39