/prelude/tracked.hpp

http://github.com/Eelis/geordi · C++ Header · 149 lines · 110 code · 29 blank · 10 comment · 4 complexity · 32dc99bb995d1bca3ece17b2e53a245b MD5 · raw file

  1. #ifndef TRACKED_HPP
  2. #define TRACKED_HPP
  3. #include <iosfwd>
  4. #include <new>
  5. namespace tracked
  6. {
  7. namespace detail
  8. {
  9. class Tracked
  10. {
  11. protected:
  12. Tracked();
  13. Tracked(Tracked const &);
  14. #if __cplusplus >= 201103
  15. Tracked(Tracked &&);
  16. #endif
  17. void operator=(Tracked const &);
  18. #if __cplusplus >= 201103
  19. void operator=(Tracked &&);
  20. #endif
  21. ~Tracked();
  22. void set_name(char const *) const;
  23. };
  24. }
  25. void mute(); void unmute();
  26. namespace detail
  27. {
  28. /* mute/unmute allow us to suppress boring messages that are not relevant to the issue under consideration. Their use can be a bit tedious though. If we only want to get messages for a few statements inside a statement block, we have to do something like:
  29. geordi { mute(); ..foo.. unmute(); ..bar.. mute(); ..bas.. }
  30. We therefore introduce some trickery to let us write the above as:
  31. geordi { ..foo.. TRACK{ ..bar.. } ..bas.. }
  32. */
  33. template <typename>
  34. class focus_t {
  35. struct mute_in_ctor { mute_in_ctor() { mute(); } };
  36. static mute_in_ctor m;
  37. public:
  38. focus_t() { m; unmute(); }
  39. // Mentioning m forces it to exist, but only if the focus_t template is ever instantiated. The effect is that if TRACK (which instantiates focus_t) is ever used, mute() will be called before main() is entered.
  40. ~focus_t() { mute(); }
  41. operator bool() const { return false; }
  42. };
  43. template <typename T> typename focus_t<T>::mute_in_ctor focus_t<T>::m;
  44. } // namespace detail
  45. #define TRACK \
  46. if(::tracked::detail::focus_t<void> const & tracked_detail_focus = ::tracked::detail::focus_t<void>()) ; else
  47. struct B: protected detail::Tracked
  48. {
  49. B();
  50. B(B const &);
  51. #if __cplusplus >= 201103
  52. B(B &&);
  53. #endif
  54. B & operator=(B const &);
  55. #if __cplusplus >= 201103
  56. B & operator=(B &&);
  57. #endif
  58. virtual ~B();
  59. void * operator new(std::size_t);
  60. void * operator new[](std::size_t);
  61. #if __cplusplus >= 201103
  62. void * operator new(std::size_t, std::nothrow_t const &) throw();
  63. void * operator new[](std::size_t, std::nothrow_t const &) throw();
  64. #endif
  65. void * operator new(std::size_t const, void * const p) throw() { return p; }
  66. void * operator new[](std::size_t const, void * const p) throw() { return p; }
  67. void operator delete(void *, std::size_t) throw();
  68. void operator delete[](void *, std::size_t) throw();
  69. void f() const;
  70. virtual void vf() const;
  71. B & operator++();
  72. B operator++(int);
  73. void operator*() const;
  74. template<typename C, typename Tr>
  75. friend std::basic_ostream<C, Tr> & operator<<(std::basic_ostream<C, Tr> &, B const &);
  76. private:
  77. template<typename C, typename Tr> void print(std::basic_ostream<C, Tr> &) const;
  78. };
  79. bool operator<(B const &, B const &);
  80. bool operator==(B const &, B const &);
  81. inline bool operator<=(B const & x, B const & y) { return x == y || x < y; }
  82. inline bool operator>(B const & x, B const & y) { return y < x; }
  83. inline bool operator>=(B const & x, B const & y) { return y <= x; }
  84. inline bool operator!=(B const & x, B const & y) { return !(x == y); }
  85. struct D: B
  86. {
  87. D();
  88. D(D const &);
  89. #if __cplusplus >= 201103
  90. D(D &&);
  91. #endif
  92. D & operator=(D const &);
  93. #if __cplusplus >= 201103
  94. D & operator=(D &&);
  95. #endif
  96. ~D();
  97. void * operator new(std::size_t);
  98. void * operator new[](std::size_t);
  99. #if __cplusplus >= 201103
  100. void * operator new(std::size_t, std::nothrow_t const &) throw();
  101. void * operator new[](std::size_t, std::nothrow_t const &) throw();
  102. #endif
  103. void * operator new(std::size_t const, void * const p) throw() { return p; }
  104. void * operator new[](std::size_t const, void * const p) throw() { return p; }
  105. void operator delete(void *, std::size_t) throw();
  106. void operator delete[](void *, std::size_t) throw();
  107. void operator delete(void *) throw() {}
  108. void f() const;
  109. virtual void vf() const;
  110. template<typename C, typename Tr>
  111. friend std::basic_ostream<C, Tr> & operator<<(std::basic_ostream<C, Tr> &, D const &);
  112. private:
  113. template<typename C, typename Tr> void print(std::basic_ostream<C, Tr> &) const;
  114. };
  115. } // namespace tracked
  116. #endif // header guard