2014-08-11 22:26:45 +08:00
|
|
|
// Copyright (C) 2011 Milo Yip
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
// THE SOFTWARE.
|
|
|
|
|
2014-07-03 14:24:58 +02:00
|
|
|
#ifndef RAPIDJSON_INTERNAL_META_H_
|
|
|
|
#define RAPIDJSON_INTERNAL_META_H_
|
|
|
|
|
2014-08-11 15:48:43 +02:00
|
|
|
#ifdef __GNUC__
|
|
|
|
RAPIDJSON_DIAG_PUSH
|
|
|
|
RAPIDJSON_DIAG_OFF(effc++)
|
|
|
|
#endif
|
|
|
|
|
2014-07-03 14:24:58 +02:00
|
|
|
//@cond RAPIDJSON_INTERNAL
|
|
|
|
namespace rapidjson {
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
template <int N> struct IntegralC { enum { Value = N }; };
|
|
|
|
template <bool Cond> struct BoolType : IntegralC<Cond> {};
|
|
|
|
struct TrueType : BoolType<true> {};
|
|
|
|
struct FalseType : BoolType<false> {};
|
|
|
|
|
|
|
|
template <typename T> struct AddConst { typedef const T Type; };
|
|
|
|
template <typename T> struct RemoveConst { typedef T Type; };
|
|
|
|
template <typename T> struct RemoveConst<const T> { typedef T Type; };
|
|
|
|
|
|
|
|
template <bool Condition, typename T1, typename T2> struct SelectIfCond;
|
|
|
|
template <typename T1, typename T2> struct SelectIfCond<true,T1,T2> { typedef T1 Type; };
|
|
|
|
template <typename T1, typename T2> struct SelectIfCond<false,T1,T2> { typedef T2 Type; };
|
|
|
|
|
|
|
|
template <typename Condition, typename T1, typename T2>
|
|
|
|
struct SelectIf : SelectIfCond<Condition::Value,T1,T2> {};
|
|
|
|
|
|
|
|
template <bool Constify, typename T>
|
|
|
|
struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
|
|
|
|
|
2014-07-04 15:08:10 +02:00
|
|
|
template <typename T, typename U> struct IsSame : FalseType {};
|
|
|
|
template <typename T> struct IsSame<T,T> : TrueType {};
|
2014-07-03 14:24:58 +02:00
|
|
|
|
2014-07-04 15:08:10 +02:00
|
|
|
template <typename T> struct IsConst : FalseType {};
|
|
|
|
template <typename T> struct IsConst<const T> : TrueType {};
|
2014-07-03 14:24:58 +02:00
|
|
|
|
2014-07-04 16:53:10 +02:00
|
|
|
template <typename T> struct IsPointer : FalseType {};
|
|
|
|
template <typename T> struct IsPointer<T*> : TrueType {};
|
|
|
|
|
2014-07-03 14:24:58 +02:00
|
|
|
template <typename CT, typename T>
|
|
|
|
struct IsMoreConst {
|
2014-08-11 22:26:45 +08:00
|
|
|
enum { Value =
|
|
|
|
( IsSame< typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>::Value
|
|
|
|
&& ( IsConst<CT>::Value >= IsConst<T>::Value ) )
|
|
|
|
};
|
2014-07-03 14:24:58 +02:00
|
|
|
};
|
|
|
|
|
2014-08-30 12:52:36 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// EnableIf / DisableIf
|
|
|
|
//
|
2014-07-03 14:24:58 +02:00
|
|
|
template <bool Condition, typename T = void> struct EnableIfCond;
|
|
|
|
template <typename T> struct EnableIfCond<true, T> { typedef T Type; };
|
|
|
|
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
|
|
|
|
|
|
|
|
template <bool Condition, typename T = void>
|
2014-07-03 22:37:42 +08:00
|
|
|
struct DisableIfCond : EnableIfCond<!Condition, T> {};
|
2014-07-03 14:24:58 +02:00
|
|
|
|
|
|
|
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 SfinaeResultTag {};
|
|
|
|
template <typename T> struct RemoveSfinaeFptr {};
|
|
|
|
template <typename T> struct RemoveSfinaeFptr<SfinaeResultTag&(*)(T)> { typedef T Type; };
|
|
|
|
|
|
|
|
#define RAPIDJSON_REMOVEFPTR_(type) \
|
2014-08-11 22:26:45 +08:00
|
|
|
typename ::rapidjson::internal::RemoveSfinaeFptr \
|
|
|
|
< ::rapidjson::internal::SfinaeResultTag&(*) type>::Type
|
2014-07-03 14:24:58 +02:00
|
|
|
|
|
|
|
#define RAPIDJSON_ENABLEIF(cond) \
|
2014-08-11 22:26:45 +08:00
|
|
|
typename ::rapidjson::internal::EnableIf \
|
|
|
|
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
2014-07-03 14:24:58 +02:00
|
|
|
|
2014-08-30 12:52:36 +02:00
|
|
|
#define RAPIDJSON_DISABLEIF(cond) \
|
|
|
|
typename ::rapidjson::internal::DisableIf \
|
|
|
|
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
|
|
|
|
|
|
|
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
|
|
|
typename ::rapidjson::internal::EnableIf \
|
|
|
|
<RAPIDJSON_REMOVEFPTR_(cond), \
|
|
|
|
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
|
|
|
|
2014-07-04 16:53:10 +02:00
|
|
|
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
2014-08-30 12:52:36 +02:00
|
|
|
typename ::rapidjson::internal::DisableIf \
|
|
|
|
<RAPIDJSON_REMOVEFPTR_(cond), \
|
|
|
|
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
2014-07-04 16:53:10 +02:00
|
|
|
|
2014-07-03 14:24:58 +02:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace rapidjson
|
|
|
|
//@endcond
|
|
|
|
|
2014-08-11 15:48:43 +02:00
|
|
|
#ifdef __GNUC__
|
|
|
|
RAPIDJSON_DIAG_POP
|
|
|
|
#endif
|
|
|
|
|
2014-07-03 14:24:58 +02:00
|
|
|
#endif // RAPIDJSON_INTERNAL_META_H_
|