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