Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Property.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#if !qStroika_Foundation_Common_Property_EmbedThisInProperties
6#endif
8
10
11 /*
12 ********************************************************************************
13 ****************************** ReadOnlyProperty<T> *****************************
14 ********************************************************************************
15 */
16 template <typename T>
17 template <qCompilerAndStdLib_RequiresNotMatchXXXDefined_1_BWA (invocable<const ReadOnlyProperty<T>*>) G>
18 constexpr ReadOnlyProperty<T>::ReadOnlyProperty (G getter)
19 qCompilerAndStdLib_RequiresNotMatchXXXDefined_2_BWA (requires (convertible_to<invoke_result_t<G, const ReadOnlyProperty<T>*>, T>))
20 : fGetter_ (getter) // no uniform initialization because this may involve conversions
21 {
22 }
23 template <typename T>
24 inline T ReadOnlyProperty<T>::Get () const
25 requires (not IPropertyMutatable<T>)
26 {
27 return fGetter_ (this);
28 }
29 template <typename T>
30 inline T ReadOnlyProperty<T>::Get ()
31 requires (IPropertyMutatable<T>)
32 {
33 return fGetter_ (this);
34 }
35 template <typename T>
36 inline ReadOnlyProperty<T>::operator const T () const
37 requires (not IPropertyMutatable<T>)
38 {
39 return Get ();
40 }
41 template <typename T>
43 requires (IPropertyMutatable<T>)
44 {
45 return Get ();
46 }
47 template <typename T>
48 inline const T ReadOnlyProperty<T>::operator() () const
49 requires (not IPropertyMutatable<T>)
50 {
51 return Get ();
52 }
53 template <typename T>
55 requires (IPropertyMutatable<T>)
56 {
57 return Get ();
58 }
59
60 /*
61 ********************************************************************************
62 ****************************** WriteOnlyProperty<T> ****************************
63 ********************************************************************************
64 */
65 template <typename T>
66 template <qCompilerAndStdLib_RequiresNotMatchXXXDefined_1_BWA (invocable<WriteOnlyProperty<T>*, T>) S>
68 : fSetter_ (setter) // no uniform initialization because this may involve conversions
69 {
70 }
71 template <typename T>
73 {
74 fSetter_ (this, value);
75 }
76 template <typename T>
78 {
79 Set (value);
80 }
81 template <typename T>
83 {
84 Set (value);
85 return *this;
86 }
87
88 /*
89 ********************************************************************************
90 ******************************** Property<T> ***********************************
91 ********************************************************************************
92 */
93 template <typename T>
94 template <invocable<const ReadOnlyProperty<T>*> G, invocable<WriteOnlyProperty<remove_cvref_t<T>>*, remove_cvref_t<T>> S>
95 inline Property<T>::Property (G getter, S setter)
96 requires (convertible_to<invoke_result_t<G, const ReadOnlyProperty<T>*>, T>)
97 : ReadOnlyProperty<T>{getter}
98 , WriteOnlyProperty<decayed_value_type>{setter}
99 {
100 }
101 template <typename T>
102 inline auto Property<T>::operator= (ArgByValueType<decayed_value_type> value) -> Property&
103 {
105 return *this;
106 }
107 template <typename T>
108 inline auto Property<T>::operator= (const Property& value) -> Property&
109 {
110 Set (value.Get ());
111 return *this;
112 }
113 template <typename T>
114 template <typename TT>
115 inline bool Property<T>::operator== (const TT& rhs) const
116 {
117 return Get () == static_cast<T> (rhs);
118 }
119
120 /*
121 ********************************************************************************
122 ************************** ExtendableProperty<T> *******************************
123 ********************************************************************************
124 */
125 template <typename T>
126 template <qCompilerAndStdLib_RequiresNotMatchXXXDefined_1_BWA (invocable<const ExtendableProperty<T>*>) G,
127 qCompilerAndStdLib_RequiresNotMatchXXXDefined_1_BWA (invocable<ExtendableProperty<T>*, remove_cvref_t<T>>) S>
128 ExtendableProperty<T>::ExtendableProperty (G getter, S setter)
129 qCompilerAndStdLib_RequiresNotMatchXXXDefined_2_BWA (requires (convertible_to<invoke_result_t<G, const ExtendableProperty<T>*>, T>))
130 : Property<T>{[getter] ([[maybe_unused]] const auto* property) -> typename Property<T>::base_value_type {
131 // Subtle - but the 'property' here refers to 'this' (ExtendableProperty). The getter itself will want to extract the parent object, but
132 // unlike other getter/setters, here the auto property is already for this object.
133 const ExtendableProperty* thisObj = static_cast<const ExtendableProperty*> (property); // cannot use dynamic_cast without adding needless vtable to Property objects; static_cast needed (over reintepret_cast) to adjust sub-object pointer for multiple inheritance
134 AssertNotNull (thisObj);
135 if constexpr (is_reference_v<base_value_type>) { // see docs on PropertyReadEventHandlerArgAndReturnValue_
136 PropertyReadEventHandlerArgAndReturnValue_ value = &getter (property);
137 for (const auto& handler : thisObj->fPropertyReadHandlers_) {
138 value = handler (value);
139 }
140 return *value;
141 }
142 else {
143 base_value_type value = getter (property);
144 for (const auto& handler : thisObj->fPropertyReadHandlers_) {
145 value = handler (value);
146 }
147 return value;
148 }
149 },
150 [getter, setter] (auto* property, const auto& newValue) {
151 // Subtle - but the 'property' here refers to 'this' (ExtendableProperty). The getter itself will want to extract the parent object, but
152 // unlike other getter/setters, here the auto property is already for this object.
153 ExtendableProperty* thisObj = static_cast<ExtendableProperty*> (property); // cannot use dynamic_cast without adding needless vtable to Property objects; static_cast needed (over reintepret_cast) to adjust sub-object pointer for multiple inheritance
154 AssertNotNull (thisObj);
155 if (not thisObj->fPropertyChangedHandlers_.empty ()) {
156 T prevValue = getter (property);
157 for (const auto& handler : thisObj->fPropertyChangedHandlers_) {
158 if (handler (PropertyChangedEvent{prevValue, newValue}) ==
159 PropertyCommon::PropertyChangedEventResultType::eSilentlyCutOffProcessing) {
160 return;
161 }
162 }
163 }
164 setter (property, newValue);
165 }}
166 , propertyReadHandlers{[qStroika_Foundation_Common_Property_ExtraCaptureStuff] (
167 [[maybe_unused]] const auto* property) -> const std::forward_list<PropertyReadEventHandler>& {
168 const ExtendableProperty* thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &ExtendableProperty::propertyReadHandlers);
169 return thisObj->fPropertyReadHandlers_;
170 }}
171 , rwPropertyReadHandlers{
172 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] const auto* property) -> std::forward_list<PropertyReadEventHandler>& {
173 ExtendableProperty* thisObj = const_cast<ExtendableProperty*> (
174 qStroika_Foundation_Common_Property_OuterObjPtr (property, &ExtendableProperty::rwPropertyReadHandlers));
175 return thisObj->fPropertyReadHandlers_;
176 },
177 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] auto* property, const auto& handlerList) {
178 ExtendableProperty* thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &ExtendableProperty::rwPropertyReadHandlers);
179 thisObj->fPropertyReadHandlers_ = handlerList;
180 }}
181 , propertyChangedHandlers{[qStroika_Foundation_Common_Property_ExtraCaptureStuff] (
182 [[maybe_unused]] const auto* property) -> const std::forward_list<PropertyChangedEventHandler>& {
183 const ExtendableProperty* thisObj = qStroika_Foundation_Common_Property_OuterObjPtr (property, &ExtendableProperty::propertyChangedHandlers);
184 return thisObj->fPropertyChangedHandlers_;
185 }}
186 , rwPropertyChangedHandlers{
187 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] const auto* property) -> std::forward_list<PropertyChangedEventHandler>& {
188 ExtendableProperty* thisObj = const_cast<ExtendableProperty*> (
189 qStroika_Foundation_Common_Property_OuterObjPtr (property, &ExtendableProperty::rwPropertyChangedHandlers));
190 return thisObj->fPropertyChangedHandlers_;
191 },
192 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] auto* property, const auto& handlerList) {
193 ExtendableProperty* thisObj =
194 qStroika_Foundation_Common_Property_OuterObjPtr (property, &ExtendableProperty::rwPropertyChangedHandlers);
195 thisObj->fPropertyChangedHandlers_ = handlerList;
196 }}
197 {
198 }
199 template <typename T>
200 inline auto ExtendableProperty<T>::operator= (ArgByValueType<T> value) -> ExtendableProperty&
201 {
202 Property<T>::operator= (value);
203 return *this;
204 }
205 template <typename T>
206 inline auto ExtendableProperty<T>::operator= (const ExtendableProperty& value) -> ExtendableProperty&
207 {
208 Property<T>::operator= (value);
209 return *this;
210 }
211
212}
#define AssertNotNull(p)
Definition Assertions.h:333
ExtendableProperty is a Property which has callbacks associated with it, to be notified when it is ac...
Definition Property.h:491
ReadOnlyProperty< const std::forward_list< PropertyReadEventHandler > & > propertyReadHandlers
Definition Property.h:564
ReadOnlyProperty< const std::forward_list< PropertyChangedEventHandler > & > propertyChangedHandlers
Definition Property.h:571
T base_value_type
base_value_type is T the type declared, and decayed_value_type is similar, but with the references et...
Definition Property.h:411
nonvirtual const T operator()() const
Definition Property.inl:48
nonvirtual void operator()(ArgByValueType< T > value)
Definition Property.inl:77
nonvirtual void Set(ArgByValueType< T > value)
Definition Property.inl:72
nonvirtual WriteOnlyProperty & operator=(ArgByValueType< T > value)
Definition Property.inl:82
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
Definition TypeHints.h:32