Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp A. Hartmann <pah@qo.cx>2014-08-30 15:22:04 +0400
committerPhilipp A. Hartmann <pah@qo.cx>2014-08-31 13:01:05 +0400
commit1da078433111558ec3a9e7cbdb96f5f8fb26c436 (patch)
tree13b3de2ce97b3cdb78d14b56d7f78284a10661a8 /include/rapidjson
parente294ce6f7a32c5823460eb0160254c21140454e8 (diff)
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.
Diffstat (limited to 'include/rapidjson')
-rw-r--r--include/rapidjson/document.h28
-rw-r--r--include/rapidjson/internal/meta.h2
2 files changed, 24 insertions, 6 deletions
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index 8adfd7d7..e206d846 100644
--- a/include/rapidjson/document.h
+++ b/include/rapidjson/document.h
@@ -383,6 +383,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
//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
@@ -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);
diff --git a/include/rapidjson/internal/meta.h b/include/rapidjson/internal/meta.h
index bcff1a50..578b6702 100644
--- a/include/rapidjson/internal/meta.h
+++ b/include/rapidjson/internal/meta.h
@@ -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