00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "common/test/run.hpp"
00025 #include "common/util.hpp"
00026
00027 #include "testtargetobj.hpp"
00028 #include "common/factory.hpp"
00029
00030 #include <boost/lexical_cast.hpp>
00031 #include <boost/format.hpp>
00032 #include <iostream>
00033
00034 using boost::lexical_cast;
00035 using boost::format;
00036 using util::isnil;
00037 using std::string;
00038 using std::cout;
00039
00040
00041 namespace lumiera
00042 {
00043 namespace test
00044 {
00045
00049 class MallocAllocator
00050 {
00051 public:
00052 void* operator new (size_t siz) { return malloc (siz); };
00053 void operator delete (void* p) { if (p) free (p); };
00054 };
00055
00056
00060 class TargetO : public TestTargetObj
00061 {
00062 long additional_member;
00063
00064 public:
00065 TargetO (uint cnt) : TestTargetObj(cnt) {}
00066 virtual ~TargetO () {};
00067
00069 virtual void funky()
00070 {
00071 cout << string(*this) << "\n";
00072 }
00073 };
00074
00075
00079 class ImplObj : public TargetO
00080 {
00081 public:
00082 ImplObj () : TargetO(12) {}
00083
00085 virtual void funky()
00086 {
00087 cout << ".....ImplObj::funky() called\n";
00088 TargetO::funky();
00089 }
00090 };
00091
00092
00096 class MallocO : public TestTargetObj, public MallocAllocator
00097 {
00098 public:
00099 MallocO () : TestTargetObj (7) {}
00100 };
00101
00102
00103
00104 class Factory2;
00105
00109 class ParanoidObj : public TestTargetObj
00110 {
00111 private:
00112 ParanoidObj (uint cnt) : TestTargetObj(cnt) {}
00113 ~ParanoidObj () {}
00114
00115 friend class Factory2;
00116 };
00117
00118
00119
00120
00121
00122
00123 using std::tr1::shared_ptr;
00124
00129 class Factory1 : public Factory<TargetO>
00130 {
00131 public:
00132 typedef shared_ptr<TargetO> PType;
00133
00137 PType operator() (uint param) { return wrap (new(alloc()) TargetO(param) ); }
00138
00139 protected:
00140 PType wrap (TargetO* tO) { return PType (tO, &destroy); }
00141
00142 static void destroy (TargetO* victim) { victim->~TargetO(); }
00143 static void* alloc () { return buff; }
00144 static char buff[];
00145 };
00146 char Factory1::buff[sizeof(TargetO)];
00147
00148
00149
00153 class Factory2 : public Factory<ParanoidObj>
00154 {
00155 public:
00156 typedef shared_ptr<ParanoidObj> PType;
00157
00162 PType operator() (uint param) { return PType (new ParanoidObj(param), &destroy); }
00163
00164 protected:
00168 static void destroy (ParanoidObj* victim) { delete victim; }
00169
00170 };
00171
00172
00173
00174
00175
00176 typedef Factory<MallocO> FactoryM;
00177 typedef factory::PImplPtr<TargetO,ImplObj> FactoryP;
00178
00179 static Factory1 placement_fac;
00180 static Factory2 paranoid_fac;
00181 static FactoryM malloc_fac;
00182 static FactoryP pimpl_fac;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 class Factory_special_test : public Test
00196 {
00197 virtual void run(Arg arg)
00198 {
00199 uint num= isnil(arg)? 1 : lexical_cast<uint>(arg[1]);
00200
00201 checkPlacement (num);
00202 checkPrivate (num);
00203 checkMalloc ();
00204 checkPImpl () ;
00205 }
00206
00207
00212 void checkPlacement (uint cnt)
00213 {
00214 cout << "checkPlacement--------\n";
00215
00216 typedef Factory1::PType P;
00217 format msg ("created %d shared_ptrs to Object placed in static buffer.\n");
00218 void* raw (0);
00219 P pX;
00220 ASSERT (0 == pX.use_count());
00221
00222 {
00223 P p1 (placement_fac (cnt));
00224 P p2 (p1);
00225 P pX = p2;
00226
00227 cout << msg % p2.use_count()
00228 << string (*pX) << "\n";
00229
00230 raw = p1.get();
00231 }
00232
00233 ASSERT (0 == pX.use_count());
00234
00235 {
00236 P p1 (placement_fac (cnt+1));
00237 P p2 (p1);
00238 P p3 (p1);
00239 P pX = p2;
00240
00241 cout << msg % p2.use_count();
00242
00243 ASSERT (raw == p1.get(), "explicit object placement at fixed buffer doesn't work.");
00244 }
00245
00246 ASSERT (0 == pX.use_count());
00247 }
00248
00249
00250
00251
00255 void checkPrivate (uint cnt)
00256 {
00257 cout << "checkPrivate--------\n";
00258
00259 typedef Factory2::PType P;
00260 format msg ("created %d shared_ptrs to paranoid Object.\n");
00261 P pX;
00262
00263 ASSERT (0 == pX.use_count());
00264 {
00265 P p1 (paranoid_fac (cnt));
00266 P p2 (p1);
00267 P pX = p2;
00268
00269 cout << msg % p2.use_count()
00270 << string (*pX) << "\n";
00271 }
00272 ASSERT (0 == pX.use_count());
00273 }
00274
00275
00276
00277
00282 void checkMalloc (void)
00283 {
00284 cout << "checkMalloc--------\n";
00285
00286 typedef FactoryM::PType P;
00287
00288 P p1 (malloc_fac ());
00289 P p2 = p1;
00290 cout << ("created auto_ptr to malloc-ed Object.\n")
00291 << string (*p2) << "\n";
00292
00293 ASSERT (!p1.get());
00294 }
00295
00296
00297
00298
00303 void checkPImpl (void)
00304 {
00305 cout << "checkPImpl--------\n";
00306
00307 typedef FactoryP::PType P;
00308
00309 P p1 (pimpl_fac ());
00310 P p2 = p1;
00311 cout << ("created auto_ptr to Interface Object.\n");
00312 p2->funky();
00313
00314 ASSERT (!p1.get());
00315 }
00316 };
00317
00318
00320 LAUNCHER (Factory_special_test, "unit common");
00321
00322
00323
00324 }
00325
00326 }