8 #include "Utils/Compiler.h"
24 struct FunctionTraits;
26 template<
class R_,
class... Args_>
27 struct FunctionTraits<R_(*)(Args_...)> :
public FunctionTraits<R_(Args_...)>
37 template <
unsigned N1_,
unsigned N2_>
38 constexpr
bool StaticStrEqual(
const char (&str1)[N1_],
const char (&str2)[N2_]) {
59 template<
class R_,
class ...Args_>
60 struct FunctionTraits<R_(Args_...)> {
65 static const unsigned Arity =
sizeof...(Args_);
68 static const bool IsMember =
false;
74 static_assert(
N<
sizeof...(Args_),
"Argument index out of bounds");
77 using Type =
typename std::tuple_element<
N, std::tuple<Args_...>>::type;
82 template<
class C_,
class R_,
class ...Args_>
83 struct FunctionTraits<R_(C_::*)(Args_...)> :
84 public FunctionTraits<R_(typename std::decay<C_>::type&, Args_...)>
86 static const bool IsMember =
true;
89 template<
class C_,
class R_,
class ...Args_>
90 struct FunctionTraits<R_(C_::*)(Args_...) const> :
91 public FunctionTraits<R_(const typename std::decay<C_>::type&, Args_...)>
93 static const bool IsMember =
true;
100 using innertype = FunctionTraits<decltype(&F_::operator())>;
102 using ReturnType =
typename innertype::ReturnType;
104 static const unsigned Arity = innertype::Arity - 1;
106 static const bool IsMember =
false;
108 template <
unsigned N>
111 static_assert(
N<Arity,
"Argument index out of bounds");
117 struct FunctionTraits<F_&> :
public FunctionTraits<F_>
121 struct FunctionTraits<F_&&> :
public FunctionTraits<F_>
127 template<
bool Cond_,
class T1_,
class T2_>
131 template<
class T1_,
class T2_>
132 struct Choose<false, T1_, T2_> {
136 template<
class T1_,
class T2_>
137 struct Choose<true, T1_, T2_> {
171 operator const std::type_info &()
const {
180 virtual const std::type_info &
TypeInfo()
const = 0;
196 virtual void *
Clone(
const void*
const obj)
const = 0;
199 virtual void Clone(
void*
const dest,
const void*
const obj)
const = 0;
202 virtual void Delete(
void* obj)
const = 0;
212 using NewType =
typename std::remove_const<typename Choose<std::is_reference<T_>::value,
typename std::remove_reference<T_>::type*, T_>
::Type>::type;
215 virtual RTTS *Duplicate()
const override {
220 virtual void *Clone(
const void*
const obj)
const override {
221 auto n =
new NewType(*
reinterpret_cast<CloneType
>(obj));
226 virtual void Clone(
void*
const dest,
const void*
const obj)
const override {
227 *
reinterpret_cast<StorageType
>(dest) = *
reinterpret_cast<CloneType
>(obj);
231 virtual void Delete(
void *obj)
const override {
232 delete static_cast<StorageType
>(obj);
235 virtual bool IsSameType(
const std::type_info &info)
const override {
236 return info==
typeid(T_);
239 virtual const std::type_info &TypeInfo()
const override {
243 virtual long GetSize()
const override {
return sizeof(T_); }
245 virtual bool IsPointer()
const override {
return std::is_pointer<T_>::value; }
247 virtual bool IsReference()
const override {
return std::is_reference<T_>::value; }
249 virtual bool IsConstant()
const override {
return std::is_const<T_>::value; }
253 typename std::enable_if<std::is_copy_constructible<T_>::value && !std::is_abstract<T_>::value,
void*>::type
255 using NewType =
typename std::remove_const<typename Choose<std::is_reference<T_>::value,
typename std::remove_reference<T_>::type*, T_>
::Type>::type;
258 auto n =
new NewType(*
reinterpret_cast<CloneType
>(obj));
263 typename std::enable_if<!std::is_copy_constructible<T_>::value || std::is_abstract<T_>::value,
void*>::type
clonetype_wnull(
const void*
const obj) {
268 typename std::enable_if<std::is_copy_assignable<T_>::value && !std::is_const<T_>::value,
void>::type
270 using NewType =
typename std::remove_const<typename Choose<std::is_reference<T_>::value,
typename std::remove_reference<T_>::type*, T_>
::Type>::type;
274 *
reinterpret_cast<StorageType
>(dest) = *
reinterpret_cast<CloneType
>(obj);
277 typename std::enable_if<!std::is_copy_assignable<T_>::value || std::is_const<T_>::value,
void>::type
copytype_wnull(
void*
const dest,
const void*
const obj) {
285 using NewType =
typename std::remove_const<typename Choose<std::is_reference<T_>::value,
typename std::remove_reference<T_>::type*, T_>
::Type>::type;
288 virtual RTTS *Duplicate()
const {
292 virtual void* Clone(
const void*
const obj)
const override {
293 return clonetype_wnull<T_>(obj);
296 virtual void Clone(
void*
const dest,
const void*
const obj)
const override {
297 copytype_wnull<T_>(dest, obj);
300 virtual void Delete(
void *obj)
const override {
301 delete static_cast<StorageType
>(obj);
304 virtual bool IsSameType(
const std::type_info &info)
const override {
305 return info==
typeid(T_);
308 virtual const std::type_info &TypeInfo()
const override {
312 virtual long GetSize()
const override {
return sizeof(T_); }
314 virtual bool IsPointer()
const override {
return std::is_pointer<T_>::value; }
316 virtual bool IsReference()
const override {
return std::is_reference<T_>::value; }
318 virtual bool IsConstant()
const override {
return std::is_const<T_>::value; }
325 virtual RTTS *Duplicate()
const {
329 virtual void *Create()
const {
333 virtual void *Clone(
const void*
const obj)
const override {
337 virtual void Clone(
void*
const dest,
const void*
const obj)
const override {
341 virtual void Delete(
void *obj)
const override {
342 throw std::runtime_error(
"type is void");
345 virtual bool IsSameType(
const std::type_info &info)
const override {
346 return info==
typeid(void);
349 virtual const std::type_info &TypeInfo()
const override {
353 virtual long GetSize()
const override {
return 0; }
355 virtual bool IsPointer()
const override {
return std::is_pointer<void>::value; }
357 virtual bool IsReference()
const override {
return std::is_reference<void>::value; }
359 virtual bool IsConstant()
const override {
return std::is_const<void>::value; }
388 using BaseType =
typename std::remove_const<typename std::remove_reference<T_>::type>::type;
403 using BaseType =
typename std::remove_const<typename std::remove_reference<T_>::type>::type;
433 static one test(decltype(((std::ostream*)
nullptr)->
operator<<((TT*)
nullptr))) {
return one(); }
435 static two test(...) {
return two(); }
438 static const bool Value =
sizeof( test(*(std::ostream*)
nullptr) )==1;
444 template<>
struct Placeholder<1> {
static decltype(std::placeholders::_1)
value() {
return std::placeholders::_1; } };
445 template<>
struct Placeholder<2> {
static decltype(std::placeholders::_2)
value() {
return std::placeholders::_2; } };
446 template<>
struct Placeholder<3> {
static decltype(std::placeholders::_3)
value() {
return std::placeholders::_3; } };
447 template<>
struct Placeholder<4> {
static decltype(std::placeholders::_4)
value() {
return std::placeholders::_4; } };
448 template<>
struct Placeholder<5> {
static decltype(std::placeholders::_5)
value() {
return std::placeholders::_5; } };
449 template<>
struct Placeholder<6> {
static decltype(std::placeholders::_6)
value() {
return std::placeholders::_6; } };
450 template<>
struct Placeholder<7> {
static decltype(std::placeholders::_7)
value() {
return std::placeholders::_7; } };
451 template<>
struct Placeholder<8> {
static decltype(std::placeholders::_8)
value() {
return std::placeholders::_8; } };
452 template<>
struct Placeholder<9> {
static decltype(std::placeholders::_9)
value() {
return std::placeholders::_9; } };
457 template<
int I,
typename IntTuple,
typename... Types>
460 template<
int I,
int... Indices,
typename T,
typename... Types>
467 template<
int I,
int... Indices>
472 template<
typename... Types>
475 template<
class T,
class Ret_,
class... Args,
int... Indices >
481 template<
class T_,
class Ret_,
class... Args >
486 template <
typename U>
490 template<
typename T,
typename L=decltype(&T::operator())>