Lumiera  0.pre.03
»edit your freedom«
del-stash-test.cpp
Go to the documentation of this file.
1 /*
2  DelStash(Test) - verify a facility to memorise and trigger deleter functions
3 
4  Copyright (C) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/del-stash.hpp"
30 
31 #include <cstdlib>
32 
33 
34 
35 namespace lib {
36 namespace test{
37 
38  using std::rand;
39 
40 
41 
42  namespace { // probe victims
43 
44  ulong MAX_MASS = 200; // number of victims to kill at once
45 
46  ulong checksum = 0;
47 
48 
49  template<uint siz>
50  class Probe
51  {
52  uint mySiz_;
53  char myCrap_[siz];
54 
55  public:
56  Probe()
57  : mySiz_(siz)
58  {
59  REQUIRE (siz);
60  for (uint i=0; i<siz; ++i)
61  {
62  char c (rand() % 256);
63  checksum += c;
64  myCrap_[i] = c;
65  }
66  }
67 
68  ~Probe()
69  {
70  CHECK (siz == mySiz_, "using wrong type information for de-allocation");
71  for (uint i=0; i<siz; ++i)
72  checksum -= myCrap_[i];
73  }
74  };
75 
76 
77  template<uint x>
78  inline Probe<x>*
79  makeViktim ()
80  {
81  return new Probe<x>();
82  }
83 
84  template<uint x>
85  inline void
86  feedViktim (DelStash& killer)
87  {
88  killer.manage (new Probe<x>());
89  }
90 
91 
92  }//(End) test data
93 
94 
95 
96 
97  /************************************************************************/
107  class DelStash_test : public Test
108  {
109 
110  virtual void
111  run (Arg)
112  {
113  checksum = 0;
114  checkSingleKill();
115  checkCustomKill();
116  checkMassKill();
117  checkAutoKill();
118  }
119 
120 
121  void
122  checkSingleKill ()
123  {
124  DelStash killer;
125  CHECK (0 == killer.size());
126 
127  killer.manage<short> (NULL);
128  CHECK (0 == killer.size());
129 
130  Probe<5> *p = makeViktim<5>();
131  Probe<7> &r = *makeViktim<7>();
132  void *v = makeViktim<9>();
133  CHECK (0 < checksum);
134 
135  killer.manage (p);
136  killer.manage (r);
137  killer.manage (static_cast<Probe<9>*> (v));
138 
139  CHECK (3 == killer.size());
140 
141  killer.kill (r);
142  CHECK (2 == killer.size());
143 
144  killer.kill (p);
145  CHECK (1 == killer.size());
146 
147  killer.kill (p);
148  CHECK (1 == killer.size()); // spurious kill requests ignored
149 
150  killer.kill (v);
151  CHECK (0 == killer.size());
152  CHECK (0 == checksum);
153  }
154 
155 
156  void
157  feedViktims (DelStash& killer)
158  {
159  for (uint i=1; i <= MAX_MASS; ++i)
160  switch (i% 5) {
161  case 0: feedViktim<12> (killer); break;
162  case 1: feedViktim<23> (killer); break;
163  case 2: feedViktim<34> (killer); break;
164  case 3: feedViktim<45> (killer); break;
165  case 4: feedViktim<56> (killer); break;
166  }
167  }
168 
169 
170  void
171  checkMassKill ()
172  {
173  DelStash killer;
174  CHECK (0 == killer.size());
175 
176  CHECK (0 == checksum);
177  CHECK (0 == killer.size());
178 
179  feedViktims (killer);
180  CHECK (MAX_MASS == killer.size());
181 
182  killer.killAll();
183  CHECK (0 == killer.size());
184  CHECK (0 == checksum);
185  }
186 
187 
188  void
189  checkAutoKill()
190  {
191  {
192  DelStash killer;
193  CHECK (0 == killer.size());
194  CHECK (0 == checksum);
195 
196  feedViktims (killer);
197  Probe<444> * individuum = makeViktim<444>();
198  killer.manage (individuum);
199  feedViktims (killer);
200  killer.manage (makeViktim<5555>());
201  feedViktims (killer);
202 
203  CHECK (3*MAX_MASS + 2 == killer.size());
204 
205  killer.kill(individuum);
206  CHECK (3*MAX_MASS + 1 == killer.size());
207 
208  CHECK (0 < checksum);
209  }// killer going out of scope...
210 
211  CHECK (0 == checksum);
212  }
213 
214 
218  void
220  {
221  DelStash killer;
222  CHECK (0 == killer.size());
223 
229  class Special
230  : Probe<555>
231  {
232  char secret_;
233 
234  public:
235  Special()
236  : Probe<555>()
237  , secret_('a' + (rand() % (1+'z'-'a')))
238  {
239  checksum += secret_;
240  }
241 
242  static void
243  selfKill (void *it)
244  {
245  Special *self = static_cast<Special*> (it);
246  checksum -= self->secret_;
247  delete self;
248  }
249  };
250 
251 
252  void * type_erased = new Special();
253  CHECK (0 < checksum);
254 
255  killer.manage (type_erased, &Special::selfKill);
256  CHECK (1 == killer.size());
257 
258  killer.kill(type_erased);
259  CHECK (0 == killer.size());
260  CHECK (0 == checksum);
261  }
262  };
263 
264 
266  LAUNCHER (DelStash_test, "unit common");
267 
268 
269 }} // namespace lib::test
Definition: run.hpp:49
Collecting and finally triggering deleter functions.
Implementation namespace for support and library code.
Simple test class runner.
Manage a collection of deleter functions.
Definition: del-stash.hpp:65