Commit 1da07843 authored by Philipp A. Hartmann's avatar Philipp A. Hartmann

GenericValue: add and use IsGenericValue meta function

This commit adds an IsGenericValue meta function to match arbitrary
instantiations of the GenericValue template (or derived classes).

This meta function is used in the SFINAE-checks to avoid matching
the generic APIs (operator=,==,!=; AddMember, PushBack) for instances
of the main template.  This avoids ambiguities with the GenericValue
overloads.
parent e294ce6f
......@@ -382,6 +382,22 @@ inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& s
}
#endif
///////////////////////////////////////////////////////////////////////////////
// GenericValue type traits
namespace internal {
template <typename T, typename Encoding = void, typename Allocator = void>
struct IsGenericValueImpl : FalseType {};
// select candidates according to nested encoding and allocator types
template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
: IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
// helper to match arbitrary GenericValue instantiations, including derived classes
template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
} // namespace internal
///////////////////////////////////////////////////////////////////////////////
// GenericValue
......@@ -687,7 +703,7 @@ public:
//! Equal-to operator with primitive types
/*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
*/
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsBaseOf<GenericValue,T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
//! Not-equal-to operator
/*! \return !(*this == rhs)
......@@ -698,17 +714,17 @@ public:
//! Not-equal-to operator with arbitrary types
/*! \return !(*this == rhs)
*/
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsBaseOf<GenericValue,T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
//! Equal-to operator with arbitrary types (symmetric version)
/*! \return (rhs == lhs)
*/
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsBaseOf<GenericValue,T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
//! Not-Equal-to operator with arbitrary types (symmetric version)
/*! \return !(rhs == lhs)
*/
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsBaseOf<GenericValue,T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
//@}
//!@name Type
......@@ -949,7 +965,7 @@ public:
\note Amortized Constant time complexity.
*/
template <typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
AddMember(StringRefType name, T value, Allocator& allocator) {
GenericValue n(name);
GenericValue v(value);
......@@ -1174,7 +1190,7 @@ int z = a[0u].GetInt(); // This works too.
\note Amortized constant time complexity.
*/
template <typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
PushBack(T value, Allocator& allocator) {
GenericValue v(value);
return PushBack(v, allocator);
......
......@@ -38,6 +38,8 @@ RAPIDJSON_DIAG_OFF(6334)
namespace rapidjson {
namespace internal {
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
template <typename T> struct Void { typedef void Type; };
///////////////////////////////////////////////////////////////////////////////
// BoolType, TrueType, FalseType
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment