187 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Tencent is pleased to support the open source community by making RapidJSON available.
 | 
						|
// 
 | 
						|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
 | 
						|
//
 | 
						|
// Licensed under the MIT License (the "License"); you may not use this file except
 | 
						|
// in compliance with the License. You may obtain a copy of the License at
 | 
						|
//
 | 
						|
// http://opensource.org/licenses/MIT
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software distributed 
 | 
						|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 | 
						|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 | 
						|
// specific language governing permissions and limitations under the License.
 | 
						|
 | 
						|
#ifndef RAPIDJSON_INTERNAL_META_H_
 | 
						|
#define RAPIDJSON_INTERNAL_META_H_
 | 
						|
 | 
						|
#include "../rapidjson.h"
 | 
						|
 | 
						|
#ifdef __GNUC__
 | 
						|
RAPIDJSON_DIAG_PUSH
 | 
						|
RAPIDJSON_DIAG_OFF(effc++)
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(_MSC_VER) && !defined(__clang__)
 | 
						|
RAPIDJSON_DIAG_PUSH
 | 
						|
RAPIDJSON_DIAG_OFF(6334)
 | 
						|
#endif
 | 
						|
 | 
						|
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
 | 
						|
#include <type_traits>
 | 
						|
#endif
 | 
						|
 | 
						|
//@cond RAPIDJSON_INTERNAL
 | 
						|
RAPIDJSON_NAMESPACE_BEGIN
 | 
						|
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
 | 
						|
//
 | 
						|
template <bool Cond> struct BoolType {
 | 
						|
    static const bool Value = Cond;
 | 
						|
    typedef BoolType Type;
 | 
						|
};
 | 
						|
typedef BoolType<true> TrueType;
 | 
						|
typedef BoolType<false> FalseType;
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
 | 
						|
//
 | 
						|
 | 
						|
template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
 | 
						|
template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
 | 
						|
template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
 | 
						|
template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
 | 
						|
 | 
						|
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
 | 
						|
template <> struct AndExprCond<true, true> : TrueType {};
 | 
						|
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
 | 
						|
template <> struct OrExprCond<false, false> : FalseType {};
 | 
						|
 | 
						|
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
 | 
						|
template <typename C> struct NotExpr  : SelectIf<C,FalseType,TrueType>::Type {};
 | 
						|
template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
 | 
						|
template <typename C1, typename C2> struct OrExpr  : OrExprCond<C1::Value, C2::Value>::Type {};
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// AddConst, MaybeAddConst, RemoveConst
 | 
						|
template <typename T> struct AddConst { typedef const T Type; };
 | 
						|
template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
 | 
						|
template <typename T> struct RemoveConst { typedef T Type; };
 | 
						|
template <typename T> struct RemoveConst<const T> { typedef T Type; };
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// IsSame, IsConst, IsMoreConst, IsPointer
 | 
						|
//
 | 
						|
template <typename T, typename U> struct IsSame : FalseType {};
 | 
						|
template <typename T> struct IsSame<T, T> : TrueType {};
 | 
						|
 | 
						|
template <typename T> struct IsConst : FalseType {};
 | 
						|
template <typename T> struct IsConst<const T> : TrueType {};
 | 
						|
 | 
						|
template <typename CT, typename T>
 | 
						|
struct IsMoreConst
 | 
						|
    : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
 | 
						|
              BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
 | 
						|
 | 
						|
template <typename T> struct IsPointer : FalseType {};
 | 
						|
template <typename T> struct IsPointer<T*> : TrueType {};
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// IsBaseOf
 | 
						|
//
 | 
						|
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
 | 
						|
 | 
						|
template <typename B, typename D> struct IsBaseOf
 | 
						|
    : BoolType< ::std::is_base_of<B,D>::value> {};
 | 
						|
 | 
						|
#else // simplified version adopted from Boost
 | 
						|
 | 
						|
template<typename B, typename D> struct IsBaseOfImpl {
 | 
						|
    RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
 | 
						|
    RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
 | 
						|
 | 
						|
    typedef char (&Yes)[1];
 | 
						|
    typedef char (&No) [2];
 | 
						|
 | 
						|
    template <typename T>
 | 
						|
    static Yes Check(const D*, T);
 | 
						|
    static No  Check(const B*, int);
 | 
						|
 | 
						|
    struct Host {
 | 
						|
        operator const B*() const;
 | 
						|
        operator const D*();
 | 
						|
    };
 | 
						|
 | 
						|
    enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
 | 
						|
};
 | 
						|
 | 
						|
template <typename B, typename D> struct IsBaseOf
 | 
						|
    : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
 | 
						|
 | 
						|
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
 | 
						|
 | 
						|
 | 
						|
//////////////////////////////////////////////////////////////////////////
 | 
						|
// EnableIf / DisableIf
 | 
						|
//
 | 
						|
template <bool Condition, typename T = void> struct EnableIfCond  { typedef T Type; };
 | 
						|
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
 | 
						|
 | 
						|
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
 | 
						|
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
 | 
						|
 | 
						|
template <typename Condition, typename T = void>
 | 
						|
struct EnableIf : EnableIfCond<Condition::Value, T> {};
 | 
						|
 | 
						|
template <typename Condition, typename T = void>
 | 
						|
struct DisableIf : DisableIfCond<Condition::Value, T> {};
 | 
						|
 | 
						|
// SFINAE helpers
 | 
						|
struct SfinaeTag {};
 | 
						|
template <typename T> struct RemoveSfinaeTag;
 | 
						|
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
 | 
						|
 | 
						|
#define RAPIDJSON_REMOVEFPTR_(type) \
 | 
						|
    typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
 | 
						|
        < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
 | 
						|
 | 
						|
#define RAPIDJSON_ENABLEIF(cond) \
 | 
						|
    typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
 | 
						|
        <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
 | 
						|
 | 
						|
#define RAPIDJSON_DISABLEIF(cond) \
 | 
						|
    typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
 | 
						|
        <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
 | 
						|
 | 
						|
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
 | 
						|
    typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
 | 
						|
        <RAPIDJSON_REMOVEFPTR_(cond), \
 | 
						|
         RAPIDJSON_REMOVEFPTR_(returntype)>::Type
 | 
						|
 | 
						|
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
 | 
						|
    typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
 | 
						|
        <RAPIDJSON_REMOVEFPTR_(cond), \
 | 
						|
         RAPIDJSON_REMOVEFPTR_(returntype)>::Type
 | 
						|
 | 
						|
} // namespace internal
 | 
						|
RAPIDJSON_NAMESPACE_END
 | 
						|
//@endcond
 | 
						|
 | 
						|
#if defined(_MSC_VER) && !defined(__clang__)
 | 
						|
RAPIDJSON_DIAG_POP
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef __GNUC__
 | 
						|
RAPIDJSON_DIAG_POP
 | 
						|
#endif
 | 
						|
 | 
						|
#endif // RAPIDJSON_INTERNAL_META_H_
 |