1#ifndef ZSERIO_REFLECTABLE_UTIL_H_INC
2#define ZSERIO_REFLECTABLE_UTIL_H_INC
24struct 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>
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>
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,
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>
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);
160template <
typename ALLOC>
164 if (
lhs ==
nullptr ||
rhs ==
nullptr)
178 if (
lhs->isArray() ||
rhs->isArray())
180 if (!
lhs->isArray() || !
rhs->isArray())
196template <
typename ALLOC>
205 for (
size_t i = 0; i < lhsArray->size(); ++i)
207 if (!equal<ALLOC>(lhsArray->at(i), rhsArray->at(i)))
216template <
typename ALLOC>
217bool 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))
253template <
typename ALLOC>
254bool 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!");
296inline 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();
313template <
typename T,
typename ALLOC>
334 else if constexpr (std::is_enum_v<T>)
static T getValue(const IBasicReflectableDataConstPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static const T & getValue(const IBasicReflectableDataConstPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static bool equal(const IBasicReflectableDataConstPtr< ALLOC > &lhs, const IBasicReflectableDataConstPtr< ALLOC > &rhs)
static const T & getValue(const IBasicReflectableDataPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static T fromAny(const BasicAny< ALLOC > &any)
static T & getValue(const IBasicReflectableDataPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
decltype(auto) get(BasicVariant< ALLOC, INDEX, T... > &var)
IBasicReflectableDataConstPtr< ALLOC > reflectable(const T &value, const ALLOC &allocator=ALLOC())
static bool hasChoice(SchemaType schemaType)
static bool isCompound(SchemaType schemaType)