Lumiera  0.pre.03
»edit your freedom«
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(typename 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(typename 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  ||sizeof(Yes_t)==sizeof(check2<TY>(0))); \
319  };
320 
321 
322 
323 #endif
Simple and lightweight helpers for metaprogramming and type detection.