Allow set enum as json value (#4363) (#4434)

* Allow set enum as json value (#4363)

* fix issue #4341
add testEnum
if you set enum as json value then it will be cast to int

* add behavour for enum into VarHolderImpl
add tests for enum classes with differnent underline integral types

* replace static_cast with convertTo* methods, they can chaeck types and
limits

* fix missing types for convert methods

* fix code style
add testEnumType to the VarTest.cpp, extract() works

* enh(VarHolder): replace ::value and ::type with shortcuts

---------

Co-authored-by: Alexander B <ale.bychuk@gmail.com>
This commit is contained in:
Aleksandar Fabijanic
2024-07-29 16:30:51 -05:00
committed by GitHub
parent 03444bdcea
commit 669be63134
5 changed files with 591 additions and 1 deletions

View File

@@ -417,6 +417,42 @@ protected:
to = static_cast<T>(from);
}
template <typename F, typename T, std::enable_if_t<std::is_signed_v<F> && std::is_signed_v<T> && (sizeof(F) <= sizeof(T))>* = nullptr>
void convertToSigned(const F& from, T& to) const
{
to = static_cast<T>(from);
}
template <typename F, typename T, std::enable_if_t<std::is_signed_v<F> && std::is_signed_v<T> && (sizeof(F) > sizeof(T))>* = nullptr>
void convertToSigned(const F& from, T& to) const
{
convertToSmaller(from, to);
}
template <typename F, typename T, std::enable_if_t<!std::is_signed_v<F> && std::is_signed_v<T>>* = nullptr>
void convertToSigned(const F& from, T& to) const
{
convertUnsignedToSigned(from, to);
}
template <typename F, typename T, std::enable_if_t<!std::is_signed_v<F> && !std::is_signed_v<T> && (sizeof(F) <= sizeof(T))>* = nullptr>
void convertToUnsigned(const F& from, T& to) const
{
to = static_cast<T>(from);
}
template <typename F, typename T, std::enable_if_t<!std::is_signed_v<F> && !std::is_signed_v<T> && (sizeof(F) > sizeof(T))>* = nullptr>
void convertToUnsigned(const F& from, T& to) const
{
convertToSmallerUnsigned(from, to);
}
template <typename F, typename T, std::enable_if_t<std::is_signed_v<F> && !std::is_signed_v<T>>* = nullptr>
void convertToUnsigned(const F& from, T& to) const
{
convertSignedToUnsigned(from, to);
}
template <typename F, typename T,
std::enable_if_t<std::is_integral_v<F>, bool> = true,
std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
@@ -787,6 +823,287 @@ public:
return typeid(T);
}
void convert(Int8& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(Int16& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(Int32& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(Int64& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(UInt8& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(UInt16& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(UInt32& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(UInt64& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
#ifdef POCO_INT64_IS_LONG
void convert(long long& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
void convert(unsigned long long& val) const
{
if constexpr (std::is_enum_v<T>)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}
#endif
void convert(bool& val) const
{
if constexpr (std::is_enum_v<T>)
{
val = (std::underlying_type_t<T>(_val) != 0);
}
else
{
VarHolder::convert(val);
}
}
void convert(float& val) const
{
if constexpr (std::is_enum_v<T>)
{
val = static_cast<float>(_val);
}
else
{
VarHolder::convert(val);
}
}
void convert(double& val) const
{
if constexpr (std::is_enum_v<T>)
{
val = static_cast<double>(_val);
}
else
{
VarHolder::convert(val);
}
}
void convert(char& val) const
{
if constexpr (std::is_enum_v<T>)
{
val = static_cast<char>(_val);
}
else
{
VarHolder::convert(val);
}
}
void convert(std::string& val) const
{
if constexpr (std::is_enum_v<T>)
{
val = NumberFormatter::format(std::underlying_type_t<T>(_val));
}
else
{
VarHolder::convert(val);
}
}
void convert(Poco::UTF16String& val) const
{
if constexpr (std::is_enum_v<T>)
{
std::string str = NumberFormatter::format(std::underlying_type_t<T>(_val));
Poco::UnicodeConverter::convert(str, val);
}
else
{
VarHolder::convert(val);
}
}
bool isArray() const
{
if constexpr (std::is_enum_v<T>)
{
return false;
}
else
{
return VarHolder::isArray();
}
}
bool isStruct() const
{
if constexpr (std::is_enum_v<T>)
{
return false;
}
else
{
return VarHolder::isStruct();
}
}
bool isInteger() const
{
if constexpr (std::is_enum_v<T>)
{
return std::numeric_limits<std::underlying_type_t<T>>::is_integer;
}
else
{
return VarHolder::isInteger();
}
}
bool isSigned() const
{
if constexpr (std::is_enum_v<T>)
{
return std::numeric_limits<std::underlying_type_t<T>>::is_signed;
}
else
{
return VarHolder::isSigned();
}
}
bool isNumeric() const
{
if constexpr (std::is_enum_v<T>)
{
return std::numeric_limits<std::underlying_type_t<T>>::is_specialized;
}
else
{
return VarHolder::isNumeric();
}
}
bool isBoolean() const
{
if constexpr (std::is_enum_v<T>)
{
return false;
}
else
{
return VarHolder::isBoolean();
}
}
bool isString() const
{
if constexpr (std::is_enum_v<T>)
{
return false;
}
else
{
return VarHolder::isString();
}
}
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
{
return cloneHolder(pVarHolder, _val);