ADTF
properties_v2.h
Go to the documentation of this file.
1 
7 #pragma once
8 
9 #include "property_intf.h"
11 
12 #include <adtfucom3/adtf_ucom3.h>
13 
14 #include <variant>
15 #include <string>
16 #include <string_view>
17 #include <cstring>
18 
19 namespace adtf
20 {
21 namespace base
22 {
23 namespace spider
24 {
26 {
27 public:
28  struct tUserDefined
29  {
30  std::string strType;
31  std::string strValue;
32  };
33 
34  template <typename T>
35  cPropertyValue(const T& xValue)
36  {
37  if constexpr(std::is_base_of_v<ant::IPropertyValue, T>)
38  {
39  auto oResult = AssignRaw(xValue);
40 
41  if (oResult == ERR_EMPTY)
42  {
43  oResult = AssignString(xValue);
44  }
45 
46  THROW_IF_FAILED(oResult);
47  }
48  else
49  {
50  m_xValue = xValue;
51  }
52  }
53 
54  cPropertyValue(const char* strValue)
55  {
56  m_xValue = std::string(strValue);
57  }
58 
59  cPropertyValue(std::string_view strValue)
60  {
61  m_xValue = std::string(strValue);
62  }
63 
64  cPropertyValue(cPropertyValue&&) = default;
65  cPropertyValue(const cPropertyValue&) = default;
66  cPropertyValue& operator=(cPropertyValue&&) = default;
67  cPropertyValue& operator=(const cPropertyValue&) = default;
68 
69  tResult GetType(IString&& strType) const override;
70  tResult Set(const IPropertyValue& oValue) override;
71 
72  template <typename T>
73  tResult Set(const T& xValue)
74  {
75  if constexpr(std::is_base_of_v<ant::IPropertyValue, T>)
76  {
77  return this->Set(static_cast<const IPropertyValue&>(xValue));
78  }
79  else
80  {
81  m_xValue = xValue;
83  }
84  }
85 
86  tResult FromString(const IString& strValueAsString) override;
87  tResult ToString(IString&& strIToString) const override;
88  tResult FromRaw(const IRawMemory& oRawValue) override;
89  tResult ToRaw(IRawMemory&& oRawValue) const override;
90 
91  template <typename T>
92  T& Get()
93  {
94  return std::get<T>(m_xValue);
95  }
96 
97  template <typename T>
98  const T& Get() const
99  {
100  return std::get<T>(m_xValue);
101  }
102 
103 private:
104  tResult AssignRaw(const IPropertyValue& oValue);
105  tResult AssignString(const IPropertyValue& oValue);
106 
107  std::variant<bool, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, float, double, std::string, tUserDefined> m_xValue; //@todo std::unique_ptr for tUserDefined
108 };
109 
110 namespace detail
111 {
112 template <typename T>
113 using is_user_defined_property_value = std::integral_constant<bool, !(std::is_same_v<T, bool> || std::is_arithmetic_v<T> || std::is_same_v<T, std::string>)>;
114 
115 template <typename T>
116 typename std::enable_if<is_user_defined_property_value<T>::value, tResult>::type get_property_value(const cPropertyValue& oValue, T& xValue)
117 {
118  const auto& strValue = oValue.Get<cPropertyValue::tUserDefined>().strValue;
119  RETURN_IF_FAILED(ant::property_type_definition<T>::con_type::FromString(adtf::util::cString(strValue.c_str()), xValue));
121 }
122 
123 template <typename T>
124 typename std::enable_if<!is_user_defined_property_value<T>::value, tResult>::type get_property_value(const cPropertyValue& oValue, T& xValue)
125 {
126  xValue = oValue.Get<T>();
128 }
129 template <typename T>
130 using storage_type = typename std::conditional<is_user_defined_property_value<T>::value, cPropertyValue::tUserDefined, T>::type;
131 
132 }
133 
134 template <typename T>
135 tResult get_property_value(const IPropertyValue& oValue, T& xValue)
136 {
137  cPropertyValue oHelper(detail::storage_type<T>{});
138  RETURN_IF_FAILED(oHelper.Set(oValue));
139  RETURN_IF_FAILED(detail::get_property_value(oHelper, xValue));
141 }
142 
143 template <typename T>
144 T get_property_value(const IPropertyValue& oValue)
145 {
146  T xValue;
147  THROW_IF_FAILED(get_property_value<T>(oValue, xValue));
148  return xValue;
149 }
150 
151 class cProperties;
152 
154 {
155 
156 public:
157  cProperty():
158  m_oValue(false)
159  {
160  }
161 
162  cProperty(const cProperty&) = default;
163  cProperty(cProperty&&) = default;
164  cProperty& operator=(const cProperty&) = default;
165  cProperty& operator=(cProperty&&) = default;
166 
167  cProperty(const ant::IProperty& oProp);
168 
169  template <typename T>
170  cProperty(std::string_view strName, const T& xValue):
171  m_oValue(xValue),
172  m_strName(strName)
173  {
174  }
175 
176  template <typename T>
177  cProperty(const char* strName, const T& xValue): cProperty(std::string_view(strName), xValue)
178  {
179  }
180 
181  template <typename T>
182  cProperty(const T& xValue):
183  m_oValue(xValue)
184  {
185  }
186 
187  const IPropertyValue* GetValue() const override;
188  IPropertyValue* GetValue() override;
189  tResult SetValue(const IPropertyValue& oValue) override;
190 
191  template <typename T>
192  tResult SetValue(const T& xValue)
193  {
194  if constexpr(std::is_base_of_v<ant::IPropertyValue, T>)
195  {
196  return this->SetValue(static_cast<const IPropertyValue&>(xValue));
197  }
198  else
199  {
200  m_oValue.Set(xValue);
201  NotifyObservers();
203  }
204  }
205 
206  tResult GetName(IString&& strName) const override;
207  tResult SetName(const IString& strName) override;
208  tResult Set(const IProperty& oProp) override;
209  bool HasProperties() const override;
210  bool HasAttachedProperties() const override;
211  tResult SetProperties(const IProperties& pProperties) override;
212  tResult AttachProperties(const ucom::ant::iobject_ptr<IProperties>& pProperties) override;
213  tResult GetAttachedProperties(IProperty& pProperty) const override;
214  tResult DetachProperties() override;
218  void RegisterObserver(IPropertyObserver& oObserver);
219  void UnregisterObserver(IPropertyObserver& oObserver);
220 
221 private:
222  tResult SetName(const IProperty& oProp);
223  tResult SetProperties(const IProperty& oProp);
224  void NotifyObservers();
225  void CreateProperties() const;
226 
227  cPropertyValue m_oValue;
228  std::string m_strName;
229  mutable ucom::ant::object_ptr<ant::IProperties> m_pChildProperties;
230  std::vector<IPropertyObserver*> m_oObservers;
231  bool m_bAttached = false;
232 };
233 
234 template <typename T, typename Enable = void>
235 class property: public cProperty, private IPropertyObserver
236 {
237  public:
239  {
240  RegisterObserver(*this);
241  }
242 
243  property(const T& oValue): cProperty(cPropertyValue::tUserDefined{})
244  {
245  InitValue(oValue);
246  }
247 
248  property(std::string_view strName, const T& oValue): cProperty(strName, cPropertyValue::tUserDefined{ant::property_type_definition<T>::TYPE_NAME})
249  {
250  InitValue(oValue);
251  }
252 
253  property(const char* strName, const T& oValue): property(std::string_view(strName), oValue)
254  {
255  }
256 
257  const T& GetValueT() const
258  {
259  return m_xValue;
260  }
261 
262  bool operator==(const T& xOther) const
263  {
264  return GetValueT() == xOther;
265  }
266 
267  property& operator=(const T& xValue)
268  {
269  ConvertAndSetValue(xValue);
270  return *this;
271  }
272 
273  private:
274  void InitValue(const T& oValue)
275  {
276  ConvertAndSetValue(oValue);
277  RegisterObserver(*this);
278  }
279 
280  void ConvertAndSetValue(const T& oValue)
281  {
282  adtf::util::cString strHelper;
284  cProperty::SetValue(cPropertyValue::tUserDefined{ant::property_type_definition<T>::TYPE_NAME, strHelper.GetPtr()});
285  }
286 
287  void Notify(const IProperty& /* oProperty*/)
288  {
289  THROW_IF_FAILED(detail::get_property_value(*static_cast<cPropertyValue*>(GetValue()), m_xValue));
290  }
291 
292  T m_xValue;
293 };
294 
295 template <typename T>
296 class property<T, typename std::enable_if<!detail::is_user_defined_property_value<T>::value>::type>: public cProperty
297 {
298  public:
299  property(): cProperty(T{})
300  {
301  }
302 
303  using cProperty::cProperty;
304 
305  const T& GetValueT() const
306  {
307  return static_cast<const cPropertyValue*>(GetValue())->Get<T>();
308  }
309 
310  bool operator==(const T& xOther) const
311  {
312  return GetValueT() == xOther;
313  }
314 
315  property& operator=(const T& xValue)
316  {
317  SetValue(xValue);
318  return *this;
319  }
320 };
321 
322 class cProperties: public ucom::catwo::object<ant::IProperties>
323 {
324  public:
325  cProperties() = default;
326  cProperties(const ant::IProperties& oProperties);
327  bool Exists(const char* strName) const override;
328  tResult Get(IProperties& pProperties) const override;
329  tResult Set(const IProperties& pProperties) override;
330  size_t GetSize() const override;
331  tResult GetProperty(const char* strName, IProperty& pProperty) const override;
332  tResult SetProperty(const IProperty& oProperty) override;
333 
334  template<typename T>
335  cProperties& CreateProperty(std::string_view strName, const T& xValue)
336  {
337  const auto emplaced = m_oProperties.emplace(std::piecewise_construct,
338  std::forward_as_tuple(strName),
339  std::forward_as_tuple(strName, xValue));
340  if (!emplaced.second)
341  {
342  emplaced.first->second.SetValue(xValue);
343  }
344 
345  return static_cast<cProperties&>(emplaced.first->second.GetProperties());
346  }
347 
348  tResult SetPropertyByPath(const char* strParentPath, const IProperty& pProperty) override;
349  tResult RemoveProperty(const char* strName) override;
350  tResult RegisterPropertyObserver(const char* strPropertyName,
351  IPropertyObserver& oObserver) override;
352  tResult UnregisterPropertyObserver(IPropertyObserver& oObserver) override;
353 
354  private:
355  std::map<std::string, cProperty, std::less<>> m_oProperties;
356 };
357 
358 }
359 
360 using spider::cProperties;
361 using spider::cProperty;
363 using spider::property;
364 using spider::get_property_value;
365 
366 }
367 }
Copyright © Audi Electronics Venture GmbH.
#define RETURN_IF_FAILED(s)
Return if expression is failed, which requires the calling function's return type to be tResult.
#define RETURN_NOERROR
Return status ERR_NOERROR, which requires the calling function's return type to be tResult.
Defintion of a property set container interface.
The IProperty interface provides methods for getting and setting property values, name of the propert...
Observer Interface to react on property changes.
The IPropertyValue interface provides methods for getting and setting property values.
Definition: property_intf.h:60
The IRawMemory interface provides methods for getting and setting memory values through abstract inte...
The IString interface provides methods for getting and setting strings through abstract interfaces.
Definition: string_intf.h:28
tResult GetProperties(ucom::ant::iobject_ptr< const IProperties > &pProperties) const override
get subproperties for readonly access
tResult GetProperties(ucom::ant::iobject_ptr< IProperties > &pProperties) override
get subproperties for writing access
tResult SetProperties(const IProperties &pProperties) override
will copy given properties
tResult FromRaw(const IRawMemory &oRawValue) override
Implement to create a fast value copy in memory.
tResult ToRaw(IRawMemory &&oRawValue) const override
Implement to create a fast value copy in memory.
tResult FromString(const IString &strValueAsString) override
Implement to deserialize the value from a textfile and/or to set by string.
tResult ToString(IString &&strIToString) const override
Implement to serialize the value to a textfile and/or to show it on a display.
tResult Set(const IPropertyValue &oValue) override
Sets the value by a deep copy.
tResult GetType(IString &&strType) const override
Retrieves the string for the property value type.
void Notify(const IProperty &)
Implements the observer pattern.
Base object pointer to realize binary compatible reference counting in interface methods.
Object pointer implementation used for reference counting on objects of type IObject.
Definition: object_ptr.h:163
Use this template if you want to implement an ucom::ant::IObject based Interface and/or subclass an e...
Definition: object.h:379
string_base< cStackString > cString
cString implementation for a stack string which works on stack if string is lower than A_UTILS_DEFAUL...
Definition: string.h:2784
Namespace for entire ADTF SDK.
Copyright © Audi Electronics Venture GmbH.
Copyright © Audi Electronics Venture GmbH.
Concept template to define the Name and the conversion type for the given type TYPE.
#define THROW_IF_FAILED(s)
throws if the expression returns a failed tResult