Property.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD & STL
5 // ============================================================================
6 #include <iostream>
7 #include <vector>
8 #include <string>
9 #include <utility>
10 #include <algorithm>
11 #include <functional>
12 // ============================================================================
13 // GaudiKernel
14 // ============================================================================
15 #include "GaudiKernel/IProperty.h"
16 #include "GaudiKernel/SmartIF.h"
17 #include "GaudiKernel/Property.h"
18 #include "GaudiKernel/GaudiHandle.h"
19 // ============================================================================
20 // Boost
21 // ============================================================================
22 #include "boost/algorithm/string/compare.hpp"
23 // ============================================================================
29 // ============================================================================
30 // The output operator for friendly printout
31 // ============================================================================
32 std::ostream& operator<<( std::ostream& stream ,
33  const Property& prop )
34 { return prop.fillStream ( stream ) ; }
35 // ============================================================================
36 /* constructor from the property name and the type
37  * @param name proeprty name
38  * @param type property C++/RTTI type
39  */
40 // ============================================================================
42 ( const std::type_info& type ,
43  std::string name )
44  : m_name ( std::move(name) )
45  , m_documentation ( m_name )
46  , m_typeinfo ( &type )
47 {}
48 // ============================================================================
49 /* constructor from the property name and the type
50  * @param type property C++/RTTI type
51  * @param name proeprty name
52  */
53 // ============================================================================
55 ( std::string name ,
56  const std::type_info& type )
57  : m_name ( std::move(name) )
58  , m_documentation ( m_name )
59  , m_typeinfo ( &type )
60 {}
61 // ============================================================================
62 // set new callback for reading
63 // ============================================================================
64 void Property::declareReadHandler( std::function<void(Property&)> fun )
65 {
66  m_readCallBack = std::move(fun);
67 }
68 // ============================================================================
69 // set new callback for update
70 // ============================================================================
71 void Property::declareUpdateHandler ( std::function<void(Property&)> fun )
72 {
73  m_updateCallBack = std::move(fun);
74 }
75 // ============================================================================
76 // use the call-back function at reading
77 // ============================================================================
79 {
80  if ( !m_readCallBack ) { return ; } // RETURN
81  // avoid infinite loop
82  std::function<void(Property&)> theCallBack;
83  theCallBack.swap(m_readCallBack);
84  theCallBack( const_cast<Property&>(*this) ) ;
85  m_readCallBack.swap(theCallBack);
86 }
87 // ============================================================================
88 // use the call-back function at update
89 // ============================================================================
91 {
92  bool sc(true);
93  if ( !m_updateCallBack ) { return sc; } // RETURN
94  // avoid infinite loop
95  std::function<void(Property&)> theCallBack;
96  theCallBack.swap(m_updateCallBack);
97  try {
98  theCallBack( *this ) ;
99  } catch(...) {
100  sc = false;
101  }
102  m_updateCallBack.swap(theCallBack);
103  return sc;
104 }
105 // ============================================================================
106 // the printout of the property value
107 // ============================================================================
108 std::ostream&
109 Property::fillStream ( std::ostream& stream ) const
110 { return stream << " '" <<name() << "':" << toString() ; }
111 // ============================================================================
112 /* simple function which check the existence of the property with
113  * the given name.
114  *
115  * @code
116  *
117  * IInterface* p = .
118  *
119  * const bool = hasProperty( p , "Context" ) ;
120  *
121  * @endcode
122  *
123  * @param p pointer to IInterface object (any component)
124  * @param name property name (case insensitive)
125  * @return true if "p" has a property with such name
126  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
127  * @date 2006-09-09
128  */
129 // ============================================================================
131 ( const IInterface* p ,
132  const std::string& name )
133 {
134  // delegate to another method after trivial check
135  return p && getProperty ( p , name ) ;
136 }
137 // ============================================================================
138 /* simple function which check the existence of the property with
139  * the given name.
140  *
141  * @code
142  *
143  * const IProperty* p = ... ;
144  *
145  * const bool = hasProperty( p , "Context" ) ;
146  *
147  * @endcode
148  *
149  * @param p pointer to IProperty object
150  * @param name property name (case insensitive)
151  * @return true if "p" has a property with such name
152  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
153  * @date 2006-09-09
154  */
155 // ============================================================================
157 ( const IProperty* p ,
158  const std::string& name )
159 {
160  // delegate the actual work to another method ;
161  return p && getProperty ( p , name ) ;
162 }
163 // ============================================================================
164 //
165 // GaudiHandleProperty implementation
166 //
168 ( std::string name_, GaudiHandleBase& ref )
169  : Property( std::move(name_), typeid( GaudiHandleBase ) ), m_pValue( &ref )
170 {
171  m_pValue->setPropertyName( name() );
172 }
173 
175  m_pValue->setTypeAndName( value.typeAndName() );
176  return useUpdateHandler();
177 }
178 
179 std::string GaudiHandleProperty::toString( ) const {
180  useReadHandler();
181  return m_pValue->typeAndName();
182 }
183 
184 void GaudiHandleProperty::toStream(std::ostream& out) const {
185  useReadHandler();
186  out << m_pValue->typeAndName();
187 }
188 
190  m_pValue->setTypeAndName( s );
192 }
193 
194 
195 //
196 // GaudiHandlePropertyArray implementation
197 //
199  : Property( std::move(name_), typeid( GaudiHandleArrayBase ) ), m_pValue( &ref )
200 {
202 }
203 
206  return useUpdateHandler();
207 }
208 
210  // treat as if a StringArrayProperty
211  useReadHandler();
213 }
214 
215 void GaudiHandleArrayProperty::toStream(std::ostream &out) const {
216  // treat as if a StringArrayProperty
217  useReadHandler();
219 }
220 
221 StatusCode GaudiHandleArrayProperty::fromString( const std::string& source ) {
222  // treat as if a StringArrayProperty
223  std::vector< std::string > tmp;
224  StatusCode sc = Gaudi::Parsers::parse ( tmp , source );
225  if ( sc.isFailure() ) return sc;
226  if ( !m_pValue->setTypesAndNames( std::move(tmp) ) ) return StatusCode::FAILURE;
228 }
229 
230 
231 
232 // ============================================================================
233 namespace
234 {
235  template <typename C, typename BinaryPredicate>
236  bool equal_(const C& c1, const C& c2, BinaryPredicate&& p) {
237  return c1.size() == c2.size() &&
238  std::equal(std::begin(c1), std::end(c1), std::begin(c2),
239  std::forward<BinaryPredicate>(p) );
240  }
241 
242  // match (case insensitive) property by name
243  struct is_iByName
244  {
246  is_iByName ( const std::string& name ) : m_name ( name ) {}
248  bool operator () ( const Property* p ) const
249  {
250  return p && equal_(m_name,p->name(),boost::algorithm::is_iequal{});
251  } ;
252  private:
253  const std::string& m_name ;
254  } ;
255 }
256 // ============================================================================
257 /* simple function which gets the property with given name
258  * from the component
259  *
260  * @code
261  *
262  * const IProperty* p = ... ;
263  *
264  * const Property* pro = getProperty( p , "Context" ) ;
265  *
266  * @endcode
267  *
268  * @param p pointer to IProperty object
269  * @param name property name (case insensitive)
270  * @return property with the given name (if exists), NULL otherwise
271  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
272  * @date 2006-09-09
273  */
274 // ============================================================================
276 ( const IProperty* p ,
277  const std::string& name )
278 {
279  // trivial check
280  if ( !p ) { return nullptr ; } // RETURN
281  // get all properties
282  const auto& props = p->getProperties() ;
283  // comparison criteria:
284  auto ifound = std::find_if ( props.begin(), props.end(), is_iByName{ name } );
285  return ifound != props.end() ? *ifound : nullptr;
286 }
287 // ============================================================================
288 /* simple function which gets the property with given name
289  * from the component
290  *
291  * @code
292  *
293  * const IInterface* p = ... ;
294  *
295  * const Property* pro = getProperty( p , "Context" ) ;
296  *
297  * @endcode
298  *
299  * @param p pointer to IInterface object
300  * @param name property name (case insensitive)
301  * @return property with the given name (if exists), NULL otherwise
302  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
303  * @date 2006-09-09
304  */
305 // ============================================================================
307 ( const IInterface* p , const std::string& name )
308 {
309  // trivial check
310  if ( !p ) { return nullptr ; } // RETURN
311  // remove const-qualifier
312  IInterface* _i = const_cast<IInterface*>( p ) ;
313  if ( !_i ) { return nullptr ; } // RETURN
314  SmartIF<IProperty> property( _i ) ;
315  return property ? getProperty ( property , name ) : nullptr;
316 }
317 // ============================================================================
318 /* check the property by name from the list of the properties
319  *
320  * @code
321  *
322  * IJobOptionsSvc* svc = ... ;
323  *
324  * const std::string client = ... ;
325  *
326  * // get the property:
327  * bool context =
328  * hasProperty ( svc->getProperties( client ) , "Context" )
329  *
330  * @endcode
331  *
332  * @see IJobOptionsSvc
333  *
334  * @param p list of properties
335  * @param name property name (case insensitive)
336  * @return true if the property exists
337  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
338  * @date 2006-09-09
339  */
340 // ============================================================================
342 ( const std::vector<const Property*>* p ,
343  const std::string& name )
344 {
345  // delegate to another method
346  return getProperty ( p , name ) ;
347 }
348 // ============================================================================
349 /* get the property by name from the list of the properties
350  *
351  * @code
352  *
353  * IJobOptionsSvc* svc = ... ;
354  *
355  * const std::string client = ... ;
356  *
357  * // get the property:
358  * const Property* context =
359  * getProperty ( svc->getProperties( client ) , "Context" )
360  *
361  * @endcode
362  *
363  * @see IJobOptionsSvc
364  *
365  * @param p list of properties
366  * @param name property name (case insensitive)
367  * @return property with the given name (if exists), NULL otherwise
368  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
369  * @date 2006-09-09
370  */
371 // ============================================================================
373 ( const std::vector<const Property*>* p ,
374  const std::string& name )
375 {
376  // trivial check
377  if ( !p ) { return nullptr ; } // RETURN
378  auto ifound = std::find_if ( p->begin() , p->end() , is_iByName{ name } ) ;
379  return p->end() != ifound ? *ifound : nullptr ; // RETURN
380 }
381 // ============================================================================
382 /* the full specialization of the
383  * method setProperty( IProperty, std::string, const TYPE&)
384  * for C-strings
385  *
386  * @param component component which needs to be configured
387  * @param name name of the property
388  * @param value value of the property
389  * @param doc the new documentation string
390  *
391  * @see IProperty
392  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
393  * @date 2007-05-13
394  */
395 // ============================================================================
397 ( IProperty* component ,
398  const std::string& name ,
399  const char* value ,
400  const std::string& doc )
401 {
402  return Gaudi::Utils::setProperty ( component , name , std::string{value} , doc ) ;
403 }
404 // ============================================================================
405 /* the full specialization of the
406  * method Gaudi::Utils::setProperty( IProperty, std::string, const TYPE&)
407  * for standard strings
408  *
409  * @param component component which needs to be configured
410  * @param name name of the property
411  * @param value value of the property
412  *
413  * @see IProperty
414  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
415  * @date 2007-05-13
416  */
417 // ============================================================================
419 ( IProperty* component ,
420  const std::string& name ,
421  const std::string& value ,
422  const std::string& doc )
423 {
424  if ( !component ) { return StatusCode::FAILURE ; } // RETURN
425  if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
426  StatusCode sc = component -> setProperty ( name , value ) ;
427  if ( !doc.empty() )
428  {
429  Property* p = getProperty( component , name ) ;
430  if ( p ) { p -> setDocumentation ( doc ) ; }
431  }
432  sc.ignore() ;
433  return sc ;
434 }
435 // ============================================================================
436 /* simple function to set the property of the given object from another
437  * property
438  *
439  * @code
440  *
441  * IProperty* component = ... ;
442  *
443  * const Property* prop = ... ;
444  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
445  *
446  * @endcode
447  *
448  * @param component component which needs to be configured
449  * @param name name of the property
450  * @param property the property
451  * @param doc the new documentation string
452  *
453  * @see IProperty
454  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
455  * @date 2007-05-13
456  */
457 // ============================================================================
459 ( IProperty* component ,
460  const std::string& name ,
461  const Property* property ,
462  const std::string& doc )
463 {
464  if ( !component || !property ) return StatusCode::FAILURE ;
465  Property* p = getProperty ( component , name ) ;
466  if ( !p || !p->assign ( *property ) ) return StatusCode::FAILURE ;
467  if ( !doc.empty() ) { p->setDocumentation( doc ) ; }
468  return StatusCode::SUCCESS ;
469 }
470 // ============================================================================
471 /* simple function to set the property of the given object from another
472  * property
473  *
474  * @code
475  *
476  * IProperty* component = ... ;
477  *
478  * const Property& prop = ... ;
479  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
480  *
481  * @endcode
482  *
483  * @param component component which needs to be configured
484  * @param name name of the property
485  * @param property the property
486  * @param doc the new documentation string
487  *
488  * @see IProperty
489  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
490  * @date 2007-05-13
491  */
492 // ============================================================================
494 ( IProperty* component ,
495  const std::string& name ,
496  const Property& property ,
497  const std::string& doc )
498 { return setProperty ( component , name , &property , doc ) ; }
499 // ============================================================================
500 /* the full specialization of the
501  * method setProperty( IInterface , std::string, const TYPE&)
502  * for standard strings
503  *
504  * @param component component which needs to be configured
505  * @param name name of the property
506  * @param value value of the property
507  * @param doc the new documentation string
508  *
509  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
510  * @date 2007-05-13
511  */
512 // ============================================================================
514 ( IInterface* component ,
515  const std::string& name ,
516  const std::string& value ,
517  const std::string& doc )
518 {
519  if ( !component ) { return StatusCode::FAILURE ; }
520  SmartIF<IProperty> property ( component ) ;
521  return property ? setProperty ( property , name , value , doc )
523 }
524 // ============================================================================
525 /* the full specialization of the
526  * method setProperty( IInterface , std::string, const TYPE&)
527  * for C-strings
528  *
529  * @param component component which needs to be configured
530  * @param name name of the property
531  * @param value value of the property
532  * @param doc the new documentation string
533  *
534  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
535  * @date 2007-05-13
536  */
537 // ============================================================================
539 ( IInterface* component ,
540  const std::string& name ,
541  const char* value ,
542  const std::string& doc )
543 {
544  return setProperty ( component , name , std::string{ value } , doc ) ;
545 }
546 // ============================================================================
547 /* simple function to set the property of the given object from another
548  * property
549  *
550  * @code
551  *
552  * IInterface* component = ... ;
553  *
554  * const Property* prop = ... ;
555  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
556  *
557  * @endcode
558  *
559  * @param component component which needs to be configured
560  * @param name name of the property
561  * @param property the property
562  * @param doc the new documentation string
563  *
564  * @see IProperty
565  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
566  * @date 2007-05-13
567  */
568 // ============================================================================
570 ( IInterface* component ,
571  const std::string& name ,
572  const Property* property ,
573  const std::string& doc )
574 {
575  if ( !component ) { return StatusCode::FAILURE ; }
576  SmartIF<IProperty> prop ( component ) ;
577  if ( !prop ) { return StatusCode::FAILURE ; }
578  return setProperty ( prop , name , property , doc ) ;
579 }
580 // ============================================================================
581 /* simple function to set the property of the given object from another
582  * property
583  *
584  * @code
585  *
586  * IInterface* component = ... ;
587  *
588  * const Property& prop = ... ;
589  * StatusCode sc = setProperty ( component , "Data" , prop ) ;
590  *
591  * @endcode
592  *
593  * @param component component which needs to be configured
594  * @param name name of the property
595  * @param property the property
596  * @param doc the new documentation string
597  *
598  * @see IProperty
599  * @author Vanya BELYAEV ibelyaev@physics.syr.edu
600  * @date 2007-05-13
601  */
602 // ============================================================================
604 ( IInterface* component ,
605  const std::string& name ,
606  const Property& property ,
607  const std::string& doc )
608 { return setProperty ( component , name , &property , doc ) ; }
609 // ============================================================================
610 
611 // ============================================================================
612 // The END
613 // ============================================================================
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:1187
virtual void useReadHandler() const
use the call-back function at reading
Definition: Property.cpp:78
bool setValue(const GaudiHandleArrayBase &value)
Definition: Property.cpp:204
virtual bool assign(const Property &source)=0
import the property value form the source
virtual const std::vector< Property * > & getProperties() const =0
Get list of properties.
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
Definition: GaudiHandle.cpp:9
virtual std::string toString() const =0
value -> string
const std::string & name() const
property name
Definition: Property.h:45
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
StatusCode fromString(const std::string &s) override
string -> value
Definition: Property.cpp:189
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:400
void setDocumentation(std::string documentation)
set the documentation string
Definition: Property.h:94
STL namespace.
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:157
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:259
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
virtual std::ostream & fillStream(std::ostream &) const
the printout of the property value
Definition: Property.cpp:109
void toStream(std::ostream &out) const override
value -> stream
Definition: Property.cpp:215
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:338
GaudiHandleProperty(std::string name, GaudiHandleBase &ref)
Definition: Property.cpp:168
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in .
Definition: GaudiHandle.cpp:63
virtual bool useUpdateHandler()
use the call-back function at update
Definition: Property.cpp:90
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Definition of the basic interface.
Definition: IInterface.h:234
GaudiHandleArrayProperty(std::string name, GaudiHandleArrayBase &ref)
Definition: Property.cpp:198
std::function< void(Property &)> m_readCallBack
Definition: Property.h:120
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:255
virtual void declareReadHandler(std::function< void(Property &)> fun)
set new callback for reading
Definition: Property.cpp:64
std::string toString() const override
value -> string
Definition: Property.cpp:179
GAUDI_API Property * getProperty(const IProperty *p, const std::string &name)
simple function which gets the property with given name from the component
Definition: Property.cpp:276
StatusCode fromString(const std::string &s) override
string -> value
Definition: Property.cpp:221
GaudiHandleArrayBase * m_pValue
Pointer to the real property.
Definition: Property.h:867
Base class of array's of various gaudihandles.
Definition: GaudiHandle.h:304
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
void toStream(std::ostream &out) const override
value -> stream
Definition: Property.cpp:184
void setPropertyName(std::string propName)
set name as used in declareProperty(name,gaudiHandle).
Definition: GaudiHandle.h:44
std::function< void(Property &)> m_updateCallBack
Definition: Property.h:122
double fun(const std::vector< double > &x)
Definition: PFuncTest.cpp:26
string s
Definition: gaudirun.py:246
virtual void declareUpdateHandler(std::function< void(Property &)> fun)
set new callback for update
Definition: Property.cpp:71
std::ostream & operator<<(std::ostream &stream, const Property &prop)
The output operator for friendly printout.
Definition: Property.cpp:32
GaudiHandleBase * m_pValue
Pointer to the real property.
Definition: Property.h:808
const std::vector< std::string > typesAndNames() const
Return a vector with "type/name" strings of all handles in the array.
Definition: GaudiHandle.cpp:78
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
Definition: GaudiHandle.h:81
std::string toString() const override
value -> string
Definition: Property.cpp:209
std::string typeAndName() const
The full type and name: "type/name".
Definition: GaudiHandle.h:108
void ignore() const
Definition: StatusCode.h:108
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:21
bool setValue(const GaudiHandleBase &value)
Definition: Property.cpp:174
string type
Definition: gaudirun.py:151