include
tesseract_common
sfinae_utils.h
Go to the documentation of this file.
1
#ifndef TESSEACT_COMMON_SFINAE_UTILS_H
2
#define TESSEACT_COMMON_SFINAE_UTILS_H
3
4
#include <
tesseract_common/macros.h
>
5
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
6
#include <type_traits>
7
#include <array>
8
TESSERACT_COMMON_IGNORE_WARNINGS_POP
9
10
/*
11
* https://stackoverflow.com/questions/257288/templated-check-for-the-existence-of-a-class-member-function
12
*
13
* - Multiple inheritance forces ambiguity of member names.
14
* - SFINAE is used to make aliases to member names.
15
* - Expression SFINAE is used in just one generic has_member that can accept
16
* any alias we pass it.
17
*/
18
19
namespace
tesseract_common
20
{
21
// Variadic to force ambiguity of class members. C++11 and up.
22
template
<
typename
... Args>
23
struct
ambiguate
:
public
Args...
24
{
25
};
26
27
template
<
typename
A,
typename
=
void
>
28
struct
got_type
: std::false_type
29
{
30
};
31
32
template
<
typename
A>
33
struct
got_type
<A> : std::true_type
34
{
35
using
type
= A;
36
};
37
38
template
<
typename
T, T>
39
struct
sig_check
: std::true_type
40
{
41
};
42
43
template
<
typename
Alias,
typename
AmbiguitySeed>
44
struct
has_member
45
{
46
template
<
typename
C>
47
static
std::array<char, 1>&
f
(decltype(&C::value));
48
template
<
typename
C>
49
static
std::array<char, 2>&
f
(...);
50
51
// Make sure the member name is consistently spelled the same.
52
static_assert((
sizeof
(f<AmbiguitySeed>(
nullptr
)) == 1),
53
"Member name specified in AmbiguitySeed is different from member name specified in Alias, or wrong "
54
"Alias/AmbiguitySeed has been specified."
);
55
56
static
bool
const
value
=
sizeof
(f<Alias>(
nullptr
)) == 2;
57
};
58
68
#define CREATE_MEMBER_CHECK(member) \
69
\
70
template <typename T, typename = std::true_type> \
71
struct Alias_##member; \
72
\
73
template <typename T> \
74
struct Alias_##member<T, std::integral_constant<bool, tesseract_common::got_type<decltype(&T::member)>::value>> \
75
{ \
76
static const decltype(&T::member) value; \
77
}; \
78
\
79
struct AmbiguitySeed_##member \
80
{ \
81
char member;
/* NOLINT */
\
82
}; \
83
\
84
template <typename T> \
85
struct has_member_##member \
86
{ \
87
static const bool value = \
88
tesseract_common::has_member<Alias_##member<tesseract_common::ambiguate<T, AmbiguitySeed_##member>>, \
89
Alias_##member<AmbiguitySeed_##member>>::value; \
90
}
91
99
#define CREATE_MEMBER_FUNC_INVOCABLE_CHECK(func_name, ...) \
100
\
101
template <typename T, typename = std::true_type> \
102
struct has_member_func_invocable_##func_name : std::false_type \
103
{ \
104
}; \
105
\
106
template <typename T> \
107
struct has_member_func_invocable_##func_name< \
108
T, \
109
std::integral_constant<bool, std::is_invocable<decltype(&T::func_name), T, __VA_ARGS__>::value>> \
110
: std::true_type \
111
{ \
112
};
113
121
#define CREATE_MEMBER_FUNC_RETURN_TYPE_CHECK(func_name, return_type, ...) \
122
\
123
template <typename T, typename = std::true_type> \
124
struct has_member_func_return_type_##func_name : std::false_type \
125
{ \
126
}; \
127
\
128
template <typename T> \
129
struct has_member_func_return_type_##func_name< \
130
T, \
131
std::integral_constant<bool, \
132
std::is_same<typename std::invoke_result<decltype(&T::func_name), T, __VA_ARGS__>::type, \
133
return_type>::value>> : std::true_type \
134
{ \
135
};
136
144
#define CREATE_MEMBER_FUNC_RETURN_TYPE_NOARGS_CHECK(func_name, return_type) \
145
\
146
template <typename T, typename = std::true_type> \
147
struct has_member_func_return_type_##func_name : std::false_type \
148
{ \
149
}; \
150
\
151
template <typename T> \
152
struct has_member_func_return_type_##func_name< \
153
T, \
154
std::integral_constant< \
155
bool, \
156
std::is_same<typename std::invoke_result<decltype(&T::func_name), T>::type, return_type>::value>> \
157
: std::true_type \
158
{ \
159
};
160
168
#define CREATE_MEMBER_FUNC_SIGNATURE_CHECK(func_name, return_type, ...) \
169
\
170
template <typename T, typename = std::true_type> \
171
struct has_member_func_signature_##func_name : std::false_type \
172
{ \
173
}; \
174
\
175
template <typename T> \
176
struct has_member_func_signature_##func_name< \
177
T, \
178
std::integral_constant< \
179
bool, \
180
std::is_invocable<decltype(&T::func_name), T, __VA_ARGS__>::value && \
181
std::is_same<typename std::invoke_result<decltype(&T::func_name), T, __VA_ARGS__>::type, \
182
return_type>::value>> : std::true_type \
183
{ \
184
};
185
193
#define CREATE_MEMBER_FUNC_SIGNATURE_NOARGS_CHECK(func_name, return_type) \
194
\
195
template <typename T, typename = std::true_type> \
196
struct has_member_func_signature_##func_name : std::false_type \
197
{ \
198
}; \
199
\
200
template <typename T> \
201
struct has_member_func_signature_##func_name< \
202
T, \
203
std::integral_constant< \
204
bool, \
205
std::is_invocable<decltype(&T::func_name), T>::value && \
206
std::is_same<typename std::invoke_result<decltype(&T::func_name), T>::type, return_type>::value>> \
207
: std::true_type \
208
{ \
209
};
210
211
}
// namespace tesseract_common
212
213
#endif // TESSEACT_COMMON_SFINAE_UTILS_H
tesseract_common
Definition:
allowed_collision_matrix.h:19
macros.h
Common Tesseract Macros.
tesseract_common::got_type
Definition:
sfinae_utils.h:28
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
Definition:
macros.h:71
tesseract_common::has_member::f
static std::array< char, 1 > & f(decltype(&C::value))
tesseract_common::got_type< A >::type
A type
Definition:
sfinae_utils.h:35
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
Definition:
macros.h:72
tesseract_common::ambiguate
Definition:
sfinae_utils.h:23
tesseract_common::has_member
Definition:
sfinae_utils.h:44
tesseract_common::sig_check
Definition:
sfinae_utils.h:39
tesseract_common::has_member::value
static const bool value
Definition:
sfinae_utils.h:56
tesseract_common
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:01:40