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)
152 const auto& lhsTypeInfo = lhs->getTypeInfo();
153 const auto& rhsTypeInfo = rhs->getTypeInfo();
155 if (lhsTypeInfo.getSchemaType() != rhsTypeInfo.getSchemaType() ||
156 lhsTypeInfo.getSchemaName() != rhsTypeInfo.getSchemaName())
159 if (lhs->isArray() || rhs->isArray())
161 if (!lhs->isArray() || !rhs->isArray())
163 return arraysEqual<ALLOC>(lhs, rhs);
167 return compoundsEqual<ALLOC>(lhs, rhs);
171 return valuesEqual<ALLOC>(lhs, rhs);
175 template <
typename ALLOC>
176 bool ReflectableUtil::arraysEqual(
179 if (lhsArray->size() != rhsArray->size())
182 for (
size_t i = 0; i < lhsArray->size(); ++i)
184 if (!equal<ALLOC>(lhsArray->at(i), rhsArray->at(i)))
191 template <
typename ALLOC>
192 bool ReflectableUtil::compoundsEqual(
const IBasicReflectableConstPtr<ALLOC>& lhsCompound,
193 const IBasicReflectableConstPtr<ALLOC>& rhsCompound)
195 for (
const auto& parameterInfo : lhsCompound->getTypeInfo().getParameters())
197 auto lhsParameter = lhsCompound->getParameter(parameterInfo.schemaName);
198 auto rhsParameter = rhsCompound->getParameter(parameterInfo.schemaName);
199 if (!equal<ALLOC>(lhsParameter, rhsParameter))
205 if (lhsCompound->getChoice() != rhsCompound->getChoice())
208 if (!lhsCompound->getChoice().empty())
210 auto lhsField = lhsCompound->getField(lhsCompound->getChoice());
211 auto rhsField = rhsCompound->getField(rhsCompound->getChoice());
212 if (!equal<ALLOC>(lhsField, rhsField))
218 for (
const auto& fieldInfo : lhsCompound->getTypeInfo().getFields())
220 auto lhsField = lhsCompound->getField(fieldInfo.schemaName);
221 auto rhsField = rhsCompound->getField(fieldInfo.schemaName);
222 if (!equal<ALLOC>(lhsField, rhsField))
230 template <
typename ALLOC>
231 bool ReflectableUtil::valuesEqual(
232 const IBasicReflectableConstPtr<ALLOC>& lhsValue,
const IBasicReflectableConstPtr<ALLOC>& rhsValue)
234 CppType cppType = lhsValue->getTypeInfo().getCppType();
236 cppType = lhsValue->getTypeInfo().getUnderlyingType().getCppType();
241 return lhsValue->getBool() == rhsValue->getBool();
246 return lhsValue->toInt() == rhsValue->toInt();
251 return lhsValue->toUInt() == rhsValue->toUInt();
254 return doubleValuesAlmostEqual(lhsValue->toDouble(), rhsValue->toDouble());
257 Span<const uint8_t> lhs = lhsValue->getBytes();
258 Span<const uint8_t> rhs = rhsValue->getBytes();
260 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
263 return lhsValue->getStringView() == rhsValue->getStringView();
265 return lhsValue->getBitBuffer() == rhsValue->getBitBuffer();
267 throw CppRuntimeException(
"ReflectableUtil::valuesEqual - Unexpected C++ type!");
271 inline bool ReflectableUtil::doubleValuesAlmostEqual(
double lhs,
double rhs)
273 if (std::isinf(lhs) || std::isinf(rhs))
274 return std::isinf(lhs) && std::isinf(rhs) && ((lhs > 0.0 && rhs > 0.0) || (lhs < 0.0 && rhs < 0.0));
276 if (std::isnan(lhs) || std::isnan(rhs))
277 return std::isnan(lhs) && std::isnan(rhs);
280 return std::fabs(lhs - rhs) <= std::numeric_limits<double>::epsilon() * std::fabs(lhs + rhs) ||
281 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)