CeresEngine
0.2.0
A game development framework
Loading...
Searching...
No Matches
SFINAE.hpp
Go to the documentation of this file.
1
//
2
// CeresEngine - A game development framework
3
//
4
// Created by Rogiel Sulzbach.
5
// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6
//
7
8
#pragma once
9
10
#include "
TypeTraits.hpp
"
11
12
#define CE_SFINAE_HAS_TYPE(NAME) \
13
template<typename, typename = void> struct has_type_##NAME : std::false_type {}; \
14
template<typename T> struct has_type_##NAME<T, std::void_t<typename T::NAME>> : std::true_type {};
15
16
#define CE_SFINAE_HAS_METHOD(NAME) \
17
namespace internal { \
18
template<typename T, bool is_class = std::is_class<T>::value, typename = void> struct has_method_##NAME##_helper : std::false_type {}; \
19
\
20
template<typename T> struct has_method_##NAME##_helper<T, true, std::void_t<decltype(&T::NAME)>> : has_method_##NAME##_helper<decltype(&T::NAME)> {}; \
21
\
22
template<typename Signature> struct has_method_##NAME##_helper<Signature, false> { \
23
static_assert(std::is_member_function_pointer<Signature>::value, "Not a member function pointer"); \
24
using T = typename function_traits<Signature>::class_type; \
25
static_assert(!std::is_void<T>::value, "Void class type"); \
26
\
27
template<typename C, typename = std::void_t<decltype(static_cast<Signature>(&C::NAME))>> static auto check(int) -> std::true_type; \
28
template<typename> static auto check(...) -> std::false_type; \
29
\
30
using type = decltype(check<T>(0)); \
31
}; \
32
} \
33
template<typename Signature> struct has_method_##NAME : internal::has_method_##NAME##_helper<Signature>::type {};
34
35
#define CE_SFINAE_CAN_CALL_METHOD(NAME) \
36
namespace internal { \
37
template<typename T, typename... Args> using result_of_call_method_##NAME = decltype(std::declval<T>().NAME(std::declval<Args>()...)); \
38
} \
39
template<typename T, typename Signature, typename = void> struct can_call_method_##NAME : std::false_type {}; \
40
template<typename T, typename... Args> \
41
struct can_call_method_##NAME<T, void(Args...), std::void_t<internal::result_of_call_method_##NAME<T, Args...>>> : std::true_type {}; \
42
template<typename T, typename R, typename... Args> \
43
struct can_call_method_##NAME<T, R(Args...), \
44
typename std::enable_if<!std::is_void<R>::value && std::is_convertible<internal::result_of_call_method_##NAME<T, Args...>, R>::value>::type> \
45
: std::true_type {};
46
TypeTraits.hpp
Sources
CeresEngine
Foundation
SFINAE.hpp
Generated by
1.9.8