libUTL++
macros.h
1 #pragma once
2 
4 
9 #define self (*this)
10 
12 
17 #define const_self (static_cast<const std::decay<decltype(*this)>::type&>(*this))
18 
20 
25 #define const_this (&const_cast_self)
26 
28 
33 #define const_cast_self (const_cast<std::decay<decltype(*this)>::type&>(*this))
34 
36 
41 #define const_cast_this (&const_cast_self)
42 
44 
49 #undef ASSERT
50 #define ASSERT(x) \
51  if (!(x)) utl::abort(__FILE__, __LINE__, "assertion failed: " #x)
52 
54 
59 #define ABORT() utl::abort(__FILE__, __LINE__)
60 
62 
67 #define DIE(text) utl::die(__FILE__, __LINE__, text)
68 
70 
75 #define BREAKPOINT \
76  { \
77  int __bp__ = 0; \
78  __bp__ = __bp__; \
79  }
80 
82 
87 #ifdef __COUNTER__
88 #define UTL_ANONYMOUS_VARIABLE(str) UTL_CONCATENATE(str, __COUNTER__)
89 #else
90 #define UTL_ANONYMOUS_VARIABLE(str) UTL_CONCATENATE(str, __LINE__)
91 #endif
92 
94 
99 #define UTL_CONCATENATE_IMPL(a, b) a##b
100 
102 
107 #define UTL_CONCATENATE(a, b) UTL_CONCATENATE_IMPL(a, b)
108 
110 
115 #define likely(x) __builtin_expect(!!(x), 1)
116 
121 #define unlikely(x) __builtin_expect(!!(x), 0)
122 
124 
129 #define UTL_PRINT(x) cout << #x " = " << x << endl
130 
132 
133 #undef ASSERTD
134 #ifdef DEBUG
135 #define ASSERTD ASSERT
136 #define ASSERTFNZ(x) ASSERT(x == 0)
137 #define ASSERTFNP(x) ASSERT(x != 0)
138 #define IFDEBUG(x) x
139 #define INLINE
140 #else
141 #define ASSERTD(x)
142 #define ASSERTFNZ(x) x
143 #define ASSERTFNP(x) x
144 #define IFDEBUG(x)
145 #define INLINE inline
146 #endif
147 
149 
156 
164 
172 
180 
188 
194 #define UTL_INSTANTIATE_TPL(className, T) \
195  UTL_CLASS_IMPL_NAME_TPL(className, T) \
196  template class className<T>; \
197  template class utl::TRunTimeClass<className<T>>; \
198  template class utl::TConcreteRunTimeClass<className<T>>;
199 
201 
206 #define UTL_INSTANTIATE_TPL2(className, T1, T2) \
207  UTL_CLASS_IMPL_NAME_TPL2(className, T1, T2) \
208  template class className<T1, T2>; \
209  template class utl::TRunTimeClass<className<T1, T2>>; \
210  template class utl::TConcreteRunTimeClass<className<T1, T2>>;
211 
213 
219 #define UTL_INSTANTIATE_TPLxTPL2(className, TC, T1, T2) \
220  UTL_CLASS_IMPL_NAME_TPLxTPL2(className, TC, T1, T2) template class className<TC<T1, T2>>; \
221  template class utl::TRunTimeClass<className<TC<T1, T2>>>; \
222  template class utl::TConcreteRunTimeClass<className<TC<T1, T2>>>;
223 
225 
231 #define UTL_EINTR_LOOP(SyscallFn) \
232  int err; \
233  for (;;) \
234  { \
235  err = SyscallFn; \
236  if ((err >= 0) || (errno != EINTR)) break; \
237  }
238 
240 
245 #define UTL_MAIN(appName) \
246  int main(int argc, char** argv) \
247  { \
248  appName* theApp = new appName; \
249  int res = 255; \
250  try \
251  { \
252  res = theApp->run(argc, argv); \
253  } \
254  catch (utl::Exception & ex) \
255  { \
256  ex.dump(utl::cerr); \
257  ex.setObject(nullptr); \
258  } \
259  delete theApp; \
260  return res; \
261  }
262 
264 
269 #if defined(DEBUG) && UTL_HOST_OS != UTL_OS_MINGW
270 #define UTL_MAIN_RL(appName) \
271  int main(int argc, char** argv) \
272  { \
273  appName* theApp = new appName; \
274  int res = 255; \
275  try \
276  { \
277  res = theApp->run(argc, argv); \
278  } \
279  catch (utl::Exception & ex) \
280  { \
281  ex.dump(utl::cerr); \
282  ex.setObject(nullptr); \
283  } \
284  delete theApp; \
285  utl::memReportLeaks(false); \
286  return res; \
287  }
288 #else
289 #define UTL_MAIN_RL(appName) UTL_MAIN(appName)
290 #endif
291 
293 
301 #define for_each_ln(head, var_type, var_name) \
302  { \
303  for (const ListNode* __ln = head; (__ln != nullptr) && !__ln->isSentinelTail(); \
304  __ln = __ln->next()) \
305  { \
306  utl::Object* __lnPtr = __ln->get(); \
307  ASSERTD(__lnPtr->isA(var_type)); \
308  var_type& var_name = *(var_type*)__lnPtr;
309 
311 
319 #define for_each_sln(head, var_type, var_name) \
320  { \
321  for (const SlistNode* __ln = head; (__ln != nullptr) && !__ln->isSentinelTail(); \
322  __ln = __ln->next()) \
323  { \
324  utl::Object* __lnPtr = __ln->get(); \
325  ASSERTD(__lnPtr->isA(var_type)); \
326  var_type& var_name = *(var_type*)__lnPtr;
327 
329 
334 #define for_each_end \
335  } \
336  }
337 
339 
344 #define UTL_CLASS_NO_COMPARE \
345 public: \
346  virtual int compare(const utl::Object&) const \
347  { \
348  ABORT(); \
349  return 0; \
350  }
351 
353 
358 #define UTL_CLASS_NO_COPY \
359 public: \
360  virtual void copy(const utl::Object&) \
361  { \
362  ABORT(); \
363  }
364 
366 
371 #define UTL_CLASS_NO_KEY(className) \
372 public: \
373  virtual const utl::Object& getKey() const \
374  { \
375  return *this; \
376  }
377 
379 
384 #define UTL_CLASS_NO_SERIALIZE \
385 public: \
386  virtual void serialize(utl::Stream&, uint_t, uint_t) \
387  { \
388  ABORT(); \
389  }
390 
392 
397 #define UTL_CLASS_NO_VCLONE \
398 public: \
399  virtual void vclone(const utl::Object&) \
400  { \
401  ABORT(); \
402  }
403 
405 
410 #define UTL_CLASS_TYPE(className) \
411 private: \
412  typedef className thisType;
413 
415 
420 #define UTL_CLASS_TYPE_TPL2(className, T1, T2) \
421 private: \
422  typedef className<T1, T2> thisType;
423 
425 
430 #define UTL_CLASS_SUPER(baseClassName) \
431 public: \
432  typedef baseClassName super;
433 
435 
440 #define UTL_CLASS_SUPER_TPL2(baseClassName, T1, T2) \
441 public: \
442  typedef baseClassName<T1, T2> super;
443 
445 
451 #define UTL_CLASS_SUPER_TPL2_TPLxTPL2(baseClassName, T, T1, T2) \
452 public: \
453  typedef baseClassName<T<T1, T2>> super;
454 
456 
461 #define UTL_CLASS_CONSTRUCT(className) \
462 public: \
463  className() \
464  { \
465  init(); \
466  }
467 
469 
474 #define UTL_CLASS_COPYCONSTRUCT(className) \
475 public: \
476  className(const thisType& rhs) \
477  { \
478  init(); \
479  this->vclone(rhs); \
480  }
481 
483 
488 #define UTL_CLASS_MOVECONSTRUCT(className) \
489 public: \
490  className(thisType&& rhs) noexcept \
491  { \
492  init(); \
493  this->steal(rhs); \
494  }
495 
497 
502 #ifdef DEBUG
503 #define UTL_SAFE_DEINIT \
504  SCOPE_FAIL \
505  { \
506  DIE("unexpected exception during object destruction"); \
507  }; \
508  deInit();
509 #else
510 #define UTL_SAFE_DEINIT deInit();
511 #endif
512 
514 
519 #define UTL_CLASS_DESTRUCT(className) \
520 public: \
521  virtual ~className() \
522  { \
523  UTL_SAFE_DEINIT; \
524  }
525 
527 
532 #define UTL_CLASS_DEFID \
533 private: \
534  void init() \
535  { \
536  } \
537  void deInit() \
538  { \
539  }
540 
542 
547 #define UTL_CLASS_DECL_CREATE \
548 public: \
549  virtual thisType* create() const;
550 
552 
557 #define UTL_CLASS_DECL_CLONE \
558 public: \
559  virtual thisType* clone() const;
560 
562 
567 #define UTL_CLASS_EQUALS(rhsClassName) \
568 public: \
569  thisType& operator=(const rhsClassName& rhs) \
570  { \
571  this->copy(rhs); \
572  return *this; \
573  }
574 
576 
581 #define UTL_CLASS_EQUALS_MOVE \
582 public: \
583  thisType& operator=(thisType&& rhs) noexcept \
584  { \
585  this->steal(rhs); \
586  return *this; \
587  }
588 
590 
595 #define UTL_CLASS_POINTER \
596 public: \
597  operator thisType*() \
598  { \
599  return this; \
600  }
601 
603 
608 #define UTL_CLASS_CONSTPOINTER \
609 public: \
610  operator const thisType*() const \
611  { \
612  return this; \
613  } \
614  operator const thisType*() \
615  { \
616  return this; \
617  }
618 
620 
625 #define UTL_CLASS_SERIALIZE(className) \
626  inline void serialize(className& object, Stream& stream, uint_t io, \
627  uint_t mode = utl::ser_default) \
628  { \
629  object.serialize(stream, io, mode); \
630  }
631 
633 
638 #define UTL_TYPE_NO_SERIALIZE(typeName) \
639  inline void serialize(typeName&, Stream&, uint_t, uint_t) \
640  { \
641  ABORT(); \
642  }
643 
645 
650 #define UTL_CLASS_DECL_ABC(DC, BC) \
651  UTL_CLASS_TYPE(DC) \
652  UTL_CLASS_SUPER(BC) \
653  UTL_CLASS_DECL_RTTI_ABC(DC) \
654  UTL_CLASS_CONSTRUCT(DC) \
655  UTL_CLASS_DESTRUCT(DC) \
656  UTL_CLASS_DECL_CREATE \
657  UTL_CLASS_DECL_CLONE \
658  UTL_CLASS_EQUALS(DC) \
659  UTL_CLASS_EQUALS_MOVE \
660  UTL_CLASS_POINTER \
661  UTL_CLASS_CONSTPOINTER
662 
664 
669 #define UTL_CLASS_DECL_CMN(DC) \
670  UTL_CLASS_CONSTRUCT(DC) \
671  UTL_CLASS_COPYCONSTRUCT(DC) \
672  UTL_CLASS_MOVECONSTRUCT(DC) \
673  UTL_CLASS_DESTRUCT(DC) \
674  UTL_CLASS_DECL_CREATE \
675  UTL_CLASS_DECL_CLONE \
676  UTL_CLASS_EQUALS(utl::Object) \
677  UTL_CLASS_EQUALS(thisType) \
678  UTL_CLASS_EQUALS_MOVE \
679  UTL_CLASS_POINTER \
680  UTL_CLASS_CONSTPOINTER
681 
683 
688 #define UTL_CLASS_DECL(DC, BC) \
689  UTL_CLASS_TYPE(DC) \
690  UTL_CLASS_SUPER(BC) \
691  UTL_CLASS_DECL_RTTI(DC) \
692  UTL_CLASS_DECL_CMN(DC)
693 
695 
701 #define UTL_CLASS_DECL_NT_TPL2(DC, BC, T1, T2) \
702  UTL_CLASS_TYPE(DC) \
703  UTL_CLASS_SUPER_TPL2(BC, T1, T2) \
704  UTL_CLASS_DECL_RTTI(DC) \
705  UTL_CLASS_DECL_CMN(DC)
706 
708 
713 #define UTL_CLASS_DECL_TPL(DC, T, BC) \
714  UTL_CLASS_TYPE(DC<T>) \
715  UTL_CLASS_SUPER(BC) \
716  UTL_CLASS_DECL_RTTI_TPL(DC, T) \
717  UTL_CLASS_DECL_CMN(DC)
718 
720 
726 #define UTL_CLASS_DECL_TPL2(DC, T1, T2, BC) \
727  UTL_CLASS_TYPE_TPL2(DC, T1, T2) \
728  UTL_CLASS_SUPER(BC) \
729  UTL_CLASS_DECL_RTTI_TPL2(DC, T1, T2) \
730  UTL_CLASS_DECL_CMN(DC)
731 
733 
739 #define UTL_CLASS_DECL_TPL2_TPL2(DC, DC_T1, DC_T2, BC, BC_T1, BC_T2) \
740  UTL_CLASS_TYPE_TPL2(DC, DC_T1, DC_T2) \
741  UTL_CLASS_SUPER_TPL2(BC, BC_T1, BC_T2) \
742  UTL_CLASS_DECL_RTTI_TPL2(DC, DC_T1, DC_T2) \
743  UTL_CLASS_DECL_CMN(DC)
744 
746 
753 #define UTL_CLASS_DECL_TPL2_TPLxTPL2(DC, DC_T1, DC_T2, BC, BC_BT, BC_T1, BC_T2) \
754 private: \
755  UTL_CLASS_TYPE_TPL2(DC, DC_T1, DC_T2) \
756  UTL_CLASS_SUPER_TPL2_TPLxTPL2(BC, BC_BT, BC_T1, BC_T2); \
757  UTL_CLASS_DECL_RTTI_TPL2(DC, DC_T1, DC_T2) \
758  UTL_CLASS_DECL_CMN(DC)
759 
761 
766 #define UTL_CLASS_IMPL_CREATE_ABC(className) \
767  className* className::create() const \
768  { \
769  ABORT(); \
770  return nullptr; \
771  }
772 
774 
779 #define UTL_CLASS_IMPL_CREATE(className) \
780  className* className::create() const \
781  { \
782  return new className(); \
783  }
784 
786 
791 #define UTL_CLASS_IMPL_CREATE_TPL(className, T) \
792  template <class T> \
793  className<T>* className<T>::create() const \
794  { \
795  return new className<T>(); \
796  }
797 
799 
804 #define UTL_CLASS_IMPL_CREATE_TPL2(className, T1, T2) \
805  template <class T1, class T2> \
806  className<T1, T2>* className<T1, T2>::create() const \
807  { \
808  return new className<T1, T2>(); \
809  }
810 
812 
817 #define UTL_CLASS_IMPL_CLONE_ABC(className) \
818  className* className::clone() const \
819  { \
820  ABORT(); \
821  return nullptr; \
822  }
823 
825 
830 #define UTL_CLASS_IMPL_CLONE(className) \
831  className* className::clone() const \
832  { \
833  auto object = new className(); \
834  object->vclone(*this); \
835  return object; \
836  }
837 
839 
844 #define UTL_CLASS_IMPL_CLONE_TPL(className, T) \
845  template <class T> \
846  className<T>* className<T>::clone() const \
847  { \
848  auto object = new className<T>(); \
849  object->vclone(*this); \
850  return object; \
851  }
852 
854 
859 #define UTL_CLASS_IMPL_CLONE_TPL2(className, T1, T2) \
860  template <class T1, class T2> \
861  className<T1, T2>* className<T1, T2>::clone() const \
862  { \
863  auto object = new className<T1, T2>(); \
864  object->vclone(*this); \
865  return object; \
866  }
867 
869 
874 #define UTL_CLASS_IMPL_ABC(className) \
875  UTL_CLASS_IMPL_NAME(className) \
876  UTL_CLASS_IMPL_RTTI_ABC(className) \
877  UTL_CLASS_IMPL_CREATE_ABC(className) \
878  UTL_CLASS_IMPL_CLONE_ABC(className) \
879  template const className& utl::cast<className>(const utl::Object&); \
880  template className& utl::cast<className>(utl::Object&); \
881  template const className* utl::cast<className>(const utl::Object*); \
882  template className* utl::cast<className>(utl::Object*);
883 
885 
890 #define UTL_CLASS_IMPL(className) \
891  UTL_CLASS_IMPL_NAME(className) \
892  UTL_CLASS_IMPL_RTTI(className) \
893  UTL_CLASS_IMPL_CREATE(className) \
894  UTL_CLASS_IMPL_CLONE(className) \
895  template const className& utl::cast<className>(const utl::Object&); \
896  template className& utl::cast<className>(utl::Object&); \
897  template const className* utl::cast<className>(const utl::Object*); \
898  template className* utl::cast<className>(utl::Object*);
899 
901 
906 #define UTL_CLASS_IMPL_TPL(className, T) \
907  UTL_CLASS_IMPL_RTTI_TPL(className, T) \
908  UTL_CLASS_IMPL_CREATE_TPL(className, T) \
909  UTL_CLASS_IMPL_CLONE_TPL(className, T)
910 
912 
917 #define UTL_CLASS_IMPL_TPL2(className, T1, T2) \
918  UTL_CLASS_IMPL_RTTI_TPL2(className, T1, T2) \
919  UTL_CLASS_IMPL_CREATE_TPL2(className, T1, T2) \
920  UTL_CLASS_IMPL_CLONE_TPL2(className, T1, T2)