Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TestSharedPtr.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 /**
26  @file TestShardesPtr.cpp
27  @relates SharedPtr
28  @brief Test usage of shared pointers
29  @ingroup g_tests
30  @author woelk
31 */
32 
33 #include <Base/Common/SharedPtr.hh>
34 
35 #include <iostream>
36 #include <vector>
37 
38 using namespace BIAS;
39 using namespace std;
40 
41 
42 const bool verbose = false;
43 
44 /** \cond POORLY_NAMED_TEST_CLASSES **/
45 /* some parent*/
46 class parent
47 {
48 public:
49  parent() : data(0.0) {}
50  parent(const double d) : data(d) {}
51  virtual ~parent() {}
52  double data;
53  virtual void printData()
54  { cout << "parent::printData: "<<data<<endl; }
55 };
56 
57 /* comse child */
58 class child : public parent
59 {
60 public:
61  child() : parent() {}
62  child(const double d) : parent(d) {}
63  virtual ~child() {}
64  virtual void printData()
65  { cout << "child::printData: "<<data<<endl; }
66 };
67 
68 
69 ostream& operator<<(ostream& os, const parent & f)
70 { os << "parent = "<<f.data; return os; }
71 
72 
73 ostream& operator<<(ostream& os, const child & f)
74 { os << "child = "<<f.data; return os; }
75 
76 
77 
78 // compile tests
79 void TestConstructors()
80 {
81  SharedPtr<parent> empty;
82  SharedPtr<parent> empty2(empty);
83  SharedPtr<parent> filled(new parent);
84  SharedPtr<parent> filled2(filled);
85  SharedPtr<parent> equal = filled;
86 
87 #ifdef TEST_COMPILE_TIME_ERROR_Delete
88  delete equal; // does not compile, this should never be possible
89 #endif
90 }
91 
92 
93 // compile tests
94 void TestAccess()
95 {
96  const double value(2.0);
97  SharedPtr<parent> sp(new parent(value));
98  if ((*sp).data != value) { BIASABORT; }
99  if (sp->data != value) { BIASABORT; }
100  if (verbose) {
101  cout << "Get: "<<Get(sp)<<endl;
102  cout << "RefCount: "<<RefCount(sp)<<endl;
103  }
104 
105  SharedPtr<int> foo(NULL);
106  if (verbose) cout << foo << "\t" << foo << " rc "<<RefCount(foo)<<endl;
107  foo = SharedPtr<int>(new int);
108  if (verbose) cout << foo << "\t" << *foo << " rc "<<RefCount(foo)<<endl;
109  *foo += 2;
110  if (verbose) cout << foo << "\t" << *foo << " rc "<<RefCount(foo)<<endl;
111 }
112 
113 
114 // compile tests
115 void TestConversionToBool()
116 {
117  // create two SharedPtr , one filled and the other empty
118  SharedPtr<parent> parent1, parent2(new parent);
119 
120  // test if(ptr)
121  if (parent1){ BIASABORT; }
122  if (parent2){} else { BIASABORT; }
123 
124  // test if (!ptr)
125  if (!parent1){} else { BIASABORT; }
126  if (!parent2){ BIASABORT; }
127 }
128 
129 
130 void TestComparison()
131 {
132  parent *raw_1 = new parent(1.0);
133  parent *raw_2 = new parent(2.0);
134 
135  child *raw_child = new child(3.0);
136 
137  SharedPtr<parent> shared_1(raw_1), shared_2(raw_2);
138  SharedPtr<parent> shared_1b(shared_1), shared_2b(shared_2);
139  SharedPtr<parent> shared_parent_from_raw_child(raw_child);
140 
141  SharedPtr<int> shared_int(new int);
142 
143  // comparison of shared pointers
144  if (shared_1 == shared_1b) {} else { BIASABORT; }
145  if (shared_1 != shared_1b) { BIASABORT; }
146  if (shared_1 == shared_2) { BIASABORT; }
147  if (shared_1 != shared_2) {} else { BIASABORT; }
148 
149  // comparison to raw pointers is done on raw pointer basis
150  if (raw_1 == Get(shared_1)) {} else { BIASABORT; }
151  if (raw_1 != Get(shared_1)) { BIASABORT; }
152 
153  // comparison between apples and oranges, compiler error
154 #ifdef TEST_COMPILE_TIME_ERROR_CompareApplesAnOrangesEqual
155  if (shared_int == shared_1) { BIASABORT; }
156 #endif
157 #ifdef TEST_COMPILE_TIME_ERROR_CompareApplesAnOrangesNotEqual
158  if (shared_int != shared_1) {} else { BIASABORT; }
159 #endif
160 
161  // no need to cleanup, the shared pointer take care of it
162 }
163 
164 
165 void TestSorting()
166 {
167  SharedPtr<int> ptr1(new int(1));
168  SharedPtr<int> ptr2(new int(2));
169 
170  // comparing the pointers
171  if (Get(ptr1)==Get(ptr2)){ BIASABORT; }
172  if (Get(ptr1)<Get(ptr2)){
173  if (!(ptr1<ptr2)) { BIASABORT; }
174  if (ptr1>=ptr2) { BIASABORT; }
175  } else {
176  if (!(ptr1>ptr2)) { BIASABORT; }
177  if (ptr1<=ptr2) { BIASABORT; }
178  }
179 
180  // comparing the values
181  if (*ptr1>=*ptr2) { BIASABORT; }
182 }
183 
184 
185 void TestReferenceCounting()
186 {
187  SharedPtr<int> ptr1;
188  // new scope to test reference counting
189  {
190  SharedPtr<int> ptr2(new int);
191  if (verbose) cout << "reference count is "<<RefCount(ptr2)<<" expected 1\n";
192  if (RefCount(ptr2)!=1u) { BIASABORT; }
193  // assign reference ptr2 to ptr1 should increas ereference counter
194  ptr1 = ptr2;
195  if (RefCount(ptr2)!=2u) { BIASABORT; }
196  if (RefCount(ptr1)!=2u) { BIASABORT; }
197  // copy constructor should increase reference counter
198  SharedPtr<int> ptr3(ptr1);
199  if (RefCount(ptr2)!=3u) { BIASABORT; }
200  if (RefCount(ptr1)!=3u) { BIASABORT; }
201  }
202  // ptr2 and ptr 3 have left their scope and desctructors should have been
203  // executed, resulting in a reference count of 1
204  if (RefCount(ptr1)!=1u) { BIASABORT; }
205 }
206 
207 
208 
209 void TestStream()
210 {
211  SharedPtr<int> ptr1(new int(2));
212  cout << "ptr1: "<<ptr1<<" = "<<*ptr1<<endl;
213  SharedPtr<int> ptr2;
214  cout << "ptr2: "<<ptr2<<endl;
215 }
216 
217 
218 void TestConst()
219 {
220  // can do anything with variabel pointer to variable value
221  SharedPtr<int> var(new int(2));
222  *var = 3;
223  var = SharedPtr<int>(new int(5));
224 
225  // variable pointer to const value
226  SharedPtr<const int> var_ptr_2_const(new int(2));
227  var_ptr_2_const = SharedPtr<int>(new int(7)); // allowed, can change ptr
228 #ifdef TEST_COMPILE_TIME_ERROR_DereferencePtr2Const
229  // dereferencing a ptr to const is not allowed
230  *var_ptr_2_const = 8; // compiler error, not allowed
231 #endif
232 
233  // const pointer to variable value
234  const SharedPtr<int> const_ptr_2_var(new int(2));
235 #ifdef TEST_COMPILE_TIME_ERROR_InitFromGenericPointer
236  // initializiation without explicit cast to SharedPtr is not allowed
237  const_ptr_2_var = new int(7); // compiler error, not allowed
238 #endif
239  *const_ptr_2_var = 8; // allowed, can change value
240 
241  // const pointer to const value
242  const SharedPtr<const int> const_ptr_2_const(new int(2));
243 #ifdef TEST_COMPILE_TIME_ERROR_InitFromGenericPointerConst
244  // assignemnt of const ptr to const value only allowed in constructor
245  const_ptr_2_const = new int(6); // compiler error, not allowed
246 #endif
247 #ifdef TEST_COMPILE_TIME_ERROR_DereferenceConstPtr2Const
248  // cannot dereference conmst ptr to const value
249  *const_ptr_2_const = 7; // compiler error, not allowed
250 #endif
251 
252  // assignment of a pointer to a changeable to a pointer to const
253  SharedPtr<const int> foo(var);
254  SharedPtr<const int> foo2 = var;
255 
256 #ifdef TEST_COMPILE_TIME_ERROR_ConstCast
257  // compiler error, try to cast away constness
258  SharedPtr<int> foo2(var_ptr_2_const);
259 #endif
260 }
261 
262 
263 void TestSTL()
264 {
265  std::vector<SharedPtr<int> > vec(1);
266  SharedPtr<int> foo = SharedPtr<int>(new int(3));
267  vec.push_back(foo);
268  vec.push_back(foo);
269  if (verbose) {
270  for (unsigned i=0; i<vec.size(); i++){
271  cout << i << ": "<<(vec[i])<<"\tref count: "<<RefCount(vec[i])<<endl;
272  }
273  }
274  std::vector<SharedPtr<int> > vec2(5, foo);
275  foo = SharedPtr<int>(NULL);
276  if (verbose) {
277  for (unsigned i=0; i<vec2.size(); i++){
278  cout << i << ": "<<(vec2[i])<<"\tref count: "<<RefCount(vec2[i])<<endl;
279  }
280  }
281 }
282 
283 
284 /* needed for TestCast */
285 class Father {
286 public:
287  virtual double get() {return a;}
288  virtual ~Father(){}
289 protected:
290  double a;
291 };
292 
293 /* child */
294 class Child : public Father {
295 public:
296  virtual double get() {return b;}
297  virtual ~Child(){}
298  double b;
299 };
300 
301 /* child2 */
302 class Child2 : public Father {
303 public:
304  virtual double get() {return c;}
305  virtual ~Child2(){}
306  double c;
307 };
308 
309 void TestCast()
310 {
311  SharedPtr<Father> f = SharedPtr<Father>(new Father), f2;
312  SharedPtr<Child> c = SharedPtr<Child>(new Child), c2;
313  SharedPtr<Child2> cc = SharedPtr<Child2>(new Child2);
314 
315  /// this cast succeeds
316  f2 = DynamicCast<Father>(c);
317  if (f2) {} else { BIASABORT; }
318  /// this cast fails
319  c2 = DynamicCast<Child>(cc);
320  if (c2) { BIASABORT; }
321 
322  if (verbose) {
323  cout << "ref count cast f2: "<<RefCount(f2)<<" (expected 2)"<<endl;
324  cout << "ref count cast c : "<<RefCount(c) <<" (expected 2)"<<endl;
325  cout << "ref count cast f : "<<RefCount(f) <<" (expected 1)"<<endl;
326  cout << "ref count cast c2: "<<RefCount(c2)<<" (expected 0)"<<endl;
327  cout << "ref count cast c : "<<RefCount(cc)<<" (expected 1)"<<endl;
328  }
329 
331  // should be successfull
332  f2 = ConstCast<Father>(f3);
333  if (f2) {} else { BIASABORT; };
334  f3 = ConstCast<const Father>(f);
335  if (f3) {} else { BIASABORT; };
336 
337 #ifdef TEST_COMPILE_TIME_ERROR_ConstCastTypeMismatch
338  // type mismatch: fails, compile time error
339  f2 = ConstCast<Father>(c);
340 #endif
341 
342 }
343 
344 void TestAutomaticCast()
345 {
346  SharedPtr<Father> father;
347  SharedPtr<const Father> const_father;
348  SharedPtr<Child> child = SharedPtr<Child>(new Child);
349  SharedPtr<const Child> const_child = SharedPtr<const Child>(new Child);
350 
351  father = child;
352  const_father = child;
353  const_father = const_child;
354 
355 #ifdef TEST_COMPILE_TIME_ERROR_AutocastConst
356  child = const_father;
357 #endif
358 }
359 /** \endcond **/
360 
361 int main()
362 {
363  TestConstructors();
364  TestAccess();
365  TestConversionToBool();
366  TestComparison();
367  TestSorting();
368  TestReferenceCounting();
369  TestStream();
370  TestConst();
371  TestSTL();
372  TestCast();
373  TestAutomaticCast();
374 
375  return 0;
376 }
T * Get(SharedPtr< T > &t)
pointer with reference count and automatic deletion
Definition: SharedPtr.hh:50
unsigned RefCount(const SharedPtr< T > &t)
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
Definition: Array2D.hh:260