The Gaudi Framework  v41r0 (bdbe7744)
Loading...
Searching...
No Matches
Property.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 "COPYING". *
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#pragma once
12
16#include <Gaudi/PropertyFwd.h>
19#include <string>
20#include <utility>
21
24
25 // ==========================================================================
26 // The following code is going to be a bit unpleasant, but as far as its
27 // author can tell, it is as simple as the design constraints and C++'s
28 // implementation constraints will allow. If you disagree, please submit
29 // a patch which simplifies it. Here is the underlying design rationale:
30 //
31 // - For any given type T used in a Property, we want to have an
32 // associated StringConverter<T> struct which explains how to convert a
33 // value of that type into a string (toString) and parse that string
34 // back (fromString).
35 // - There is a default implementation, called DefaultStringConverter<T>,
36 // which is based on the overloadable parse() and toStream() global
37 // methods of Gaudi. Its exact behaviour varies depending on whether T
38 // is default-constructible or only copy-constructible, which requires a
39 // layer of SFINAE indirection.
40 // - Some people want to be able to specialize StringConverter as an
41 // alternative to defining parse/toStream overloads. This interferes
42 // with the SFINAE tricks used by DefaultStringConverter, so we cannot
43 // just call a DefaultStringConverter a StringConverter and must add one
44 // more layer to the StringConverter type hierarchy.
45
46 // This class factors out commonalities between DefaultStringConverters
47 template <class TYPE>
49 public:
50 virtual ~DefaultStringConverterImpl() = default;
51 std::string toString( const TYPE& v ) {
53 return toString( v );
54 }
55
56 // Implementation of fromString depends on whether TYPE is default-
57 // constructible (fastest, easiest) or only copy-constructible (still
58 // doable as long as the caller can provide a valid value of TYPE)
59 virtual TYPE fromString( const TYPE& ref_value, const std::string& s ) = 0;
60
61 protected:
62 void fromStringImpl( TYPE& buffer, const std::string& s ) {
64 if ( !parse( buffer, InputData{ s } ).isSuccess() ) {
65 throw std::invalid_argument( "cannot parse '" + s + "' to " + System::typeinfoName( typeid( TYPE ) ) );
66 }
67 }
68 };
69
70 // Specialization of toString for strings (identity function)
71 template <>
72 inline std::string DefaultStringConverterImpl<std::string>::toString( const std::string& v ) {
73 return v;
74 }
75
76 // This class provides a default implementation of StringConverter based
77 // on the overloadable parse() and toStream() global Gaudi methods.
78 //
79 // It leverages the fact that TYPE is default-constructible if it can, and
80 // falls back fo a requirement of copy-constructibility if it must. So
81 // here is the "default" implementation for copy-constructible types...
82 //
83 template <typename TYPE>
85 TYPE fromString( const TYPE& ref_value, const std::string& s ) final override {
86 TYPE buffer = ref_value;
87 this->fromStringImpl( buffer, s );
88 return buffer;
89 }
90 };
91 // ...and here is the preferred impl for default-constructible types:
92 template <class TYPE>
93 requires( std::is_default_constructible_v<TYPE> )
95 TYPE fromString( const TYPE& /* ref_value */, const std::string& s ) final override {
96 TYPE buffer{};
97 this->fromStringImpl( buffer, s );
98 return buffer;
99 }
100 };
101
102 // Specializable StringConverter struct with a default implementation
103 template <typename TYPE>
105
107 template <class TYPE>
108 void operator()( const TYPE& ) const {}
109 };
110 template <class TYPE>
112 void operator()( const TYPE& value ) const {
114 // throw the exception if the limit is defined and value is outside
115 if ( ( m_hasLowerBound && ( value < m_lowerBound ) ) || ( m_hasUpperBound && ( m_upperBound < value ) ) )
116 throw std::out_of_range( "value " + toString( value ) + " outside range" );
117 }
118
120 bool hasLower() const { return m_hasLowerBound; }
122 bool hasUpper() const { return m_hasUpperBound; }
124 const TYPE& lower() const { return m_lowerBound; }
126 const TYPE& upper() const { return m_upperBound; }
127
129 void setLower( const TYPE& value ) {
130 m_hasLowerBound = true;
131 m_lowerBound = value;
132 }
133
134 void setUpper( const TYPE& value ) {
135 m_hasUpperBound = true;
136 m_upperBound = value;
137 }
138
139 void clearLower() {
140 m_hasLowerBound = false;
141 m_lowerBound = TYPE();
142 }
143
144 void clearUpper() {
145 m_hasUpperBound = false;
146 m_upperBound = TYPE();
147 }
148
150 void setBounds( const TYPE& lower, const TYPE& upper ) {
151 setLower( lower );
152 setUpper( upper );
153 }
154
156 void clearBounds() {
157 clearLower();
158 clearUpper();
159 }
160
161 private:
163 bool m_hasLowerBound{ false };
164 bool m_hasUpperBound{ false };
167 };
168
170 struct SwapCall {
171 using callback_t = std::function<void( PropertyBase& )>;
173 SwapCall( callback_t& input ) : orig( input ) { tmp.swap( orig ); }
174 ~SwapCall() { orig.swap( tmp ); }
175 void operator()( PropertyBase& p ) const { tmp( p ); }
176 };
177
178 struct NoHandler {
179 void useReadHandler( const PropertyBase& ) const {}
180 void setReadHandler( std::function<void( PropertyBase& )> ) {
181 throw std::logic_error( "setReadHandler not implemented for this class" );
182 }
183 std::function<void( PropertyBase& )> getReadHandler() const { return nullptr; }
184 void useUpdateHandler( const PropertyBase& ) const {}
185 void setUpdateHandler( std::function<void( PropertyBase& )> ) {
186 throw std::logic_error( "setUpdateHandler not implemented for this class" );
187 }
188 std::function<void( PropertyBase& )> getUpdateHandler() const { return nullptr; }
189 };
191 mutable std::function<void( PropertyBase& )> m_readCallBack;
192 void useReadHandler( const PropertyBase& p ) const {
193 if ( m_readCallBack ) { SwapCall{ m_readCallBack }( const_cast<PropertyBase&>( p ) ); }
194 }
195 void setReadHandler( std::function<void( PropertyBase& )> fun ) { m_readCallBack = std::move( fun ); }
196 std::function<void( PropertyBase& )> getReadHandler() const { return m_readCallBack; }
197 };
199 std::function<void( PropertyBase& )> m_updateCallBack;
201 if ( m_updateCallBack ) {
202 try {
204 } catch ( const std::exception& x ) {
205 throw std::invalid_argument( "failure in update handler of '" + p.name() + "': " + x.what() );
206 }
207 }
208 }
209 void setUpdateHandler( std::function<void( PropertyBase& )> fun ) { m_updateCallBack = std::move( fun ); }
210 std::function<void( PropertyBase& )> getUpdateHandler() const { return m_updateCallBack; }
211 };
220
221 enum class ParsingErrorPolicy { Ignore, Warning, Exception, Abort };
224} // namespace Gaudi::Details::Property
The declaration of major parsing functions used e.g for (re)implementation of new extended properties...
StatusCode parse(DataObjID &dest, std::string_view src)
Definition DataObjID.cpp:58
implementation of various functions for streaming.
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
const std::string name() const
property name
bool isSuccess() const
Definition StatusCode.h:302
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
Definition Property.h:23
ParsingErrorPolicy setParsingErrorPolicy(ParsingErrorPolicy p)
Definition Property.cpp:477
ParsingErrorPolicy parsingErrorPolicy()
Definition Property.cpp:476
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition ToStream.h:329
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:254
const TYPE & lower() const
Return the lower bound value.
Definition Property.h:124
bool hasUpper() const
Return if it has a lower bound.
Definition Property.h:122
bool hasLower() const
Return if it has a lower bound.
Definition Property.h:120
void setUpper(const TYPE &value)
Set upper bound value.
Definition Property.h:134
void setLower(const TYPE &value)
Set lower bound value.
Definition Property.h:129
void setBounds(const TYPE &lower, const TYPE &upper)
Set both bounds (lower and upper) at the same time.
Definition Property.h:150
const TYPE & upper() const
Return the upper bound value.
Definition Property.h:126
void operator()(const TYPE &value) const
Definition Property.h:112
void clearLower()
Clear lower bound value.
Definition Property.h:139
void clearBounds()
Clear both bounds (lower and upper) at the same time.
Definition Property.h:156
void clearUpper()
Clear upper bound value.
Definition Property.h:144
TYPE fromString(const TYPE &, const std::string &s) final override
Definition Property.h:95
TYPE fromString(const TYPE &ref_value, const std::string &s) final override
Definition Property.h:85
virtual TYPE fromString(const TYPE &ref_value, const std::string &s)=0
void fromStringImpl(TYPE &buffer, const std::string &s)
Definition Property.h:62
void useUpdateHandler(const PropertyBase &) const
Definition Property.h:184
std::function< void(PropertyBase &)> getReadHandler() const
Definition Property.h:183
void setUpdateHandler(std::function< void(PropertyBase &)>)
Definition Property.h:185
void setReadHandler(std::function< void(PropertyBase &)>)
Definition Property.h:180
std::function< void(PropertyBase &)> getUpdateHandler() const
Definition Property.h:188
void useReadHandler(const PropertyBase &) const
Definition Property.h:179
void operator()(const TYPE &) const
Definition Property.h:108
std::function< void(PropertyBase &)> getReadHandler() const
Definition Property.h:196
void useReadHandler(const PropertyBase &p) const
Definition Property.h:192
std::function< void(PropertyBase &)> m_readCallBack
Definition Property.h:191
void setReadHandler(std::function< void(PropertyBase &)> fun)
Definition Property.h:195
helper to disable a while triggering it, to avoid infinite recursion
Definition Property.h:170
std::function< void(PropertyBase &)> callback_t
Definition Property.h:171
void operator()(PropertyBase &p) const
Definition Property.h:175
void setUpdateHandler(std::function< void(PropertyBase &)> fun)
Definition Property.h:209
void useUpdateHandler(PropertyBase &p)
Definition Property.h:200
std::function< void(PropertyBase &)> getUpdateHandler() const
Definition Property.h:210
std::function< void(PropertyBase &)> m_updateCallBack
Definition Property.h:199
Helper class to enable ADL for parsers.
Definition InputData.h:18