Lumiera  0.pre.03
»edityourfreedom«
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) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
102 #ifndef LIB_META_DUCK_DETECTOR_H
103 #define LIB_META_DUCK_DETECTOR_H
104 
105 
106 #include "lib/meta/util.hpp"
107 
108 
109 
110 
111 
120 #define META_DETECT_NESTED(_TYPE_) \
121  template<typename TY> \
122  class HasNested_##_TYPE_ \
123  { \
124  \
125  template<class X> \
126  static Yes_t check(typename X::_TYPE_ *); \
127  template<class> \
128  static No_t check(...); \
129  \
130  public: \
131  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
132  };
133 
134 
135 
143 #define META_DETECT_MEMBER(_NAME_) \
144  template<typename TY> \
145  class HasMember_##_NAME_ \
146  { \
147  template<typename X, \
148  typename SEL = decltype(&X::_NAME_)> \
149  struct Probe \
150  { }; \
151  \
152  template<class X> \
153  static Yes_t check(Probe<X> * ); \
154  template<class> \
155  static No_t check(...); \
156  \
157  public: \
158  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
159  };
160 
161 
162 
170 #define META_DETECT_FUNCTION(_RET_TYPE_,_FUN_NAME_,_ARGS_) \
171  template<typename TY> \
172  class HasFunSig_##_FUN_NAME_ \
173  { \
174  template<typename X, _RET_TYPE_ (X::*)_ARGS_> \
175  struct Probe \
176  { }; \
177  \
178  template<class X> \
179  static Yes_t check(Probe<X, &X::_FUN_NAME_> * ); \
180  template<class> \
181  static No_t check(...); \
182  \
183  public: \
184  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
185  };
186 
187 
195 #define META_DETECT_FUNCTION_NAME(_FUN_NAME_) \
196  template<typename TY> \
197  class HasFunName_##_FUN_NAME_ \
198  { \
199  template<typename SEL> \
200  struct Probe; \
201  template<class C, typename RET, typename...ARGS> \
202  struct Probe<RET (C::*) (ARGS...)> \
203  { \
204  using Match = void; \
205  }; \
206  template<class C, typename RET, typename...ARGS> \
207  struct Probe<RET (C::*) (ARGS...) const> \
208  { \
209  using Match = void; \
210  }; \
211  \
212  template<class X> \
213  static Yes_t check(typename Probe<decltype(&X::_FUN_NAME_)>::Match * ); \
214  template<class> \
215  static No_t check(...); \
216  \
217  public: \
218  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
219  };
220 
221 
228 #define META_DETECT_FUNCTION_ARGLESS(_FUN_) \
229  template<typename TY> \
230  class HasArglessFun_##_FUN_ \
231  { \
232  template<typename X, \
233  typename SEL = decltype(std::declval<X>()._FUN_())>\
234  struct Probe \
235  { }; \
236  \
237  template<class X> \
238  static Yes_t check(Probe<X> * ); \
239  template<class> \
240  static No_t check(...); \
241  \
242  public: \
243  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
244  };
245 
246 
247 
257 #define META_DETECT_EXTENSION_POINT(_FUN_) \
258  template<typename TY> \
259  class HasExtensionPoint_##_FUN_ \
260  { \
261  template<typename X, \
262  typename SEL = decltype( _FUN_(std::declval<X>()))>\
263  struct Probe \
264  { }; \
265  \
266  template<class X> \
267  static Yes_t check(Probe<X> * ); \
268  template<class> \
269  static No_t check(...); \
270  \
271  public: \
272  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
273  };
274 
275 
276 
278 #define META_DETECT_OPERATOR_DEREF() \
279  template<typename TY> \
280  class HasOperator_deref \
281  { \
282  template<typename X, int i = sizeof(&X::operator*)> \
283  struct Probe \
284  { }; \
285  \
286  template<class X> \
287  static Yes_t check(Probe<X> * ); \
288  template<class> \
289  static No_t check(...); \
290  \
291  public: \
292  static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
293  };
294 
295 
296 
305 #define META_DETECT_OPERATOR_INC() \
306  template<typename TY> \
307  class HasOperator_inc \
308  { \
309  template<typename X, X& (X::*)(void)> \
310  struct Probe_1 \
311  { }; \
312  template<typename X, int i = sizeof(&X::operator++)> \
313  struct Probe_2 \
314  { }; \
315  \
316  template<class X> \
317  static Yes_t check1(Probe_1<X, &X::operator++> * ); \
318  template<class> \
319  static No_t check1(...); \
320  template<class X> \
321  static Yes_t check2(Probe_2<X> * ); \
322  template<class> \
323  static No_t check2(...); \
324  \
325  public: \
326  static const bool value = (sizeof(Yes_t)==sizeof(check1<TY>(0)) \
327  ||sizeof(Yes_t)==sizeof(check2<TY>(0))); \
328  };
329 
330 
331 
332 #endif
Simple and lightweight helpers for metaprogramming and type detection.