1 #ifndef ZSERIO_REFLECTABLE_UTIL_H_INC
2 #define ZSERIO_REFLECTABLE_UTIL_H_INC
23 struct gets_value_by_value
24 : std::integral_constant<bool,
25 std::is_arithmetic<T>::value || std::is_same<StringView, T>::value ||
26 std::is_enum<T>::value || is_bitmask<T>::value>
47 template <
typename ALLOC = std::allocator<u
int8_t>>
61 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
62 typename std::enable_if<detail::gets_value_by_value<T>::value,
int>::type = 0>
65 return reflectable->getAnyValue(allocator).template get<T>();
81 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
82 typename std::enable_if<!detail::gets_value_by_value<T>::value,
int>::type = 0>
86 return reflectable->getAnyValue(allocator).template get<std::reference_wrapper<const T>>().get();
102 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
103 typename std::enable_if<!detail::gets_value_by_value<T>::value &&
104 !std::is_same<BasicBitBuffer<ALLOC>, T>::value,
108 return reflectable->getAnyValue(allocator).template get<std::reference_wrapper<T>>().get();
122 template <
typename T,
typename ALLOC = std::allocator<u
int8_t>,
123 typename std::enable_if<std::is_same<BasicBitBuffer<ALLOC>, T>::value,
int>::type = 0>
126 return reflectable->getAnyValue(allocator).template get<std::reference_wrapper<const T>>().get();
130 template <
typename ALLOC>
131 static bool arraysEqual(
134 template <
typename ALLOC>
138 template <
typename ALLOC>
139 static bool valuesEqual(
142 static bool doubleValuesAlmostEqual(
double lhs,
double rhs);
145 template <
typename ALLOC>
149 if (lhs ==
nullptr || rhs ==
nullptr)
154 const auto& lhsTypeInfo = lhs->getTypeInfo();
155 const auto& rhsTypeInfo = rhs->getTypeInfo();
157 if (lhsTypeInfo.getSchemaType() != rhsTypeInfo.getSchemaType() ||
158 lhsTypeInfo.getSchemaName() != rhsTypeInfo.getSchemaName())
163 if (lhs->isArray() || rhs->isArray())
165 if (!lhs->isArray() || !rhs->isArray())
169 return arraysEqual<ALLOC>(lhs, rhs);
173 return compoundsEqual<ALLOC>(lhs, rhs);
177 return valuesEqual<ALLOC>(lhs, rhs);
181 template <
typename ALLOC>
182 bool ReflectableUtil::arraysEqual(
185 if (lhsArray->size() != rhsArray->size())
190 for (
size_t i = 0; i < lhsArray->size(); ++i)
192 if (!equal<ALLOC>(lhsArray->at(i), rhsArray->at(i)))
201 template <
typename ALLOC>
202 bool ReflectableUtil::compoundsEqual(
const IBasicReflectableConstPtr<ALLOC>& lhsCompound,
203 const IBasicReflectableConstPtr<ALLOC>& rhsCompound)
205 for (
const auto& parameterInfo : lhsCompound->getTypeInfo().getParameters())
207 auto lhsParameter = lhsCompound->getParameter(parameterInfo.schemaName);
208 auto rhsParameter = rhsCompound->getParameter(parameterInfo.schemaName);
209 if (!equal<ALLOC>(lhsParameter, rhsParameter))
217 if (lhsCompound->getChoice() != rhsCompound->getChoice())
222 if (!lhsCompound->getChoice().empty())
224 auto lhsField = lhsCompound->getField(lhsCompound->getChoice());
225 auto rhsField = rhsCompound->getField(rhsCompound->getChoice());
226 if (!equal<ALLOC>(lhsField, rhsField))
234 for (
const auto& fieldInfo : lhsCompound->getTypeInfo().getFields())
236 auto lhsField = lhsCompound->getField(fieldInfo.schemaName);
237 auto rhsField = rhsCompound->getField(fieldInfo.schemaName);
238 if (!equal<ALLOC>(lhsField, rhsField))
248 template <
typename ALLOC>
249 bool ReflectableUtil::valuesEqual(
250 const IBasicReflectableConstPtr<ALLOC>& lhsValue,
const IBasicReflectableConstPtr<ALLOC>& rhsValue)
252 CppType cppType = lhsValue->getTypeInfo().getCppType();
255 cppType = lhsValue->getTypeInfo().getUnderlyingType().getCppType();
261 return lhsValue->getBool() == rhsValue->getBool();
266 return lhsValue->toInt() == rhsValue->toInt();
271 return lhsValue->toUInt() == rhsValue->toUInt();
274 return doubleValuesAlmostEqual(lhsValue->toDouble(), rhsValue->toDouble());
277 Span<const uint8_t> lhs = lhsValue->getBytes();
278 Span<const uint8_t> rhs = rhsValue->getBytes();
280 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
283 return lhsValue->getStringView() == rhsValue->getStringView();
285 return lhsValue->getBitBuffer() == rhsValue->getBitBuffer();
287 throw CppRuntimeException(
"ReflectableUtil::valuesEqual - Unexpected C++ type!");
291 inline bool ReflectableUtil::doubleValuesAlmostEqual(
double lhs,
double rhs)
293 if (std::isinf(lhs) || std::isinf(rhs))
295 return std::isinf(lhs) && std::isinf(rhs) && ((lhs > 0.0 && rhs > 0.0) || (lhs < 0.0 && rhs < 0.0));
298 if (std::isnan(lhs) || std::isnan(rhs))
300 return std::isnan(lhs) && std::isnan(rhs);
304 return std::fabs(lhs - rhs) <= std::numeric_limits<double>::epsilon() * std::fabs(lhs + rhs) ||
305 std::fabs(lhs - rhs) < std::numeric_limits<double>::min();
static bool equal(const IBasicReflectableConstPtr< ALLOC > &lhs, const IBasicReflectableConstPtr< ALLOC > &rhs)
static T getValue(const IBasicReflectableConstPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static const T & getValue(const IBasicReflectablePtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static const T & getValue(const IBasicReflectableConstPtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
static T & getValue(const IBasicReflectablePtr< ALLOC > &reflectable, const ALLOC &allocator=ALLOC())
typename IBasicReflectable< ALLOC >::Ptr IBasicReflectablePtr
typename IBasicReflectable< ALLOC >::ConstPtr IBasicReflectableConstPtr
static bool hasChoice(SchemaType schemaType)
static bool isCompound(SchemaType schemaType)