Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
duck-detector.hpp
Go to the documentation of this file.
1/*
2 DUCK-DETECTOR.hpp - helpers for statically detecting properties of a type
3
4 Copyright (C)
5 2010, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
93#ifndef LIB_META_DUCK_DETECTOR_H
94#define LIB_META_DUCK_DETECTOR_H
95
96
97#include "lib/meta/util.hpp"
98
99
100
101
102
111#define META_DETECT_NESTED(_TYPE_) \
112 template<typename TY> \
113 class HasNested_##_TYPE_ \
114 { \
115 \
116 template<class X> \
117 static Yes_t check(X::_TYPE_ *); \
118 template<class> \
119 static No_t check(...); \
120 \
121 public: \
122 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
123 };
124
125
126
134#define META_DETECT_MEMBER(_NAME_) \
135 template<typename TY> \
136 class HasMember_##_NAME_ \
137 { \
138 template<typename X, \
139 typename SEL = decltype(&X::_NAME_)> \
140 struct Probe \
141 { }; \
142 \
143 template<class X> \
144 static Yes_t check(Probe<X> * ); \
145 template<class> \
146 static No_t check(...); \
147 \
148 public: \
149 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
150 };
151
152
153
161#define META_DETECT_FUNCTION(_RET_TYPE_,_FUN_NAME_,_ARGS_) \
162 template<typename TY> \
163 class HasFunSig_##_FUN_NAME_ \
164 { \
165 template<typename X, _RET_TYPE_ (X::*)_ARGS_> \
166 struct Probe \
167 { }; \
168 \
169 template<class X> \
170 static Yes_t check(Probe<X, &X::_FUN_NAME_> * ); \
171 template<class> \
172 static No_t check(...); \
173 \
174 public: \
175 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
176 };
177
178
186#define META_DETECT_FUNCTION_NAME(_FUN_NAME_) \
187 template<typename TY> \
188 class HasFunName_##_FUN_NAME_ \
189 { \
190 template<typename SEL> \
191 struct Probe; \
192 template<class C, typename RET, typename...ARGS> \
193 struct Probe<RET (C::*) (ARGS...)> \
194 { \
195 using Match = void; \
196 }; \
197 template<class C, typename RET, typename...ARGS> \
198 struct Probe<RET (C::*) (ARGS...) const> \
199 { \
200 using Match = void; \
201 }; \
202 \
203 template<class X> \
204 static Yes_t check(Probe<decltype(&X::_FUN_NAME_)>::Match * ); \
205 template<class> \
206 static No_t check(...); \
207 \
208 public: \
209 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
210 };
211
212
219#define META_DETECT_FUNCTION_ARGLESS(_FUN_) \
220 template<typename TY> \
221 class HasArglessFun_##_FUN_ \
222 { \
223 template<typename X, \
224 typename SEL = decltype(std::declval<X>()._FUN_())>\
225 struct Probe \
226 { }; \
227 \
228 template<class X> \
229 static Yes_t check(Probe<X> * ); \
230 template<class> \
231 static No_t check(...); \
232 \
233 public: \
234 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
235 };
236
237
238
248#define META_DETECT_EXTENSION_POINT(_FUN_) \
249 template<typename TY> \
250 class HasExtensionPoint_##_FUN_ \
251 { \
252 template<typename X, \
253 typename SEL = decltype( _FUN_(std::declval<X>()))>\
254 struct Probe \
255 { }; \
256 \
257 template<class X> \
258 static Yes_t check(Probe<X> * ); \
259 template<class> \
260 static No_t check(...); \
261 \
262 public: \
263 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
264 };
265
266
267
269#define META_DETECT_OPERATOR_DEREF() \
270 template<typename TY> \
271 class HasOperator_deref \
272 { \
273 template<typename X, int i = sizeof(&X::operator*)> \
274 struct Probe \
275 { }; \
276 \
277 template<class X> \
278 static Yes_t check(Probe<X> * ); \
279 template<class> \
280 static No_t check(...); \
281 \
282 public: \
283 static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
284 };
285
286
287
296#define META_DETECT_OPERATOR_INC() \
297 template<typename TY> \
298 class HasOperator_inc \
299 { \
300 template<typename X, X& (X::*)(void)> \
301 struct Probe_1 \
302 { }; \
303 template<typename X, int i = sizeof(&X::operator++)> \
304 struct Probe_2 \
305 { }; \
306 \
307 template<class X> \
308 static Yes_t check1(Probe_1<X, &X::operator++> * ); \
309 template<class> \
310 static No_t check1(...); \
311 template<class X> \
312 static Yes_t check2(Probe_2<X> * ); \
313 template<class> \
314 static No_t check2(...); \
315 \
316 public: \
317 static const bool value = (sizeof(Yes_t)==sizeof(check1<TY>(0)) \
318 or sizeof(Yes_t)==sizeof(check2<TY>(0))); \
319 };
320
321
322
323#endif
Simple and lightweight helpers for metaprogramming and type detection.