Lumiera  0.pre.03
»edit your freedom«
scoped-holder-transfer-test.cpp
Go to the documentation of this file.
1 /*
2  ScopedHolderTransfer(Test) - managing noncopyable objects within a growing vector
3 
4  Copyright (C)
5  2008, 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 
20 #include "lib/test/run.hpp"
21 #include "lib/util.hpp"
22 
23 #include "lib/scoped-holder.hpp"
26 
27 #include <iostream>
28 #include <vector>
29 
30 
31 namespace lib {
32 namespace test {
33 
34  using ::Test;
35  using util::isnil;
36 
37  using std::vector;
38  using std::cout;
39 
40  namespace { // extending the Dummy for our special purpose....
41 
42  bool throw_in_transfer = false;
43 
44  class FixedDummy
45  : public Dummy
46  {
47  public:
48  FixedDummy()
49  {
50  TRACE (test, "CTOR FixedDummy() --> this=%p val=%d", this, getVal());
51  }
52 
53  ~FixedDummy()
54  {
55  TRACE (test, "DTOR ~FixedDummy() this=%p val=%d", this, getVal());
56  }
57 
58  friend void
59  transfer_control (FixedDummy& from, FixedDummy& to)
60  {
61  TRACE (test, "TRANSFER target=%p <-- source=%p (%d,%d)", &to,&from, to.getVal(),from.getVal());
62 
63  if (throw_in_transfer)
64  throw to.getVal();
65 
66  swap (from,to);
67  from.setVal(0); // remove the old Dummy from accounting (checksum)
68  }
69 
70  };
71 
72 
75 
76  template<class HOL>
77  struct Table
78  {
80  typedef typename std::vector<HOL,Allo> Type;
81 
82  };
83 
84  }//(End) test helpers
85 
86 
87 
88 
89 
90  /******************************************************************************/
97  class ScopedHolderTransfer_test : public Test
98  {
99 
100  virtual void
101  run (Arg)
102  {
103 
104  cout << "checking ScopedHolder<Dummy>...\n";
105  buildVector<HolderD>();
106  growVector<HolderD>();
107  checkErrorHandling<HolderD>();
108 
109  cout << "checking ScopedPtrHolder<Dummy>...\n";
110  buildVector<PtrHolderD>();
111  growVector<PtrHolderD>();
112  checkErrorHandling<PtrHolderD>();
113  }
114 
115  void create_contained_object (HolderD& holder) { holder.create(); }
116  void create_contained_object (PtrHolderD& holder) { holder.reset(new FixedDummy()); }
117 
118 
119  template<class HO>
120  void
121  buildVector()
122  {
123  CHECK (0 == Dummy::checksum());
124  {
125  typedef typename Table<HO>::Type Vect;
126 
127  Vect table(50);
128  CHECK (0 == Dummy::checksum());
129 
130  for (uint i=0; i<10; ++i)
131  create_contained_object (table[i]);
132 
133  CHECK (0 < Dummy::checksum());
134  CHECK ( table[9]);
135  CHECK (!table[10]);
136 
137  Dummy *rawP = table[5].get();
138  CHECK (rawP);
139  CHECK (table[5]);
140  CHECK (rawP == &(*table[5]));
141  CHECK (rawP->calc(-555) == table[5]->calc(-555));
142  }
143  CHECK (0 == Dummy::checksum());
144  }
145 
146 
147  template<class HO>
148  void
149  growVector()
150  {
151  CHECK (0 == Dummy::checksum());
152  {
153  typedef typename Table<HO>::Type Vect;
154 
155  Vect table;
156  table.reserve(2);
157  CHECK (0 == Dummy::checksum());
158 
159  cout << ".\n..install one element at index[0]\n";
160  table.push_back(HO());
161  CHECK (0 == Dummy::checksum());
162 
163  create_contained_object (table[0]); // switches into "managed" state
164  CHECK (0 < Dummy::checksum());
165  int theSum = Dummy::checksum();
166 
167  cout << ".\n..*** resize table to 16 elements\n";
168  for (uint i=0; i<15; ++i)
169  table.push_back(HO());
170 
171  CHECK (theSum == Dummy::checksum());
172  }
173  CHECK (0 == Dummy::checksum());
174  }
175 
176 
177  template<class HO>
178  void
179  checkErrorHandling()
180  {
181  CHECK (0 == Dummy::checksum());
182  {
183  typedef typename Table<HO>::Type Vect;
184 
185  Vect table(5);
186  table.reserve(5);
187  CHECK (0 == Dummy::checksum());
188 
189  create_contained_object (table[2]);
190  create_contained_object (table[4]);
191  CHECK (0 < Dummy::checksum());
192  int theSum = Dummy::checksum();
193 
194  cout << ".\n.throw some exceptions...\n";
195  Dummy::activateCtorFailure();
196  try
197  {
198  create_contained_object (table[3]);
199  NOTREACHED ("ctor should throw");
200  }
201  catch (int val)
202  {
203  CHECK (theSum < Dummy::checksum());
204  Dummy::checksum() -= val;
205  CHECK (theSum == Dummy::checksum());
206  }
207  CHECK ( table[2]);
208  CHECK (!table[3]); // not created because of exception
209  CHECK ( table[4]);
210 
211  Dummy::activateCtorFailure(false);
212  throw_in_transfer=true; // can do this only when using ScopedHolder
213  try
214  {
215  table.resize(10);
216  }
217  catch (int val)
218  {
219  CHECK ( table.size() < 10);
220  }
221  CHECK (theSum == Dummy::checksum());
222  throw_in_transfer=false;
223  }
224  CHECK (0 == Dummy::checksum());
225  }
226 
227  };
228 
229  LAUNCHER (ScopedHolderTransfer_test, "unit common");
230 
231 
232 }} // namespace lib::test
Some wrappers for coping with ownership problems.
Definition: run.hpp:40
virtual long calc(int i)
a dummy API operation
Implementation namespace for support and library code.
A mechanism to take ownership without allowing copy.
Addendum to scoped-holder.hpp for transferring the lifecycle management to another instance...
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Inline buffer holding and owning an object similar to unique_ptr.
unittest helper code: test dummy objects to track instances.
A Dummy object for tests.
Extension to std::unique_ptr, allowing copy operations on empty pointers (i.e.