Files CCore/inc/gadget/Meta.h CCore/src/gadget/Meta.cpp
The namespace Meta contains a collection of meta-tools widely-used in CCore. They are enclosed in the namespace Meta.
template <class T,T Val> const T Const = Val ;
This is a general Meta-constant with the given type and value.
template <class RetType,class ... TT>
constexpr RetType SumOf(TT ... tt);
This constexpr function sums its arguments and returns the result as the given RetType.
template <class RetType,class ... TT>
constexpr RetType MaxOf(TT ... tt);
This constexpr function finds the maximum of its arguments and returns the result as the given RetType. Arguments are implicitly converted to RetType to participate in calculation. Technically the definition of this function is located not in the file Meta.h, but in the file UtilFunc.h.
struct Empty
{
};
Empty is an empty Meta-class. It is used to return an empty result from Meta-functions.
struct ProbeSetBase
{
template <class T> static T & Ref();
template <class T> static T Obj();
};
This class is used as a base class of probe classes. Such classes are used to determine some type properties. ProbeSetBase declares (but not defines!) two functions to build an expression of the given type or the given reference type.
template <class T>
struct DefType
{
using Ret = T ;
};
DefType is a Meta-function, it returns the given type as the result.
template <class T,T Val>
struct DefConst
{
static const T Ret = Val ;
};
DefConst is a Meta-function, it returns the given constant as the result.
template <bool Cond,class T1,class T2>
using Select = .... ;
Select is a Meta-type. It is used to select a type from two types. If Cond is true, then the first type is selected, otherwise the second.
template <bool Cond,template <class A> class T,class A>
using BuildIf = .... ;
BuildIf is a Meta-type. If Cond is true, then BuildIf equals T<A>. Otherwise it is Empty. In the last case T<A> is not instantiated (that is the point to use this tool).
template <bool Cond,template <class A1> class T1, template <class A1> class T2, class A1> using SelectBuild1 = .... ; template <bool Cond,template <class A1,class A2> class T1, template <class A1,class A2> class T2, class A1,class A2> using SelectBuild2 = .... ; template <bool Cond,template <class A1,class A2,class A3> class T1, template <class A1,class A2,class A3> class T2, class A1,class A2,class A3> using SelectBuild3 = .... ;
SelectBuildx is a Meta-type. If Cond is true, then SelectBuildx equals T1<A1(,A2,A3)>. Otherwise it is T2<A1(,A2,A3)>. The alternative template is not instantiated (that is the point to use this tool).
template <bool Cond,class RetType=void>
using EnableIf = .... ;
EnableIf is a Meta-type. It can be instantiated only if Cond is true and in this case it equals RetType (defaulted to void). This tool is used instead of concepts in the current version of the language.
template <class ProbeSet,class T>
const bool Detect = .... ;
Detect is a Meta-constant. It equals true iff the following template can be instantiated: typename ProbeSet::template Condition<T>. I.e. it is expected, that the structure ProbeSet contains the inner template template <class T> struct Condition. Detect shows if this inner template can be instantiated with the given argument.
template <class T1,class T2>
const bool IsSame = .... ;
IsSame is a Meta-constant. It equals true iff both arguments are the same.
template <class T,class ... TT>
const bool OneOf = .... ;
OneOf is a Meta-constant. It equals true iff the first argument T belongs to the following type list TT.
template <class T>
const bool IsUInt = .... ;
IsUInt is a Meta-constant. It equals true iff the argument is an unsigned integral type. The following types are unsigned integral types: unsignd char, unsigned short, unsigned int, unsigned long, unsigned long long. The type char is an unsigned integral type iff it is unsigned. Some other types can be also considered as unsigned integral types, it is controlled by the target through the target header PlatformBase.h (see below).
template <class T>
const unsigned UIntBits = .... ;
UIntBits is a Meta-constant. It's defined for unsigned integral types (i.e. for types T with IsUInt<T> equals true) and equals the number of bits of the argument.
template <class UInt>
const unsigned HexWidth = (UIntBits<UInt> +3)/4 ;
HexWidth is a Meta-constant. It's defined for unsigned integral types (i.e. for types T with IsUInt<T> equals true) and equals the number of hex digits required to represent a type value.
template <class T>
const bool IsSInt = .... ;
IsSInt is a Meta-constant. It equals true iff the argument is an signed integral type. The following types are signed integral types: signd char, signed short, signed int, signed long, signed long long. The type char is a signed integral type iff it is signed. Some other types can be also considered as signed integral types, it is controlled by the target through the target header PlatformBase.h (see below).
template <class T>
const bool IsSUInt = IsSInt<T> || IsUInt<T> ;
IsSUInt is a Meta-constant. It equals true iff the argument is a signed or an unsigned integral type.
template <class T>
using UnRef = typename std::remove_reference<T>::type ;
UnRef is a Meta-type. It removes the reference qualifier from the argument type.
template <class T>
using UnConst = typename std::remove_const<T>::type ;
UnConst is a Meta-type. It removes the constant qualifier from the argument type.
template <class R>
using RangeObjType = .... ;
RangeObjType is a Meta-type. It should be applied to range kind types to retrieve the type of objects from the range. For example, if R is PtrLen<T>, then RangeObjType<R> is T.
template <ulen Len>
using AlignedStorage = typename std::aligned_storage<Len>::type ;
AlignedStorage is a Meta-type. It is a POD type. An object of this type can be used as an aligned storage of required length.
template <class SInt>
struct SIntToUInt
{
using SType = .... ; // SInt or equivalent signed type
using UType = .... ; // unsigned SType
};
SIntToUInt is a Meta-function. It is applied to signed integral types and returns as the result two types: SType — the original type (or equivalent) and UType — the correspondent unsigned type. The implementation is supported by the target (see below).
template <class UInt>
struct PromoteUInt
{
using Type = .... ; // promoted UInt type
};
PromoteUInt is a Meta-function. It is applied to unsigned integral types and returns as the result a type: Type is a "promoted" type for the UInt. I.e. it is the same or greater type and the promoted type is greater or equals than unsigned. The implementation is supported by the target (see below).
template <class SInt>
struct PromoteSInt
{
using SType = .... ; // promoted SInt type
using UType = .... ; // unsigned SType
};
PromoteSInt is a Meta-function. It is applied to unsigned integral types and returns as the result two types: SType is a "promoted" type for the SInt. I.e. it is the same or greater type and the promoted type is greater or equals than int. UType is the correspondent unsigned SType type. The implementation is supported by the target (see below).
template <class T,class ... TT>
const unsigned IndexOf = .... ;
IndexOf is a Meta-constant. It equals the 1-based index of the type T in the following type list TT.
template <unsigned Index,class ... TT>
using SelectList = .... ;
SelectList is a Meta-type. It equals the type from the type list TT with the given 0-based index.
template <class S,class T>
using CommonType = .... ;
CommonType is a Meta-type. It is defined iff T equals S and is T in this case.
template <class Split,class ... TT>
using SplitTypeList = .... ;
SplitTypeList is a Meta-type. It can be used to split the type list TT:
struct Split { template <class T> struct Last { template <class ... SS> struct Start { }; }; }; SplitTypeList<Split,TT,T> == Split::Last<T>::Start<TT>
template <class Skip,ulen Count,class ... TT>
using SkipTypeList = .... ;
SkipTypeList is a Meta-type. It selects the part of the type list TT and use it as the argument of instantiation of the Skip::Ctor:
struct Skip { template <class ... SS> struct Ctor; }; SkipTypeList<Skip,Count,T1,...,TCount,TCount+1,...> == Skip::Ctor<TCount+1,...>
/* const IsEnum<E> */ template <class E> const bool IsEnum = std::is_enum<E>::value ; /* const IsClass<T> */ template <class T> const bool IsClass = std::is_class<T>::value ; /* const IsPOD<T> */ template <class T> const bool IsPOD = std::is_pod<T>::value ; /* const HasTrivDtor<T> */ template <class T> const bool HasTrivDtor = std::is_trivially_destructible<T>::value ; /* const HasNothrowDefaultCtor<T> */ template <class T> const bool HasNothrowDefaultCtor = std::is_nothrow_default_constructible<T>::value ; /* const HasNothrowCopyCtor<T> */ template <class T> const bool HasNothrowCopyCtor = std::is_nothrow_copy_constructible<T>::value ; /* const HasCopyCtor<T> */ template <class T> const bool HasCopyCtor = std::is_copy_constructible<T>::value ; /* const HasMoveCtor<T> */ template <class T> const bool HasMoveCtor = std::is_move_constructible<T>::value ; /* const IsNothrowCopyable<T> */ template <class T> const bool IsNothrowCopyable = std::is_nothrow_copy_constructible<T>::value && std::is_nothrow_copy_assignable<T>::value ; /* const IsCopyable<T> */ template <class T> const bool IsCopyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value ; /* const IsMovable<T> */ template <class T> const bool IsMovable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value ;
This is a whole list of Meta-constants. They can be used to determine different type properties.
IsEnum equals true iff the type T is an enum type.
IsClass equals true iff the type T is a class type.
IsPOD equals true iff the type T is a POD type.
HasTrivDtor equals true iff the type T is trivially destructible.
HasNothrowDefaultCtor equals true iff the type T is nothrow default constructible.
HasNothrowCopyCtor equals true iff the type T is nothrow copy constructible.
HasCopyCtor equals true iff the type T is copy constructible.
HasMoveCtor equals true iff the type T is move constructible.
IsNothrowCopyable equals true iff the type T is nothrow copy constructible and nothrow copy assignable.
IsCopyable equals true iff the type T is copy constructible and copy assignable.
IsMovable equals true iff the type T is move constructible and move assignable.
Target must provide the following entities in the its header file PlatformBase.h.
namespace CCore { namespace Bits { const unsigned unsigned_char = "bit size of type char" ; const unsigned unsigned_short = "bit size of type short" ; const unsigned unsigned_int = "bit size of type int" ; const unsigned unsigned_long = "bit size of type long" ; const unsigned unsigned_long_long = "bit size of type long long" ; } // namespace Bits } // namespace CCore
The following structure is used to extend the list of types, recognized as integral types:
namespace CCore { namespace ExtraInt { template <class T> struct Prop { enum { IsSigned = false, IsUnsigned = false }; }; template <> struct Prop<"extra sint type"> { enum { IsSigned = true, IsUnsigned = false, }; using SType = "signed type" ; using UType = "unsigned type" ; using PromoteSType = "signed promote type" ; using PromoteUType = "unsigned promote type" ; }; template <> struct Prop<"extra uint type"> { enum { IsSigned = false, IsUnsigned = true, Bits = "bit size" }; using PromoteUType = "promote type" ; }; } // namespace ExtraInt } // namespace CCore