File indexing completed on 2025-01-18 09:57:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012
0013 #include <Gaudi/PropertyFwd.h>
0014 #include <GaudiKernel/StatusCode.h>
0015 #include <GaudiKernel/System.h>
0016 #include <functional>
0017 #include <iostream>
0018 #include <set>
0019 #include <string>
0020 #include <string_view>
0021 #include <typeinfo>
0022 #include <utility>
0023
0024 namespace Gaudi::Details {
0025 class WeakPropertyRef;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 class GAUDI_API PropertyBase {
0036
0037 public:
0038
0039 const std::string name() const { return std::string{ m_name }; }
0040
0041 std::string documentation() const { return std::string{ m_documentation }; }
0042
0043 std::string semantics() const { return std::string{ m_semantics }; }
0044
0045 const std::type_info* type_info() const { return m_typeinfo; }
0046
0047 std::string type() const { return m_typeinfo->name(); }
0048
0049 virtual bool load( PropertyBase& dest ) const = 0;
0050
0051 virtual bool assign( const PropertyBase& source ) = 0;
0052
0053 public:
0054
0055 virtual std::string toString() const = 0;
0056
0057 virtual void toStream( std::ostream& out ) const = 0;
0058
0059 virtual StatusCode fromString( const std::string& value ) = 0;
0060
0061 public:
0062
0063 virtual PropertyBase& declareReadHandler( std::function<void( PropertyBase& )> fun ) = 0;
0064
0065 virtual PropertyBase& declareUpdateHandler( std::function<void( PropertyBase& )> fun ) = 0;
0066
0067
0068 virtual const std::function<void( PropertyBase& )> readCallBack() const = 0;
0069
0070 virtual const std::function<void( PropertyBase& )> updateCallBack() const = 0;
0071
0072
0073 virtual bool useUpdateHandler() = 0;
0074
0075 template <class HT>
0076 PropertyBase& declareReadHandler( void ( HT::*MF )( PropertyBase& ), HT* instance ) {
0077 return declareReadHandler( [=]( PropertyBase& p ) { ( instance->*MF )( p ); } );
0078 }
0079
0080 template <class HT>
0081 PropertyBase& declareUpdateHandler( void ( HT::*MF )( PropertyBase& ), HT* instance ) {
0082 return declareUpdateHandler( [=]( PropertyBase& p ) { ( instance->*MF )( p ); } );
0083 }
0084
0085 public:
0086
0087 virtual inline ~PropertyBase();
0088
0089 void setName( std::string value ) { m_name = to_view( std::move( value ) ); }
0090
0091 void setDocumentation( std::string value ) { m_documentation = to_view( std::move( value ) ); }
0092
0093 void setSemantics( std::string value ) { m_semantics = to_view( std::move( value ) ); }
0094
0095 virtual std::ostream& fillStream( std::ostream& ) const;
0096
0097 virtual PropertyBase* clone() const = 0;
0098
0099
0100 void setOwnerType( const std::type_info& ownerType ) { m_ownerType = &ownerType; }
0101
0102
0103 template <class OWNER>
0104 void setOwnerType() {
0105 setOwnerType( typeid( OWNER ) );
0106 }
0107
0108
0109 const std::type_info* ownerType() const { return m_ownerType; }
0110
0111
0112 std::string ownerTypeName() const {
0113 return m_ownerType ? System::typeinfoName( *m_ownerType ) : std::string( "unknown owner type" );
0114 }
0115
0116 protected:
0117
0118 PropertyBase( const std::type_info& type, std::string name = "", std::string doc = "", std::string semantics = "" )
0119 : m_name( to_view( std::move( name ) ) )
0120 , m_documentation( to_view( std::move( doc ) ) )
0121 , m_semantics( to_view( std::move( semantics ) ) )
0122 , m_typeinfo( &type ) {}
0123
0124 PropertyBase( std::string name, const std::type_info& type )
0125 : m_name( to_view( std::move( name ) ) ), m_documentation( m_name ), m_typeinfo( &type ) {}
0126
0127 PropertyBase( const PropertyBase& ) = default;
0128
0129 PropertyBase& operator=( const PropertyBase& ) = default;
0130
0131 private:
0132
0133 static std::string_view to_view( std::string str );
0134
0135 std::string_view m_name;
0136
0137 std::string_view m_documentation;
0138
0139 std::string_view m_semantics;
0140
0141 const std::type_info* m_typeinfo;
0142
0143 const std::type_info* m_ownerType = nullptr;
0144
0145 friend WeakPropertyRef;
0146 std::set<WeakPropertyRef*> m_weakReferences;
0147 void add( WeakPropertyRef* ref ) {
0148 if ( ref ) m_weakReferences.insert( ref );
0149 }
0150 void remove( WeakPropertyRef* ref ) { m_weakReferences.erase( ref ); }
0151 };
0152
0153
0154
0155 class GAUDI_API WeakPropertyRef {
0156 friend PropertyBase;
0157
0158 public:
0159 WeakPropertyRef() = default;
0160 WeakPropertyRef( std::string value ) : m_value{ std::move( value ) }, m_unset{ false } {}
0161 WeakPropertyRef( PropertyBase& property ) : m_property{ &property } { property.add( this ); }
0162 WeakPropertyRef( const WeakPropertyRef& other ) = delete;
0163 WeakPropertyRef( WeakPropertyRef&& other )
0164 : m_property{ other.m_property }, m_value{ std::move( other.m_value ) }, m_unset{ other.m_unset } {
0165 if ( m_property ) {
0166 other.m_property = nullptr;
0167 m_property->remove( &other );
0168 m_property->add( this );
0169 }
0170 }
0171 ~WeakPropertyRef() {
0172 if ( m_property ) m_property->remove( this );
0173 }
0174 WeakPropertyRef& operator=( WeakPropertyRef&& other ) {
0175 if ( this != &other ) {
0176 if ( m_property ) m_property->remove( this );
0177 m_property = other.m_property;
0178 other.m_property = nullptr;
0179 if ( m_property ) {
0180 m_property->remove( &other );
0181 m_property->add( this );
0182 }
0183 m_value = std::move( other.m_value );
0184 m_unset = other.m_unset;
0185 }
0186 return *this;
0187 }
0188 WeakPropertyRef& operator=( PropertyBase& value ) {
0189 if ( m_property != &value ) {
0190 if ( m_property ) {
0191 m_property->remove( this );
0192 if ( !m_unset ) m_value = m_property->toString();
0193 }
0194 if ( !m_unset ) value.fromString( m_value ).ignore();
0195 m_property = &value;
0196 value.add( this );
0197 }
0198 return *this;
0199 }
0200 WeakPropertyRef& operator=( const std::string& value ) {
0201 if ( m_property ) m_property->fromString( value ).ignore();
0202 m_value = value;
0203 m_unset = false;
0204 return *this;
0205 }
0206 operator std::string() const;
0207
0208 inline bool isBound() const { return m_property; }
0209 inline bool isSet() const { return !m_unset; }
0210
0211 private:
0212 PropertyBase* m_property = nullptr;
0213 std::string m_value;
0214 bool m_unset = true;
0215
0216 void detach() { m_property = nullptr; }
0217 };
0218
0219 inline PropertyBase::~PropertyBase() {
0220 for ( auto ref : m_weakReferences ) { ref->detach(); }
0221 }
0222
0223 inline std::ostream& operator<<( std::ostream& stream, const PropertyBase& prop ) {
0224 return prop.fillStream( stream );
0225 }
0226 }