Tesseract
Motion Planning Environment
Loading...
Searching...
No Matches
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
6#include <type_traits>
7#include <array>
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
19namespace tesseract_common
20{
21// Variadic to force ambiguity of class members. C++11 and up.
22template <typename... Args>
23struct ambiguate : public Args...
24{
25};
26
27template <typename A, typename = void>
28struct got_type : std::false_type
29{
30};
31
32template <typename A>
33struct got_type<A> : std::true_type
34{
35 using type = A;
36};
37
38template <typename T, T>
39struct sig_check : std::true_type
40{
41};
42
43template <typename Alias, typename AmbiguitySeed>
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
Common Tesseract Macros.
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
Definition: macros.h:71
Definition: create_convex_hull.cpp:36
Definition: allowed_collision_matrix.h:16
Definition: sfinae_utils.h:24
A type
Definition: sfinae_utils.h:35
Definition: sfinae_utils.h:29
Definition: sfinae_utils.h:45
static std::array< char, 1 > & f(decltype(&C::value))
static std::array< char, 2 > & f(...)
static bool const value
Definition: sfinae_utils.h:56
Definition: sfinae_utils.h:40