1 #ifndef ZSERIO_REFLECTABLE_UTIL_H_INC
2 #define ZSERIO_REFLECTABLE_UTIL_H_INC
24 struct gets_value_by_value
25 : std::integral_constant<bool,
26 std::is_arithmetic_v<T> || std::is_same_v<std::string_view, T> || std::is_enum_v<T> ||
27 is_bitmask_v<T> || is_numeric_wrapper_v<T>>
48 template <
typename ALLOC = std::allocator<u
int8_t>>
63 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
64 typename std::enable_if<detail::gets_value_by_value<T>::value,
int>::type = 0>
67 return reflectable->getAnyValue(allocator).template get<T>();
83 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
84 typename std::enable_if<!detail::gets_value_by_value<T>::value,
int>::type = 0>
88 return reflectable->getAnyValue(allocator).template get<std::reference_wrapper<const T>>().
get();
104 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
105 typename std::enable_if<!detail::gets_value_by_value<T>::value &&
106 !std::is_same<BasicBitBuffer<ALLOC>, T>::value,
110 return reflectable->getAnyValue(allocator).template get<std::reference_wrapper<T>>().
get();
124 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
125 typename std::enable_if<std::is_same<BasicBitBuffer<ALLOC>, T>::value,
int>::type = 0>
129 return reflectable->getAnyValue(allocator).template get<std::reference_wrapper<const T>>().
get();
141 template <
typename T,
typename ALLOC>
145 template <
typename ALLOC>
149 template <
typename ALLOC>
153 template <
typename ALLOC>
157 static bool doubleValuesAlmostEqual(
double lhs,
double rhs);
160 template <
typename ALLOC>
164 if (lhs ==
nullptr || rhs ==
nullptr)
169 const auto& lhsTypeInfo = lhs->getTypeInfo();
170 const auto& rhsTypeInfo = rhs->getTypeInfo();
172 if (lhsTypeInfo.getSchemaType() != rhsTypeInfo.getSchemaType() ||
173 lhsTypeInfo.getSchemaName() != rhsTypeInfo.getSchemaName())
178 if (lhs->isArray() || rhs->isArray())
180 if (!lhs->isArray() || !rhs->isArray())
184 return arraysEqual<ALLOC>(lhs, rhs);
188 return compoundsEqual<ALLOC>(lhs, rhs);
192 return valuesEqual<ALLOC>(lhs, rhs);
196 template <
typename ALLOC>
200 if (lhsArray->size() != rhsArray->size())
205 for (
size_t i = 0; i < lhsArray->size(); ++i)
207 if (!equal<ALLOC>(lhsArray->at(i), rhsArray->at(i)))
216 template <
typename ALLOC>
217 bool ReflectableUtil::compoundsEqual(
const IBasicReflectableDataConstPtr<ALLOC>& lhsCompound,
218 const IBasicReflectableDataConstPtr<ALLOC>& rhsCompound)
222 if (lhsCompound->getChoice() != rhsCompound->getChoice())
227 if (!lhsCompound->getChoice().empty())
229 auto lhsField = lhsCompound->getField(lhsCompound->getChoice());
230 auto rhsField = rhsCompound->getField(rhsCompound->getChoice());
231 if (!equal<ALLOC>(lhsField, rhsField))
239 for (
const auto& fieldInfo : lhsCompound->getTypeInfo().getFields())
241 auto lhsField = lhsCompound->getField(fieldInfo.schemaName);
242 auto rhsField = rhsCompound->getField(fieldInfo.schemaName);
243 if (!equal<ALLOC>(lhsField, rhsField))
253 template <
typename ALLOC>
254 bool ReflectableUtil::valuesEqual(
const IBasicReflectableDataConstPtr<ALLOC>& lhsValue,
255 const IBasicReflectableDataConstPtr<ALLOC>& rhsValue)
257 CppType cppType = lhsValue->getTypeInfo().getCppType();
260 cppType = lhsValue->getTypeInfo().getUnderlyingType().getCppType();
266 return lhsValue->getBool() == rhsValue->getBool();
271 return lhsValue->toInt() == rhsValue->toInt();
276 return lhsValue->toUInt() == rhsValue->toUInt();
279 return doubleValuesAlmostEqual(lhsValue->toDouble(), rhsValue->toDouble());
282 Span<const uint8_t> lhs = lhsValue->getBytes();
283 Span<const uint8_t> rhs = rhsValue->getBytes();
285 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
288 return lhsValue->getStringView() == rhsValue->getStringView();
290 return lhsValue->getBitBuffer() == rhsValue->getBitBuffer();
292 throw CppRuntimeException(
"ReflectableUtil::valuesEqual - Unexpected C++ type!");
296 inline bool ReflectableUtil::doubleValuesAlmostEqual(
double lhs,
double rhs)
298 if (std::isinf(lhs) || std::isinf(rhs))
300 return std::isinf(lhs) && std::isinf(rhs) && ((lhs > 0.0 && rhs > 0.0) || (lhs < 0.0 && rhs < 0.0));
303 if (std::isnan(lhs) || std::isnan(rhs))
305 return std::isnan(lhs) && std::isnan(rhs);
309 return std::fabs(lhs - rhs) <= std::numeric_limits<double>::epsilon() * std::fabs(lhs + rhs) ||
310 std::fabs(lhs - rhs) < std::numeric_limits<double>::min();
313 template <
typename T,
typename ALLOC>
316 if constexpr (is_bitmask_v<T>)
318 using ZserioType =
typename T::ZserioType;
319 using UnderlyingType =
typename ZserioType::ValueType;
321 if (any.template isType<T>())
323 return any.template get<T>();
325 else if (any.template isType<ZserioType>())
327 return T(any.template get<ZserioType>());
331 return T(any.template get<UnderlyingType>());
334 else if constexpr (std::is_enum_v<T>)
337 using UnderlyingType = std::underlying_type_t<T>;
339 if (any.template isType<T>())
341 return any.template get<T>();
343 else if (any.template isType<ZserioType>())
345 return valueToEnum<T>(any.template get<ZserioType>());
349 return valueToEnum<T>(any.template get<UnderlyingType>());
352 else if constexpr (is_numeric_wrapper_v<T>)
354 if (any.template isType<T>())
356 return any.template get<T>();
360 return any.template get<typename T::ValueType>();
365 return any.template get<T>();
static T getValue(const IBasicReflectableDataConstPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static const T & getValue(const IBasicReflectableDataPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static bool equal(const IBasicReflectableDataConstPtr< ALLOC > &lhs, const IBasicReflectableDataConstPtr< ALLOC > &rhs)
static T fromAny(const BasicAny< ALLOC > &any)
static const T & getValue(const IBasicReflectableDataConstPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static T & getValue(const IBasicReflectableDataPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
typename IBasicReflectableData< ALLOC >::ConstPtr IBasicReflectableDataConstPtr
typename IBasicReflectableData< ALLOC >::Ptr IBasicReflectableDataPtr
IBasicReflectableDataConstPtr< ALLOC > reflectable(const T &value, const ALLOC &allocator=ALLOC())
decltype(auto) get(BasicVariant< ALLOC, INDEX, T... > &var)
static bool hasChoice(SchemaType schemaType)
static bool isCompound(SchemaType schemaType)