fw4spl
core/fwCore/include/fwCore/macros.hpp
Go to the documentation of this file.
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
12 #pragma once
13 
14 #include "fwCore/Demangler.hpp"
15 
16 #include <boost/preprocessor/cat.hpp>
17 #include <boost/preprocessor/comparison/equal.hpp>
18 #include <boost/preprocessor/control/expr_if.hpp>
19 #include <boost/preprocessor/control/if.hpp>
20 #include <boost/preprocessor/facilities/empty.hpp>
21 #include <boost/preprocessor/facilities/expand.hpp>
22 #include <boost/preprocessor/logical/and.hpp>
23 #include <boost/preprocessor/logical/not.hpp>
24 #include <boost/preprocessor/repetition/enum_params.hpp>
25 #include <boost/preprocessor/seq/elem.hpp>
26 #include <boost/preprocessor/seq/fold_right.hpp>
27 #include <boost/preprocessor/seq/for_each.hpp>
28 #include <boost/preprocessor/seq/for_each_i.hpp>
29 #include <boost/preprocessor/seq/seq.hpp>
30 #include <boost/preprocessor/seq/size.hpp>
31 #include <boost/preprocessor/seq/to_tuple.hpp>
32 #include <boost/preprocessor/seq/transform.hpp>
33 #include <boost/preprocessor/tuple/elem.hpp>
34 
35 #include <memory>
36 #include <string>
37 #include <type_traits>
38 
39 #ifdef _WIN32
40 #pragma warning(disable: 4003)
41 #endif //_WIN32
42 
43 #define FwCoreNotUsedMacro(x) ((void) x )
44 
48 #define __FWCORE_TYPEDEF_SELF_NAME SelfType
49 #define __FWCORE_TYPEDEF_SHARED_PTR_NAME sptr
50 #define __FWCORE_TYPEDEF_WEAK_PTR_NAME wptr
51 #define __FWCORE_TYPEDEF_UNIQUE_PTR_NAME uptr
52 #define __FWCORE_TYPEDEF_SHARED_PTR_CONST_NAME csptr
53 #define __FWCORE_TYPEDEF_WEAK_PTR_CONST_NAME cwptr
54 #define __FWCORE_TYPEDEF_UNIQUE_PTR_CONST_NAME cuptr
55 #define __FWCORE_FACTORY_NAME New
56 #define __FWCORE_TYPEDEF_SUPERCLASS_NAME BaseClass
57 #define __FWCORE_TYPEDEF_ROOTCLASS_NAME RootClass
58 #define __FWCORE_DYNAMIC_CAST_FUNC_NAME dynamicCast
59 #define __FWCORE_DYNAMIC_CONST_CAST_FUNC_NAME dynamicConstCast
60 #define __FWCORE_CONST_CAST_FUNC_NAME constCast
61 #define __FWCORE_SPTR_FROM_THIS_FUNC_NAME getSptr
62 #define __FWCORE_CONST_SPTR_FROM_THIS_FUNC_NAME getConstSptr
63 #define __FWCORE_ARG_NAME __var
64 
71 #define SPTR(_cls_) std::shared_ptr < _cls_ >
72 
73 #define CSPTR(_cls_) std::shared_ptr < const _cls_ >
74 
75 #define WPTR(_cls_) std::weak_ptr < _cls_ >
76 
77 #define CWPTR(_cls_) std::weak_ptr < const _cls_ >
78 
79 #define UPTR(_cls_) std::unique_ptr < _cls_ >
80 
81 #define CUPTR(_cls_) std::unique_ptr < const _cls_ >
82 
84 // @cond
85 #define __FWCORE_NOTHING( _a_ )
86 #define __FWCORE_NOTHING_2( _a_, _b_ )
87 
88 #define __FWCORE_GET_NTH_ELEM_III(_s_, _n_, _elem_) BOOST_PP_SEQ_ELEM(_n_, _elem_)
89 #define __FWCORE_GET_ARGS_TYPES(_args_) BOOST_PP_SEQ_TRANSFORM(__FWCORE_GET_NTH_ELEM_III, 0, _args_)
90 #define __FWCORE_GET_ARG_DEFAULT_IF_HAS_ONE(arg) \
91  BOOST_PP_EXPR_IF( \
92  BOOST_PP_EQUAL( BOOST_PP_SEQ_SIZE(arg), 2 ), \
93  = \
94  ) \
95  BOOST_PP_EXPAND( \
96  BOOST_PP_IF( \
97  BOOST_PP_EQUAL( BOOST_PP_SEQ_SIZE(arg), 2 ), \
98  BOOST_PP_SEQ_ELEM, __FWCORE_NOTHING_2 \
99  ) \
100  (1, arg) \
101  )
102 
103 #define __FWCORE_SEQ_IS_EMPTY_SINGLE(_seq_) BOOST_PP_AND( BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(_seq_), 1), \
104  BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_ELEM(0, _seq_)), \
105  0) )
106 #define __FWCORE_SEQ_IS_NOT_EMPTY_SINGLE(_seq_) BOOST_PP_NOT(__FWCORE_SEQ_IS_EMPTY_SINGLE(_seq_))
107 
108 /*
109  * __FWCORE_GENERATE_ARGS( ((a)) ((b)) ((c)(default)) ) expands to (a __var, ) (b __var, ) (c __var, = default) where
110  *__var is defined by __FWCORE_ARG_NAME
111  */
112 #define __FWCORE_ADD_ARG_NAME_AND_VALUE_III(s, _data_, _elem_) \
113  BOOST_PP_EXPR_IF(_data_, \
114  (BOOST_PP_SEQ_ELEM(0, _elem_) __FWCORE_ARG_NAME, __FWCORE_GET_ARG_DEFAULT_IF_HAS_ONE(_elem_) ) )
115 #define __FWCORE_GENERATE_ARGS(_args_) \
116  BOOST_PP_IF( \
117  __FWCORE_SEQ_IS_EMPTY_SINGLE(_args_), \
118  (), \
119  BOOST_PP_EXPR_IF(__FWCORE_SEQ_IS_NOT_EMPTY_SINGLE(_args_), \
120  BOOST_PP_SEQ_TRANSFORM) (__FWCORE_ADD_ARG_NAME_AND_VALUE_III, BOOST_PP_SEQ_SIZE(_args_), \
121  _args_ ) \
122  )
123 
124 /*
125  * __FWCORE_GENERATE_TYPED_NUMBERED_TUPLE( ((a)) ((b)) ((c)(default)) ) expands to (a __var0, b __var1, c __var2 =
126  * default) or to () if _args_ is an empty boost_pp sequence
127  */
128 #define __FWCORE_ADD_ID(_r_, _data_, _i_, _elem_) BOOST_PP_IF(_data_, \
129  ( BOOST_PP_CAT( BOOST_PP_TUPLE_ELEM(2, 0, _elem_), \
130  _i_) BOOST_PP_TUPLE_ELEM(2, 1, \
131  _elem_)), ())
132 #define __FWCORE_GENERATE_TYPED_NUMBERED_TUPLE(_args_) \
133  BOOST_PP_IF( \
134  __FWCORE_SEQ_IS_EMPTY_SINGLE(_args_), \
135  (), \
136  BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_FOR_EACH_I(__FWCORE_ADD_ID, BOOST_PP_SEQ_SIZE(_args_), \
137  __FWCORE_GENERATE_ARGS(_args_))) \
138  )
139 
140 /*
141  * __FWCORE_GENERATE_NUMBERED_TUPLE((a)(b)(c)) expands to ( __var0, __var1, __var2) or to () if _args_ is an empty
142  * boost_pp sequence
143  */
144 #define __FWCORE_GENERATE_NUMBERED_TUPLE(_args_) \
145  BOOST_PP_IF( \
146  __FWCORE_SEQ_IS_EMPTY_SINGLE(_args_), \
147  (), \
148  (BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(_args_), __FWCORE_ARG_NAME)) \
149  )
150 
151 /*
152  * Utils for Factories (obj::New(...)), work like constructors utils
153  */
154 #define __FWCORE_GENERATE_FACTORY( _factory_, _args_ ) \
155  static __FWCORE_TYPEDEF_SHARED_PTR_NAME __FWCORE_FACTORY_NAME __FWCORE_GENERATE_TYPED_NUMBERED_TUPLE(_args_) \
156  { \
157  return __FWCORE_TYPEDEF_SHARED_PTR_NAME(_factory_ __FWCORE_GENERATE_NUMBERED_TUPLE(_args_)); \
158  }
159 
160 #define __FWCORE_GENERATE_ONE_FACTORY(_r_, _data_, _args_) \
161  __FWCORE_GENERATE_FACTORY( BOOST_PP_SEQ_ELEM(0, _data_), _args_)
162 
163 #define __FWCORE_GENERATE_FACTORIES( _factory_, _args_ ) \
164  BOOST_PP_SEQ_FOR_EACH(__FWCORE_GENERATE_ONE_FACTORY, (_factory_), _args_)
165 
166 #define __FWCORE_GENERATE_ONE_FACTORY_WITH_N_FACTORIES(_r_, _data_, _factory_args_) \
167  __FWCORE_GENERATE_FACTORY( BOOST_PP_TUPLE_ELEM(2, 0, _factory_args_), BOOST_PP_TUPLE_ELEM(2, 1, _factory_args_))
168 
169 #define __FWCORE_GENERATE_FACTORIES_WITH_N_FACTORIES_I( _factories_args_ ) \
170  BOOST_PP_SEQ_FOR_EACH(__FWCORE_GENERATE_ONE_FACTORY_WITH_N_FACTORIES, (BOOST_PP_EMPTY), _factories_args_)
171 
172 #define __FWCORE_GENERATE_FACTORIES_WITH_ONE_FACTORY( _factory_, _args_ ) \
173  __FWCORE_GENERATE_FACTORIES( _factory_, _args_ )
174 
175 #define __FWCORE_GENERATE_FACTORIES_WITH_N_FACTORIES( _factories_args_ ) \
176  __FWCORE_GENERATE_FACTORIES_WITH_N_FACTORIES_I( _factories_args_ )
177 
178 /*
179  * __FWCORE_GET_CLASSNAME and __FWCORE_GET_SUPERCLASSNAME work with a sequence like "(classname)(baseclassname)" or
180  *"(classname)"
181  * and return respectively 1st and 2nd element
182  *
183  * if the sequence containt only 1 element, __FWCORE_GET_SUPERCLASSNAME returns the 1st
184  */
185 #define __FWCORE_GET_CLASSNAME( _seq_ ) BOOST_PP_SEQ_ELEM(0, _seq_)
186 #define __FWCORE_GET_SUPERCLASSNAME( _seq_ ) BOOST_PP_SEQ_ELEM( BOOST_PP_IF( BOOST_PP_EQUAL( BOOST_PP_SEQ_SIZE(_seq_), \
187  2 ), 1, 0), _seq_)
188 
189 /*
190  * __FWCORE_CLASS_TYPEDEFS define several typdefs for classes (sptr, wptr, ...)
191  *
192  * BaseClass is a typedef to the superclass
193  * RootClass is a typedef to the toplevel base class
194  */
195 #define __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
196  \
197  typedef __FWCORE_GET_CLASSNAME (_classinfo_) __FWCORE_TYPEDEF_SELF_NAME; \
198  \
199  typedef __FWCORE_GET_SUPERCLASSNAME (_classinfo_) __FWCORE_TYPEDEF_SUPERCLASS_NAME; \
200  \
201  typedef BOOST_PP_IF ( BOOST_PP_EQUAL ( BOOST_PP_SEQ_SIZE(_classinfo_), 2 ), \
202  __FWCORE_TYPEDEF_SUPERCLASS_NAME::__FWCORE_TYPEDEF_ROOTCLASS_NAME, \
203  __FWCORE_TYPEDEF_SELF_NAME \
204  ) __FWCORE_TYPEDEF_ROOTCLASS_NAME; \
205  \
206  typedef SPTR ( __FWCORE_TYPEDEF_SELF_NAME ) __FWCORE_TYPEDEF_SHARED_PTR_NAME; \
207  \
208  typedef WPTR ( __FWCORE_TYPEDEF_SELF_NAME ) __FWCORE_TYPEDEF_WEAK_PTR_NAME; \
209  \
210  typedef UPTR ( __FWCORE_TYPEDEF_SELF_NAME ) __FWCORE_TYPEDEF_UNIQUE_PTR_NAME; \
211  \
212  typedef CSPTR ( __FWCORE_TYPEDEF_SELF_NAME ) __FWCORE_TYPEDEF_SHARED_PTR_CONST_NAME; \
213  \
214  typedef CWPTR ( __FWCORE_TYPEDEF_SELF_NAME ) __FWCORE_TYPEDEF_WEAK_PTR_CONST_NAME; \
215  \
216  typedef CUPTR ( __FWCORE_TYPEDEF_SELF_NAME ) __FWCORE_TYPEDEF_UNIQUE_PTR_CONST_NAME;
217 
218 /*
219  * Cast definition for casting from baseclassname and derived to _classname_
220  */
221 #define __FWCORE_GENERATE_CAST(_classname_, _baseclassname_) \
222  \
223  template< class BASETYPE, typename = typename std::enable_if < std::is_const<BASETYPE>::value >::type > \
224  static std::shared_ptr< const _classname_> __FWCORE_DYNAMIC_CAST_FUNC_NAME( \
225  const std::shared_ptr<BASETYPE> &p ) \
226  { \
227  return std::dynamic_pointer_cast< const _classname_ >(p); \
228  } \
229  template< class BASETYPE, typename = typename std::enable_if < !std::is_const<BASETYPE>::value >::type > \
230  static std::shared_ptr<_classname_> __FWCORE_DYNAMIC_CAST_FUNC_NAME( \
231  const std::shared_ptr<BASETYPE> &p ) \
232  { \
233  return std::dynamic_pointer_cast< _classname_ >(p); \
234  } \
235  \
238  template< class BASETYPE > static __FWCORE_TYPEDEF_SHARED_PTR_CONST_NAME __FWCORE_DYNAMIC_CONST_CAST_FUNC_NAME( \
239  BASETYPE const &p ) \
240  { \
241  return std::dynamic_pointer_cast< const _classname_ >(p); \
242  } \
243  \
244  static __FWCORE_TYPEDEF_SHARED_PTR_NAME __FWCORE_CONST_CAST_FUNC_NAME( \
245  __FWCORE_TYPEDEF_SHARED_PTR_CONST_NAME const &p ) \
246  { \
247  return std::const_pointer_cast< _classname_ >(p); \
248  }
249 
250 #define __FWCORE_PREDECLARE(_s_, _state_, _elem_) \
251  BOOST_PP_IF( \
252  BOOST_PP_EQUAL( _s_, 2 ), \
253  class _elem_; , \
254  namespace _elem_ { _state_ } \
255  )
256 
257 // @endcond
258 
270 #define fwCoreAllowSharedFromThis() \
271  \
272  __FWCORE_TYPEDEF_SHARED_PTR_CONST_NAME __FWCORE_CONST_SPTR_FROM_THIS_FUNC_NAME() const { \
273  return __FWCORE_DYNAMIC_CONST_CAST_FUNC_NAME(this->::fwCore::BaseObject::shared_from_this()); \
274  } \
275  \
276  __FWCORE_TYPEDEF_SHARED_PTR_NAME __FWCORE_SPTR_FROM_THIS_FUNC_NAME(){ \
277  return __FWCORE_DYNAMIC_CAST_FUNC_NAME(this->::fwCore::BaseObject::shared_from_this()); \
278  }
279 
292 #define fwCorePredeclare( _cls_ ) \
293  BOOST_PP_SEQ_FOLD_RIGHT( __FWCORE_PREDECLARE, BOOST_PP_SEQ_NIL, _cls_)
294 
295 #define __FWCORE_STATIC_CACHE( value ) \
296  static const std::string __cache__(value); return __cache__;
297 
298 #ifdef __GNUC__
299 #define FW_NOINLINE __attribute__((noinline))
300 #else
301 #define FW_NOINLINE
302 #endif
303 
311 #define __FWCORECLASSNAMEMACRO(_qualifier) \
312  \
313  \
314  \
315  FW_NOINLINE virtual const std::string& getLeafClassname() const _qualifier \
316  { __FWCORE_STATIC_CACHE(::fwCore::Demangler(*this).getLeafClassname()); } \
317  FW_NOINLINE static const std::string& leafClassname() \
318  { __FWCORE_STATIC_CACHE(::fwCore::getLeafClassname<SelfType>()); } \
319  \
320  FW_NOINLINE virtual const std::string& getClassname() const _qualifier \
321  { __FWCORE_STATIC_CACHE(::fwCore::getClassname<SelfType>()); } \
322  FW_NOINLINE static const std::string& classname() \
323  { __FWCORE_STATIC_CACHE(::fwCore::getClassname<SelfType>()); } \
324 
326 #define fwCoreInterfaceMacro() __FWCORECLASSNAMEMACRO()
327 #define fwCoreClassnameMacro() __FWCORECLASSNAMEMACRO(override)
328 
338 #define __FWCOREISTYPEOFMACRO(_classinfo_) \
339  static bool isTypeOf(const std::string& type) \
340  { \
341  if (__FWCORE_TYPEDEF_SELF_NAME::classname() == type) \
342  { \
343  return true; \
344  } \
345  return BOOST_PP_IF( BOOST_PP_EQUAL( BOOST_PP_SEQ_SIZE( _classinfo_), 2 ), \
346  __FWCORE_TYPEDEF_SUPERCLASS_NAME::isTypeOf( type ), false); \
347  }
348 
349 #define __FWCOREISAMACRO(_qualifier) \
350  virtual bool isA(const std::string& type) const _qualifier \
351  { \
352  return __FWCORE_TYPEDEF_SELF_NAME::isTypeOf(type); \
353  }
354 
355 #define fwCoreIsTypeOfMacro(_classinfo_) \
356  __FWCOREISTYPEOFMACRO(_classinfo_) \
357  __FWCOREISAMACRO(override)
358 #define fwCoreInterfaceIsTypeOfMacro(_classinfo_) \
359  __FWCOREISTYPEOFMACRO(_classinfo_) \
360  __FWCOREISAMACRO()
361 
362 namespace fwTools
363 {
364 template<class, class, class>
366 class Factory;
367 }
368 
369 namespace boost
370 {
371 namespace serialization
372 {
373 class access;
374 }
375 }
376 
377 namespace boost
378 {
379 namespace python
380 {
381 namespace objects
382 {
383 template <class, class>
385 }
386 }
387 }
388 
392 #define fwCoreFriendClassFactoryMacro() \
393  friend class ::boost::serialization::access; \
394  template<class, class> \
395  friend struct ::boost::python::objects::pointer_holder; \
396  template<class, class, class> \
397  friend class ::fwTools::ClassFactory; \
398  friend class ::fwTools::Factory;
399 
419 #define fwCoreClassFactoryMacro(_classinfo_, _parameters_, _factory_) \
420  __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
421  \
423  /* @cond */ \
424  /* @endcond */ \
425  __FWCORE_GENERATE_FACTORIES_WITH_ONE_FACTORY(_factory_, _parameters_) \
426  fwCoreFriendClassFactoryMacro() \
427 
428 
447 #define fwCoreClassDefinitionsWithFactoryMacro(_classinfo_, _parameters_, _factory_) \
448  __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
449  \
451  /* @cond */ \
452  /* @endcond */ \
453  __FWCORE_GENERATE_FACTORIES_WITH_ONE_FACTORY(_factory_, _parameters_) \
454  __FWCORE_GENERATE_CAST(__FWCORE_GET_CLASSNAME(_classinfo_), __FWCORE_TYPEDEF_ROOTCLASS_NAME) \
455  fwCoreFriendClassFactoryMacro() \
456  fwCoreClassnameMacro() \
457  fwCoreIsTypeOfMacro(_classinfo_)
458 
476 #define fwCoreClassDefinitionsWithNFactoriesMacro(_classinfo_, _factories_args_) \
477  __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
478  \
480  /* @cond */ \
481  \
482  __FWCORE_GENERATE_FACTORIES_WITH_N_FACTORIES(_factories_args_) \
483  /* @endcond */ \
484  __FWCORE_GENERATE_CAST(__FWCORE_GET_CLASSNAME(_classinfo_), __FWCORE_TYPEDEF_ROOTCLASS_NAME) \
485  fwCoreFriendClassFactoryMacro() \
486  fwCoreClassnameMacro() \
487  fwCoreIsTypeOfMacro(_classinfo_)
488 
496 #define fwCoreServiceClassDefinitionsMacro(_classinfo_) \
497  __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
498  __FWCORE_GENERATE_CAST(__FWCORE_GET_CLASSNAME(_classinfo_), __FWCORE_TYPEDEF_ROOTCLASS_NAME) \
499  fwCoreFriendClassFactoryMacro() \
500  fwCoreClassnameMacro() \
501  fwCoreIsTypeOfMacro(_classinfo_)
502 
511 #define fwCoreNonInstanciableClassDefinitionsMacro(_classinfo_) \
512  __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
513  __FWCORE_GENERATE_CAST(__FWCORE_GET_CLASSNAME(_classinfo_), __FWCORE_TYPEDEF_ROOTCLASS_NAME) \
514  fwCoreClassnameMacro() \
515  fwCoreIsTypeOfMacro(_classinfo_)
516 
525 #define fwCoreBaseClassDefinitionsMacro(_classinfo_) \
526  __FWCORE_CLASS_TYPEDEFS(_classinfo_) \
527  __FWCORE_GENERATE_CAST(__FWCORE_GET_CLASSNAME(_classinfo_), __FWCORE_TYPEDEF_ROOTCLASS_NAME) \
528  fwCoreInterfaceMacro() \
529  fwCoreInterfaceIsTypeOfMacro(_classinfo_)
530 
The namespace fwTools contains several tools like UUID, factory, dispatche, stringizer, macros, helper.