The Gaudi Framework  v33r1 (b1225454)
Property.cpp
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 "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 // ============================================================================
12 // Include files
13 // ============================================================================
14 // STD & STL
15 // ============================================================================
16 #include <algorithm>
17 #include <functional>
18 #include <iostream>
19 #include <string>
20 #include <unordered_set>
21 #include <utility>
22 #include <vector>
23 // ============================================================================
24 // GaudiKernel
25 // ============================================================================
27 #include "GaudiKernel/IProperty.h"
28 #include "GaudiKernel/Property.h"
30 #include "GaudiKernel/SmartIF.h"
31 // ============================================================================
32 // Boost
33 // ============================================================================
34 #include "boost/algorithm/string/compare.hpp"
35 // ============================================================================
36 namespace {
38  struct PtrCmp {
39  bool operator()( const std::unique_ptr<std::string>& a, const std::unique_ptr<std::string>& b ) const {
40  return *a == *b;
41  }
42  };
43  struct PtrHash {
44  std::size_t operator()( const std::unique_ptr<std::string>& s ) const { return std::hash<std::string>()( *s ); }
45  };
47  std::unordered_set<std::unique_ptr<std::string>, PtrHash, PtrCmp> all_strings;
48 } // namespace
49 
51 
52 std::string_view PropertyBase::to_view( std::string str ) {
53  return **( all_strings.insert( std::make_unique<std::string>( std::move( str ) ) ).first );
54 }
55 
56 // ============================================================================
57 // the printout of the property value
58 // ============================================================================
60  return stream << " '" << name() << "':" << toString();
61 }
62 
63 // ============================================================================
64 /* simple function which check the existence of the property with
65  * the given name.
66  *
67  * @code
68  *
69  * IInterface* p = .
70  *
71  * const bool = hasProperty( p , "Context" ) ;
72  *
73  * @endcode
74  *
75  * @param p pointer to IInterface object (any component)
76  * @param name property name (case insensitive)
77  * @return true if "p" has a property with such name
78  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
79  * @date 2006-09-09
80  */
81 // ============================================================================
83  // delegate to another method after trivial check
84  return p && getProperty( p, name );
85 }
86 // ============================================================================
87 /* simple function which check the existence of the property with
88  * the given name.
89  *
90  * @code
91  *
92  * const IProperty* p = ... ;
93  *
94  * const bool = hasProperty( p , "Context" ) ;
95  *
96  * @endcode
97  *
98  * @param p pointer to IProperty object
99  * @param name property name (case insensitive)
100  * @return true if "p" has a property with such name
101  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
102  * @date 2006-09-09
103  */
104 // ============================================================================
106  // delegate the actual work to another method ;
107  return p && getProperty( p, name );
108 }
109 // ============================================================================
110 //
111 // GaudiHandleProperty implementation
112 //
114  : PropertyWithHandlers( std::move( name_ ), typeid( GaudiHandleBase ) ), m_pValue( &ref ) {
116 }
117 
120  return useUpdateHandler();
121 }
122 
124  useReadHandler();
125  return m_pValue->typeAndName();
126 }
127 
129  useReadHandler();
130  out << m_pValue->typeAndName();
131 }
132 
136  return StatusCode::SUCCESS;
137 }
138 
139 //
140 // GaudiHandlePropertyArray implementation
141 //
143  : PropertyWithHandlers( std::move( name_ ), typeid( GaudiHandleArrayBase ) ), m_pValue( &ref ) {
145 }
146 
149  return useUpdateHandler();
150 }
151 
153  // treat as if a Gaudi::Property<std::vector<std::string>>
154  useReadHandler();
156 }
157 
159  // treat as if a Gaudi::Property<std::vector<std::string>>
160  useReadHandler();
162 }
163 
165  // treat as if a Gaudi::Property<std::vector<std::string>>
167  StatusCode sc = Gaudi::Parsers::parse( tmp, source );
168  if ( sc.isFailure() ) return sc;
169  if ( !m_pValue->setTypesAndNames( std::move( tmp ) ) ) return StatusCode::FAILURE;
171  return StatusCode::SUCCESS;
172 }
173 
174 // ============================================================================
175 namespace {
176  template <typename C, typename BinaryPredicate>
177  bool equal_( const C& c1, const C& c2, BinaryPredicate&& p ) {
178  return c1.size() == c2.size() &&
179  std::equal( std::begin( c1 ), std::end( c1 ), std::begin( c2 ), std::forward<BinaryPredicate>( p ) );
180  }
181 
182  // match (case insensitive) property by name
183  struct is_iByName {
185  is_iByName( const std::string& name ) : m_name( name ) {}
187  bool operator()( const PropertyBase* p ) const {
188  return p && equal_( m_name, p->name(), boost::algorithm::is_iequal{} );
189  };
190 
191  private:
192  const std::string& m_name;
193  };
194 } // namespace
195 // ============================================================================
196 /* simple function which gets the property with given name
197  * from the component
198  *
199  * @code
200  *
201  * const IProperty* p = ... ;
202  *
203  * auto pro = getProperty( p , "Context" ) ;
204  *
205  * @endcode
206  *
207  * @param p pointer to IProperty object
208  * @param name property name (case insensitive)
209  * @return property with the given name (if exists), NULL otherwise
210  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
211  * @date 2006-09-09
212  */
213 // ============================================================================
215  // trivial check
216  if ( !p ) { return nullptr; } // RETURN
217  // get all properties
218  const auto& props = p->getProperties();
219  // comparison criteria:
220  auto ifound = std::find_if( props.begin(), props.end(), is_iByName{name} );
221  return ifound != props.end() ? *ifound : nullptr;
222 }
223 // ============================================================================
224 /* simple function which gets the property with given name
225  * from the component
226  *
227  * @code
228  *
229  * const IInterface* p = ... ;
230  *
231  * auto pro = getProperty( p , "Context" ) ;
232  *
233  * @endcode
234  *
235  * @param p pointer to IInterface object
236  * @param name property name (case insensitive)
237  * @return property with the given name (if exists), NULL otherwise
238  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
239  * @date 2006-09-09
240  */
241 // ============================================================================
243  // trivial check
244  if ( !p ) { return nullptr; } // RETURN
245  // remove const-qualifier
246  IInterface* _i = const_cast<IInterface*>( p );
247  if ( !_i ) { return nullptr; } // RETURN
248  SmartIF<IProperty> property( _i );
249  return property ? getProperty( property, name ) : nullptr;
250 }
251 // ============================================================================
252 /* check the property by name from the list of the properties
253  *
254  * @code
255  *
256  * IJobOptionsSvc* svc = ... ;
257  *
258  * const std::string client = ... ;
259  *
260  * // get the property:
261  * bool context =
262  * hasProperty ( svc->getProperties( client ) , "Context" )
263  *
264  * @endcode
265  *
266  * @see IJobOptionsSvc
267  *
268  * @param p list of properties
269  * @param name property name (case insensitive)
270  * @return true if the property exists
271  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
272  * @date 2006-09-09
273  */
274 // ============================================================================
276  // delegate to another method
277  return getProperty( p, name );
278 }
279 // ============================================================================
280 /* get the property by name from the list of the properties
281  *
282  * @code
283  *
284  * IJobOptionsSvc* svc = ... ;
285  *
286  * const std::string client = ... ;
287  *
288  * // get the property:
289  * auto context = getProperty ( svc->getProperties( client ) , "Context" )
290  *
291  * @endcode
292  *
293  * @see IJobOptionsSvc
294  *
295  * @param p list of properties
296  * @param name property name (case insensitive)
297  * @return property with the given name (if exists), NULL otherwise
298  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
299  * @date 2006-09-09
300  */
301 // ============================================================================
303  // trivial check
304  if ( !p ) { return nullptr; } // RETURN
305  auto ifound = std::find_if( p->begin(), p->end(), is_iByName{name} );
306  return p->end() != ifound ? *ifound : nullptr; // RETURN
307 }
308 // ============================================================================
309 /* the full specialization of the
310  * method setProperty( IProperty, std::string, const TYPE&)
311  * for C-strings
312  *
313  * @param component component which needs to be configured
314  * @param name name of the property
315  * @param value value of the property
316  * @param doc the new documentation string
317  *
318  * @see IProperty
319  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
320  * @date 2007-05-13
321  */
322 // ============================================================================
323 StatusCode Gaudi::Utils::setProperty( IProperty* component, const std::string& name, const char* value,
324  const std::string& doc ) {
325  return Gaudi::Utils::setProperty( component, name, std::string{value}, doc );
326 }
327 // ============================================================================
328 /* the full specialization of the
329  * method Gaudi::Utils::setProperty( IProperty, std::string, const TYPE&)
330  * for standard strings
331  *
332  * @param component component which needs to be configured
333  * @param name name of the property
334  * @param value value of the property
335  *
336  * @see IProperty
337  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
338  * @date 2007-05-13
339  */
340 // ============================================================================
342  const std::string& doc ) {
343  if ( !component ) { return StatusCode::FAILURE; } // RETURN
344  if ( !hasProperty( component, name ) ) { return StatusCode::FAILURE; }
345  StatusCode sc = component->setProperty( name, value );
346  if ( !doc.empty() ) {
347  PropertyBase* p = getProperty( component, name );
348  if ( p ) { p->setDocumentation( doc ); }
349  }
350  sc.ignore();
351  return sc;
352 }
353 // ============================================================================
354 /* simple function to set the property of the given object from another
355  * property
356  *
357  * @code
358  *
359  * IProperty* component = ... ;
360  *
361  * const Gaudi::Details::PropertyBase* prop = ... ;
362  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
363  *
364  * @endcode
365  *
366  * @param component component which needs to be configured
367  * @param name name of the property
368  * @param property the property
369  * @param doc the new documentation string
370  *
371  * @see IProperty
372  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
373  * @date 2007-05-13
374  */
375 // ============================================================================
377  const std::string& doc ) {
378  if ( !component || !property ) return StatusCode::FAILURE;
379  PropertyBase* p = getProperty( component, name );
380  if ( !p || !p->assign( *property ) ) return StatusCode::FAILURE;
381  if ( !doc.empty() ) { p->setDocumentation( doc ); }
382  return StatusCode::SUCCESS;
383 }
384 // ============================================================================
385 /* simple function to set the property of the given object from another
386  * property
387  *
388  * @code
389  *
390  * IProperty* component = ... ;
391  *
392  * const Gaudi::Details::PropertyBase& prop = ... ;
393  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
394  *
395  * @endcode
396  *
397  * @param component component which needs to be configured
398  * @param name name of the property
399  * @param property the property
400  * @param doc the new documentation string
401  *
402  * @see IProperty
403  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
404  * @date 2007-05-13
405  */
406 // ============================================================================
408  const std::string& doc ) {
409  return setProperty( component, name, &property, doc );
410 }
411 // ============================================================================
412 /* the full specialization of the
413  * method setProperty( IInterface , std::string, const TYPE&)
414  * for standard strings
415  *
416  * @param component component which needs to be configured
417  * @param name name of the property
418  * @param value value of the property
419  * @param doc the new documentation string
420  *
421  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
422  * @date 2007-05-13
423  */
424 // ============================================================================
426  const std::string& doc ) {
427  if ( !component ) { return StatusCode::FAILURE; }
428  SmartIF<IProperty> property( component );
429  return property ? setProperty( property, name, value, doc ) : StatusCode::FAILURE;
430 }
431 // ============================================================================
432 /* the full specialization of the
433  * method setProperty( IInterface , std::string, const TYPE&)
434  * for C-strings
435  *
436  * @param component component which needs to be configured
437  * @param name name of the property
438  * @param value value of the property
439  * @param doc the new documentation string
440  *
441  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
442  * @date 2007-05-13
443  */
444 // ============================================================================
445 StatusCode Gaudi::Utils::setProperty( IInterface* component, const std::string& name, const char* value,
446  const std::string& doc ) {
447  return setProperty( component, name, std::string{value}, doc );
448 }
449 // ============================================================================
450 /* simple function to set the property of the given object from another
451  * property
452  *
453  * @code
454  *
455  * IInterface* component = ... ;
456  *
457  * const Gaudi::Details::PropertyBase* prop = ... ;
458  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
459  *
460  * @endcode
461  *
462  * @param component component which needs to be configured
463  * @param name name of the property
464  * @param property the property
465  * @param doc the new documentation string
466  *
467  * @see IProperty
468  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
469  * @date 2007-05-13
470  */
471 // ============================================================================
473  const std::string& doc ) {
474  if ( !component ) { return StatusCode::FAILURE; }
475  SmartIF<IProperty> prop( component );
476  if ( !prop ) { return StatusCode::FAILURE; }
477  return setProperty( prop, name, property, doc );
478 }
479 // ============================================================================
480 /* simple function to set the property of the given object from another
481  * property
482  *
483  * @code
484  *
485  * IInterface* component = ... ;
486  *
487  * const Gaudi::Details::PropertyBase& prop = ... ;
488  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
489  *
490  * @endcode
491  *
492  * @param component component which needs to be configured
493  * @param name name of the property
494  * @param property the property
495  * @param doc the new documentation string
496  *
497  * @see IProperty
498  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
499  * @date 2007-05-13
500  */
501 // ============================================================================
503  const std::string& doc ) {
504  return setProperty( component, name, &property, doc );
505 }
506 // ============================================================================
507 
508 // ============================================================================
509 // The END
510 // ============================================================================
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:1207
T empty(T... args)
std::ostream & toStream(ITERATOR first, ITERATOR last, std::ostream &s, const std::string &open, const std::string &close, const std::string &delim)
the helper function to print the sequence
Definition: ToStream.h:291
bool setValue(const GaudiHandleArrayBase &value)
Definition: Property.cpp:147
void setDocumentation(std::string value)
set the documentation string
Definition: Property.h:98
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
Definition: GaudiHandle.cpp:19
const GaudiHandleArrayBase & value() const
Definition: Property.h:931
virtual bool assign(const PropertyBase &source)=0
import the property value form the source
std::string typeAndName() const
The full type and name: "type/name".
Definition: GaudiHandle.h:125
const std::vector< std::string > typesAndNames() const
Return a vector with "type/name" strings of all handles in the array.
Definition: GaudiHandle.cpp:78
StatusCode fromString(const std::string &s) override
string -> value
Definition: Property.cpp:133
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:105
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:341
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
STL namespace.
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
T end(T... args)
const std::string name() const
property name
Definition: Property.h:46
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:247
void toStream(std::ostream &out) const override
value -> stream
Definition: Property.cpp:158
Helper class to simplify the migration old properties deriving directly from PropertyBase.
Definition: Property.h:834
STL class.
virtual StatusCode setProperty(const Gaudi::Details::PropertyBase &p)=0
Set the property by property.
GaudiHandleBase * m_pValue
Pointer to the real property.
Definition: Property.h:904
GaudiHandleProperty(std::string name, GaudiHandleBase &ref)
Definition: Property.cpp:113
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in <myTypesAndNamesList>.
Definition: GaudiHandle.cpp:63
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
Definition of the basic interface.
Definition: IInterface.h:254
GaudiHandleArrayProperty(std::string name, GaudiHandleArrayBase &ref)
Definition: Property.cpp:142
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:243
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:42
std::string toString() const override
value -> string
Definition: Property.cpp:123
virtual std::ostream & fillStream(std::ostream &) const
the printout of the property value
Definition: Property.cpp:59
T move(T... args)
StatusCode fromString(const std::string &s) override
string -> value
Definition: Property.cpp:164
T find_if(T... args)
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:168
Base class of array's of various gaudihandles.
Definition: GaudiHandle.h:340
STL class.
void toStream(std::ostream &out) const override
value -> stream
Definition: Property.cpp:128
void setPropertyName(std::string propName)
set name as used in declareProperty(name,gaudiHandle).
Definition: GaudiHandle.h:60
bool useUpdateHandler() override
use the call-back function at update, if available
Definition: Property.h:860
T begin(T... args)
GaudiHandleArrayBase * m_pValue
Pointer to the real property.
Definition: Property.h:941
virtual const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const =0
Get list of properties.
string s
Definition: gaudirun.py:328
constexpr static const auto FAILURE
Definition: StatusCode.h:101
bool isFailure() const
Definition: StatusCode.h:145
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
Definition: GaudiHandle.h:99
std::string toString() const override
value -> string
Definition: Property.cpp:152
const GaudiHandleBase & value() const
Definition: Property.h:894
The IProperty is the basic interface for all components which have properties that can be set or get.
Definition: IProperty.h:30
STL class.
T equal(T... args)
virtual std::string toString() const =0
value -> string
bool setValue(const GaudiHandleBase &value)
Definition: Property.cpp:118
GAUDI_API Gaudi::Details::PropertyBase * getProperty(const IProperty *p, const std::string &name)
simple function which gets the property with given name from the component
Definition: Property.cpp:214
void useReadHandler() const
use the call-back function at reading, if available
Definition: Property.h:857