PageRenderTime 30ms CodeModel.GetById 10ms app.highlight 16ms RepoModel.GetById 2ms app.codeStats 0ms

/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
  4#include <iosfwd>
  5#include <new>
  6
  7namespace tracked
  8{
  9  namespace detail
 10  {
 11    class Tracked
 12    {
 13      protected:
 14
 15        Tracked();
 16        Tracked(Tracked const &);
 17        #if __cplusplus >= 201103
 18        Tracked(Tracked &&);
 19        #endif
 20
 21        void operator=(Tracked const &);
 22        #if __cplusplus >= 201103
 23        void operator=(Tracked &&);
 24        #endif
 25
 26        ~Tracked();
 27
 28        void set_name(char const *) const;
 29    };
 30  }
 31
 32  void mute(); void unmute();
 33
 34  namespace detail
 35  {
 36    /* 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:
 37
 38      geordi { mute(); ..foo.. unmute(); ..bar.. mute(); ..bas.. }
 39
 40    We therefore introduce some trickery to let us write the above as:
 41
 42      geordi { ..foo.. TRACK{ ..bar.. } ..bas.. }
 43
 44    */
 45
 46    template <typename>
 47    class focus_t {
 48      struct mute_in_ctor { mute_in_ctor() { mute(); } };
 49      static mute_in_ctor m;
 50      public:
 51        focus_t() { m; unmute(); }
 52          // 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.
 53        ~focus_t() { mute(); }
 54        operator bool() const { return false; }
 55    };
 56
 57    template <typename T> typename focus_t<T>::mute_in_ctor focus_t<T>::m;
 58
 59  } // namespace detail
 60
 61  #define TRACK \
 62    if(::tracked::detail::focus_t<void> const & tracked_detail_focus = ::tracked::detail::focus_t<void>()) ; else
 63
 64  struct B: protected detail::Tracked
 65  {
 66    B();
 67    B(B const &);
 68    #if __cplusplus >= 201103
 69    B(B &&);
 70    #endif
 71
 72    B & operator=(B const &);
 73    #if __cplusplus >= 201103
 74    B & operator=(B &&);
 75    #endif
 76    virtual ~B();
 77
 78    void * operator new(std::size_t);
 79    void * operator new[](std::size_t);
 80    #if __cplusplus >= 201103
 81    void * operator new(std::size_t, std::nothrow_t const &) throw();
 82    void * operator new[](std::size_t, std::nothrow_t const &) throw();
 83    #endif
 84    void * operator new(std::size_t const, void * const p) throw() { return p; }
 85    void * operator new[](std::size_t const, void * const p) throw() { return p; }
 86    void operator delete(void *, std::size_t) throw();
 87    void operator delete[](void *, std::size_t) throw();
 88
 89    void f() const;
 90    virtual void vf() const;
 91
 92    B & operator++();
 93    B operator++(int);
 94
 95    void operator*() const;
 96
 97    template<typename C, typename Tr>
 98    friend std::basic_ostream<C, Tr> & operator<<(std::basic_ostream<C, Tr> &, B const &);
 99
100    private:
101      template<typename C, typename Tr> void print(std::basic_ostream<C, Tr> &) const;
102  };
103
104  bool operator<(B const &, B const &);
105  bool operator==(B const &, B const &);
106  inline bool operator<=(B const & x, B const & y) { return x == y || x < y; }
107  inline bool operator>(B const & x, B const & y) { return y < x; }
108  inline bool operator>=(B const & x, B const & y) { return y <= x; }
109  inline bool operator!=(B const & x, B const & y) { return !(x == y); }
110
111  struct D: B
112  {
113    D();
114    D(D const &);
115    #if __cplusplus >= 201103
116    D(D &&);
117    #endif
118
119    D & operator=(D const &);
120    #if __cplusplus >= 201103
121    D & operator=(D &&);
122    #endif
123    ~D();
124
125    void * operator new(std::size_t);
126    void * operator new[](std::size_t);
127    #if __cplusplus >= 201103
128    void * operator new(std::size_t, std::nothrow_t const &) throw();
129    void * operator new[](std::size_t, std::nothrow_t const &) throw();
130    #endif
131    void * operator new(std::size_t const, void * const p) throw() { return p; }
132    void * operator new[](std::size_t const, void * const p) throw() { return p; }
133    void operator delete(void *, std::size_t) throw();
134    void operator delete[](void *, std::size_t) throw();
135    void operator delete(void *) throw() {}
136
137    void f() const;
138    virtual void vf() const;
139
140    template<typename C, typename Tr>
141    friend std::basic_ostream<C, Tr> & operator<<(std::basic_ostream<C, Tr> &, D const &);
142
143    private:
144      template<typename C, typename Tr> void print(std::basic_ostream<C, Tr> &) const;
145  };
146
147} // namespace tracked
148
149#endif // header guard