testShadowPtr.cc
Go to the documentation of this file.
1 
11 #include <iostream>
12 #include <vector>
13 #include <cppunit/extensions/HelperMacros.h>
14 #include <tst/Verify.h>
15 #include <utl/CountedObject.h>
16 #include <utl/CountedObjectRegistry.h>
17 #include <utl/ShadowPtr.h>
18 
19 using namespace utl;
20 using namespace tst;
21 
22 #define ASSERT_OBJECT_COUNTS(o, c, d, e) \
23  CPPUNIT_ASSERT(utl::CountedObject<o>::GetObjectsCreated() == c); \
24  CPPUNIT_ASSERT(utl::CountedObject<o>::GetObjectsDestroyed() == d); \
25  CPPUNIT_ASSERT(utl::CountedObject<o>::GetObjectsExisting() == e)
26 
27 
28 namespace ns2 {
29  class Bar;
30 }
31 
32 
33 namespace ns1 {
34 
35  // this class emulates offline framework object with private ctor/dtor
36  // commented methods are implicit
37  class Foo : public utl::CountedObject<Foo> {
38 
39  public:
40  Foo(const Foo& foo) : utl::CountedObject<Foo>() { fData = foo.fData; }
41  Foo& operator=(const Foo& foo) { fData = foo.fData; return *this; }
42  int GetData() const { return fData; }
43  void SetData(const int data) { fData = data; }
44  bool operator==(const Foo& foo) const { return fData == foo.fData; }
45  bool operator!=(const Foo& foo) const { return !operator==(foo); }
46 
47  private:
48  Foo() : fData(0) { }
49  ~Foo() { }
50 
51  int fData;
52 
53  friend class ns2::Bar;
54  friend class utl::ShadowPtr<Foo>;
56 
57  };
58 
59 }
60 
61 
62 namespace ns2 {
63 
64  class Bar {
65 
66  public:
67  bool HasFoo1() const { return bool(fFoo1); }
68  void MakeFoo1() { fFoo1 = new ns1::Foo; }
69  ns1::Foo& GetFoo1() { return *fFoo1; }
70  const ns1::Foo& GetFoo1() const { return *fFoo1; }
71 
72  bool HasFoo2() const { return bool(fFoo2); }
73  ns1::Foo& GetFoo2() { return *fFoo2; }
74  const ns1::Foo& GetFoo2() const { return *fFoo2; }
75 
76  bool operator==(const Bar& bar) const
77  { return utl::DeepEqual(fFoo1, bar.fFoo1) && utl::DeepEqual(fFoo2, bar.fFoo2); }
78  bool operator!=(const Bar& bar) const { return !operator==(bar); }
79 
80  Bar() {}
81 
82  private:
85 
86  };
87 
88 }
89 
90 
91 namespace ns3 {
92 
93  class VBase {
94 
95  public:
96  typedef int IsClonableTag;
97 
98  virtual VBase* Clone() const = 0;
99  virtual ~VBase() { }
100 
101  };
102 
103  class Child : public VBase {
104 
105  public:
106  virtual ~Child() { }
107  Child() : fCountClone(0) { }
108  int GetCount() const { return fCountClone; }
109  Child* Clone() const { ++fCountClone; return new Child(*this); }
110 
111  private:
112  mutable int fCountClone;
113 
114  };
115 
116  class Mother {
117 
118  public:
119  bool HasChild() const { return bool(fChild); }
120  void MakeChild() { fChild = new Child; }
121  Child& GetChild() { return *fChild; }
122  const Child& GetChild() const { return *fChild; }
123 
124  private:
126 
127  };
128 
129 }
130 
131 /*namespace ns4 {
132 
133  class Prince {
134  public:
135  int i;
136  Prince()
137  : i(0)
138  { }
139  static int fgCloneCount;
140  };
141 
142  int Prince::fgCloneCount = 0;
143 
144  class King {
145  public:
146  utl::ShadowPtr<Prince> fHeir;
147  King()
148  : fHeir(new Prince())
149  { }
150  };
151 
152  Prince* Clone(const Prince& src)
153  {
154  ++Prince::fgCloneCount;
155  return new Prince(src);
156  }
157 
158 }*/
159 
160 
161 class OverCounted {
162 public:
163  explicit OverCounted(const int data = 0)
164  { ++fgConstructor; fData = data; }
165 
167  { ++fgDestructor; }
168 
170  { ++fgCopyConstructor; fData = oc.fData; }
171 
173  { ++fgAssign; fData = oc.fData; return *this; }
174 
175  static void Clear()
176  { fgConstructor = fgDestructor = fgCopyConstructor = fgAssign = fgSwap = 0; }
177 
178  void Swap(OverCounted& oc)
179  { ++fgSwap; std::swap(fData, oc.fData); }
180 
181  static
182  void
184  {
185  std::cout << '+' << fgConstructor << " ~" << fgDestructor
186  << " :" << fgCopyConstructor << " =" << fgAssign
187  << " s" << fgSwap << std::endl;
188  }
189 
190 private:
191  int fData;
192  static int fgConstructor;
193  static int fgDestructor;
194  static int fgCopyConstructor;
195  static int fgAssign;
196  static int fgSwap;
197 };
198 
202 int OverCounted::fgAssign = 0;
203 int OverCounted::fgSwap = 0;
204 
205 
206 //namespace std {
207 
208  void
210  {
211  oc1.Swap(oc2);
212  }
213 
214 //}
215 
216 
220 class testShadowPtr : public CppUnit::TestFixture {
221 
222  CPPUNIT_TEST_SUITE(testShadowPtr);
223  CPPUNIT_TEST(testALot);
224  CPPUNIT_TEST_EXCEPTION(testDereferenceZeroThrow, utl::NonExistentComponentException);
225  CPPUNIT_TEST(testNoThrow);
226  CPPUNIT_TEST(testCloning);
227  //CPPUNIT_TEST(testKoenigCloning);
228  CPPUNIT_TEST(testPrintStatistics);
229  CPPUNIT_TEST(testContainerOps);
230  CPPUNIT_TEST_SUITE_END();
231 
232 public:
233  void setUp() { }
234 
235  void tearDown() { }
236 
237  void
239  {
240  int created = 0;
241  int destroyed = 0;
242  int existing = 0;
243  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
244  {
245  ns2::Bar bar;
246  ++created; ++existing;
247  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
248  }
249  ++destroyed; --existing;
250  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
251  {
252  ns2::Bar bar1;
253  ++created; ++existing;
254  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
255  CPPUNIT_ASSERT(bar1.HasFoo1() == false);
256  CPPUNIT_ASSERT(bar1.HasFoo2() == true);
257  bar1.MakeFoo1();
258  ++created; ++existing;
259  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
260  CPPUNIT_ASSERT(bar1.HasFoo1() == true);
261  CPPUNIT_ASSERT(bar1.HasFoo2() == true);
262  bar1.GetFoo1().SetData(13);
263  bar1.GetFoo2().SetData(137);
264  CPPUNIT_ASSERT(bar1.GetFoo1().GetData() == 13);
265  CPPUNIT_ASSERT(bar1.GetFoo2().GetData() == 137);
266  const ns2::Bar bar2(bar1);
267  created += 2; existing += 2;
268  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
269  CPPUNIT_ASSERT(bar2.GetFoo1().GetData() == 13);
270  CPPUNIT_ASSERT(bar2.GetFoo2().GetData() == 137);
271  CPPUNIT_ASSERT(&bar1.GetFoo1() != &bar2.GetFoo1());
272  CPPUNIT_ASSERT(&bar1.GetFoo2() != &bar2.GetFoo2());
273  const ns2::Bar bar3 = bar1;
274  created += 2; existing += 2;
275  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
276  CPPUNIT_ASSERT(bar3.GetFoo1().GetData() == 13);
277  CPPUNIT_ASSERT(bar3.GetFoo2().GetData() == 137);
278  CPPUNIT_ASSERT(&bar1.GetFoo1() != &bar3.GetFoo1());
279  CPPUNIT_ASSERT(&bar1.GetFoo2() != &bar3.GetFoo2());
280  CPPUNIT_ASSERT(bar3 == bar1);
281  CPPUNIT_ASSERT(bar3.GetFoo1() == bar1.GetFoo1());
282  CPPUNIT_ASSERT(bar3.GetFoo2() == bar1.GetFoo2());
283  ns2::Bar bar4;
284  ++created; ++existing;
285  CPPUNIT_ASSERT(bar4 != bar1);
286  }
287  destroyed += 7; existing -= 7;
288  ASSERT_OBJECT_COUNTS(ns1::Foo, created, destroyed, existing);
289  }
290 
291  void
293  {
294  const ns2::Bar bar;
295  const ns1::Foo& foo = bar.GetFoo1();
296  foo.GetData();
297  }
298 
299  void
301  {
302  const ns2::Bar bar;
303  const ns1::Foo& foo = bar.GetFoo2();
304  foo.GetData();
305  }
306 
307  void
309  {
310  ns3::Mother mom;
311  CPPUNIT_ASSERT(mom.HasChild() == false);
312  mom.MakeChild();
313  CPPUNIT_ASSERT(mom.HasChild() == true);
314  CPPUNIT_ASSERT(Verify<Equal>(mom.GetChild().GetCount(), 0));
315  ns3::Mother stepMother(mom);
316  CPPUNIT_ASSERT(stepMother.HasChild() == true);
317  CPPUNIT_ASSERT(Verify<Equal>(mom.GetChild().GetCount(), 1));
318  CPPUNIT_ASSERT(Verify<Equal>(stepMother.GetChild().GetCount(), 1));
319  CPPUNIT_ASSERT(&mom.GetChild() != &stepMother.GetChild());
320  }
321 
322  /*void
323  testKoenigCloning()
324  {
325  ns4::King k;
326  CPPUNIT_ASSERT(Verify<Equal>(ns4::Prince::fgCloneCount, 0));
327  ns4::King k2(k);
328  CPPUNIT_ASSERT(Verify<Equal>(ns4::Prince::fgCloneCount, 1));
329  }*/
330 
331  void
333  {
334  std::cerr << std::endl;
335  utl::CountedObjectRegistry::PrintStatistics(std::cerr, "ns1::Foo");
336  std::cerr << std::endl;
337  }
338 
339  void
341  {
343  std::cout << "\n0: "; OverCounted::Print();
344  // ctor
345  OverCounted obj;
346  std::cout << "1: "; OverCounted::Print();
347  // vec
348  std::vector<utl::ShadowPtr<OverCounted> > vec;
349  std::cout << "2: "; OverCounted::Print();
350  // push_back version 1
351  vec.push_back(utl::ShadowPtr<OverCounted>(new OverCounted(obj)));
352  std::cout << "3: "; OverCounted::Print();
353  // push_back version 2
354  vec.push_back(utl::ShadowPtr<OverCounted>());
355  std::cout << "4: "; OverCounted::Print();
356  vec.back() = new OverCounted(obj);
357  std::cout << "5: "; OverCounted::Print();
358 
359  //
360 
362  {
363  typedef utl::ShadowPtr<OverCounted> OverCountedShPtr;
364  std::vector<OverCountedShPtr> vec;
365  for (int i = 0; i < 100; ++i)
366  vec.push_back(OverCountedShPtr(new OverCounted(obj)));
367  std::cout << "\n vec: "; OverCounted::Print();
368  }
369  std::cout << "~vec: "; OverCounted::Print();
370 
371  //
372 
373  std::vector<OverCounted> v2(1, obj);
374  // trim to exactly 1 element size
375  std::vector<OverCounted>(v2).swap(v2);
377  std::cout << "\n0: "; OverCounted::Print();
378  v2.push_back(obj);
379  std::cout << "1: "; OverCounted::Print();
380  v2.push_back(obj);
381  std::cout << "2: "; OverCounted::Print();
382 
383  //
384 
385  std::vector<std::vector<OverCounted> > v3(1, v2);
386  // trim to exactly 1 element size
387  std::vector<std::vector<OverCounted> >(v3).swap(v3);
389  std::cout << "\n0: "; OverCounted::Print();
390  v3.push_back(v2);
391  std::cout << "1: "; OverCounted::Print();
392  v3.push_back(v2);
393  std::cout << "2: "; OverCounted::Print();
394  }
395 
396 };
397 
399 
400 
401 // Configure (x)emacs for this file ...
402 // Local Variables:
403 // mode: c++
404 // End:
pointer with built-in initialization, deletion, deep copying
Definition: ShadowPtr.h:163
virtual ~Child()
static int fgAssign
const Child & GetChild() const
static int fgDestructor
void swap(utl::Trace< T > &t1, utl::Trace< T > &t2)
Definition: Trace.h:363
T * Clone(const T &src)
Clone a given object.
Definition: ShadowPtr.h:69
const ns1::Foo & GetFoo1() const
bool operator==(const Foo &foo) const
void swap(utl::TabulatedFunction &t1, utl::TabulatedFunction &t2)
utl::ShadowPtr< ns1::Foo > fFoo1
static int fgConstructor
void testPrintStatistics()
utl::InitializedShadowPtr< ns1::Foo > fFoo2
static void Clear()
Foo & operator=(const Foo &foo)
Base class for exceptions trying to access non-existing components.
OverCounted(const OverCounted &oc)
Child & GetChild()
utl::ShadowPtr< Child > fChild
CPPUNIT_TEST_SUITE_REGISTRATION(testAiresShowerFile)
bool HasChild() const
OverCounted(const int data=0)
OverCounted & operator=(const OverCounted &oc)
bool operator!=(const Bar &bar) const
ns1::Foo & GetFoo1()
bool operator==(const TimeStamp &ts, const TimeRange &tr)
Definition: TimeRange.h:97
bool operator==(const Bar &bar) const
static int fgSwap
void MakeFoo1()
Foo(const Foo &foo)
bool HasFoo1() const
static void Print()
bool HasFoo2() const
const ns1::Foo & GetFoo2() const
ns1::Foo & GetFoo2()
void Swap(OverCounted &oc)
static void PrintStatistics(std::ostream &theStream, const std::string &filter="")
uint16_t * data
Definition: dump1090.h:228
void testDereferenceZeroThrow()
bool DeepEqual(const LameShadowPtr< T, D > &s1, const LameShadowPtr< T, D > &s2)
Definition: LameShadowPtr.h:91
int GetCount() const
bool operator!=(const Foo &foo) const
int GetData() const
void SetData(const int data)
#define ASSERT_OBJECT_COUNTS(o, c, d, e)
Child * Clone() const
Mix-in class for counting creation and destruction of objects.
Definition: CountedObject.h:30
constexpr double bar
Definition: AugerUnits.h:213
virtual ~VBase()
static int fgCopyConstructor
void testContainerOps()
void MakeChild()

, generated on Tue Sep 26 2023.