Lumiera  0.pre.03
»edit your freedom«
del-stash.hpp
Go to the documentation of this file.
1 /*
2  DEL-STASH.hpp - collect and execute deleter functions
3 
4  Copyright (C)
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
34 #ifndef LIB_DEL_STASH_H
35 #define LIB_DEL_STASH_H
36 
37 
38 #include "lib/error.hpp"
39 #include "lib/symbol.hpp"
40 #include "lib/nocopy.hpp"
41 
42 #include <algorithm>
43 #include <vector>
44 
45 
46 namespace lib {
47 
48 
56  class DelStash
58  {
59 
60  typedef void KillFun(void*);
61 
66  class Killer
67  {
68  void* target_;
69  KillFun* killIt_;
70 
71  public:
72  Killer(KillFun* f, void* t)
73  : target_{t}
74  , killIt_{f}
75  {
76  REQUIRE(f);
77  }
78 
79  void
80  trigger()
81  {
82  if (target_)
83  killIt_(target_);
84  target_ = NULL; // remember kill
85  }
86 
87  bool operator== (const void* target) const { return target_ == target; }
88  bool operator!= (const void* target) const { return target_ != target; }
89 
90  bool
91  isActive() const
92  {
93  return bool(target_);
94  }
95  };
96 
97 
98  typedef std::vector<Killer> Killers;
99 
100  Killers killers_;
101 
102 
103  public:
104  DelStash (size_t elms_to_reserve =0)
105  : killers_()
106  {
107  if (elms_to_reserve)
108  {
109  killers_.reserve (elms_to_reserve);
110  }
111  }
112 
113  ~DelStash ()
114  try { killAll(); }
115 
116  catch(...)
117  {
118  Symbol errID = lumiera_error();
119  WARN (memory, "Problems on de-allocation: %s", errID.c());
120  }
121 
122 
123  size_t
124  size () const
125  {
126  size_t activeEntries = 0;
127  size_t i = killers_.size();
128  while (i)
129  if (killers_[--i].isActive())
130  ++activeEntries;
131  return activeEntries;
132  }
133 
134 
135 
136  template<typename TY>
137  void
138  manage (TY* obj)//, __disable_if_voidPtr<TY> =0)
139  {
140  if (!obj) return;
141  REQUIRE (!isRegistered (obj));
142  killers_.push_back (Killer (how_to_kill<TY>, obj));
143  }
144 
145  template<typename TY>
146  void
147  manage (TY& obj)//, __disable_if_voidPtr<TY> =0)
148  {
149  REQUIRE (!isRegistered (&obj));
150  killers_.push_back (Killer (how_to_kill<TY>, &obj));
151  }
152 
153  void
154  manage (void* obj, KillFun* customDeleter)
155  {
156  if (!obj) return;
157  REQUIRE (!isRegistered (obj));
158  killers_.push_back (Killer (customDeleter, obj));
159  }
160 
161 
162  template<typename TY>
163  void
164  kill (TY* obj)
165  {
166  triggerKill (obj);
167  } // note: entry remains in the killer vector,
168  // but is disabled and can't be found anymore
169 
170  template<typename TY>
171  void
172  kill (TY& obj)
173  {
174  triggerKill (&obj);
175  }
176 
177  void
178  killAll ()
179  {
180  size_t i = killers_.size();
181  while (i)
182  killers_[--i].trigger();
183  }
184 
185 
186  private:
189  template<typename X>
190  static void
191  how_to_kill (void* subject)
192  {
193  X* victim = static_cast<X*> (subject);
194  ENSURE (victim);
195  delete victim;
196  };
197 
198  bool
199  isRegistered (const void* objAddress)
200  {
201  REQUIRE (objAddress);
202  return killers_.end() != findEntry (objAddress);
203  }
204 
205  Killers::iterator
206  findEntry (const void* obj)
207  {
208  REQUIRE (obj);
209  return std::find (killers_.begin(),killers_.end(), obj);
210  }
211 
212  void
213  triggerKill (void* objAddress)
214  {
215  Killers::iterator pos = findEntry (objAddress);
216  if (killers_.end() != pos)
217  pos->trigger();
218  ENSURE (!isRegistered (objAddress), "duplicate deleter registration");
219  }
220  };
221 
222 
223 
224 
225 } // namespace lib
226 #endif
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
Implementation namespace for support and library code.
Token or Atom with distinct identity.
Definition: symbol.hpp:117
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Marker types to indicate a literal string and a Symbol.
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:115
Manage a collection of deleter functions.
Definition: del-stash.hpp:56
Lumiera error handling (C++ interface).
static void how_to_kill(void *subject)
trampoline function to invoke destructor of the specific target type
Definition: del-stash.hpp:191