Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
317 changes: 317 additions & 0 deletions Foundation/include/Poco/Dynamic/VarHolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,42 @@ class Foundation_API VarHolder
checkUpperLimit<F,T>(from);
to = static_cast<T>(from);
}

template <typename F, typename T, std::enable_if_t<std::is_signed<F>::value && std::is_signed<T>::value && (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<F>::value && std::is_signed<T>::value && (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<F>::value && std::is_signed<T>::value>* = nullptr>
void convertToSigned(const F& from, T& to) const
{
convertUnsignedToSigned(from, to);
}

template <typename F, typename T, std::enable_if_t<!std::is_signed<F>::value && !std::is_signed<T>::value && (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<F>::value && !std::is_signed<T>::value && (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<F>::value && !std::is_signed<T>::value>* = nullptr>
void convertToUnsigned(const F& from, T& to) const
{
convertSignedToUnsigned(from, to);
}

template <typename F, typename T,
std::enable_if_t<std::is_integral<F>::value, bool> = true,
Expand Down Expand Up @@ -787,6 +823,287 @@ class VarHolderImpl: public VarHolder
return typeid(T);
}

void convert(Int8& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(Int16& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(Int32& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(Int64& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(UInt8& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(UInt16& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(UInt32& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(UInt64& val) const
{
if constexpr (std::is_enum<T>::value)
{
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<T>::value)
{
convertToSigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

void convert(unsigned long long& val) const
{
if constexpr (std::is_enum<T>::value)
{
convertToUnsigned(std::underlying_type_t<T>(_val), val);
}
else
{
VarHolder::convert(val);
}
}

#endif

void convert(bool& val) const
{
if constexpr (std::is_enum<T>::value)
{
val = (std::underlying_type_t<T>(_val) != 0);
}
else
{
VarHolder::convert(val);
}
}

void convert(float& val) const
{
if constexpr (std::is_enum<T>::value)
{
val = static_cast<float>(_val);
}
else
{
VarHolder::convert(val);
}
}

void convert(double& val) const
{
if constexpr (std::is_enum<T>::value)
{
val = static_cast<double>(_val);
}
else
{
VarHolder::convert(val);
}
}

void convert(char& val) const
{
if constexpr (std::is_enum<T>::value)
{
val = static_cast<char>(_val);
}
else
{
VarHolder::convert(val);
}
}

void convert(std::string& val) const
{
if constexpr (std::is_enum<T>::value)
{
val = NumberFormatter::format(std::underlying_type_t<T>(_val));
}
else
{
VarHolder::convert(val);
}
}

void convert(Poco::UTF16String& val) const
{
if constexpr (std::is_enum<T>::value)
{
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<T>::value)
{
return false;
}
else
{
return VarHolder::isArray();
}
}

bool isStruct() const
{
if constexpr (std::is_enum<T>::value)
{
return false;
}
else
{
return VarHolder::isStruct();
}
}

bool isInteger() const
{
if constexpr (std::is_enum<T>::value)
{
return std::numeric_limits<std::underlying_type_t<T>>::is_integer;
}
else
{
return VarHolder::isInteger();
}
}

bool isSigned() const
{
if constexpr (std::is_enum<T>::value)
{
return std::numeric_limits<std::underlying_type_t<T>>::is_signed;
}
else
{
return VarHolder::isSigned();
}
}

bool isNumeric() const
{
if constexpr (std::is_enum<T>::value)
{
return std::numeric_limits<std::underlying_type_t<T>>::is_specialized;
}
else
{
return VarHolder::isNumeric();
}
}

bool isBoolean() const
{
if constexpr (std::is_enum<T>::value)
{
return false;
}
else
{
return VarHolder::isBoolean();
}
}

bool isString() const
{
if constexpr (std::is_enum<T>::value)
{
return false;
}
else
{
return VarHolder::isString();
}
}

VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
{
return cloneHolder(pVarHolder, _val);
Expand Down
Loading
Loading