/** @test verify an extension built on top of the ItemWrapper:
  *        a function which remembers the last result. Here we use
  *        a test function, which picks a member of an vector and
  *        returns a \em reference to it. Thus the cached "result"
  *        can be used to access and change the values within the
  *        original vector. In a real world usage scenario, such a
  *        function could be an (expensive) data structure access.
  */
 void
 verifyFunctionRefResult()
   {
     vector<int> testVec;
     for (uint i=0; i<10; ++i)
       testVec.push_back(i);
     
     FunctionResult<int&(size_t)> funRes (pickElement_ofVector(testVec));
     
     // function was never invoked, thus the remembered result is NIL
     CHECK (!funRes);
     VERIFY_ERROR (BOTTOM_VALUE, *funRes );
     
     int& r5 = funRes (5);
     CHECK (funRes);  // indicates existence of cached result
     
     CHECK (5 == r5);
     CHECK (isSameObject (r5, testVec[5]));
     
     int& r5x = *funRes;
     CHECK (isSameObject (r5, r5x));
     
     CHECK ( isSameObject (r5, *funRes));
     int& r7 = funRes (7);
     CHECK (!isSameObject (r5, *funRes));
     CHECK ( isSameObject (r7, *funRes));
     
     -- r5x;
     ++ *funRes;
     CHECK (5-1 == testVec[5]);
     CHECK (7+1 == testVec[7]);
     CHECK (7+1 == r7);
   }
 /** @test proper handling of move and rvalue references */
 void
 verifySaneMoveHandling()
   {
     using Data = shared_ptr<int>;
     using Wrap = ItemWrapper<Data>;
     
     Data data{new int(12345)};
     CHECK (1 == data.use_count());
     
     Wrap wrap{data};
     CHECK (2 == data.use_count());
     CHECK (12345 == **wrap);
     CHECK (isSameObject (*data, **wrap));
     CHECK (!isSameObject (data, *wrap));
     
     Wrap wcopy{wrap};
     CHECK (3 == data.use_count());
     
     Wrap wmove{move (wcopy)};
     CHECK (3 == data.use_count());
     CHECK (not wcopy);
     CHECK (wmove);
     
     wcopy = move(wmove);
     CHECK (3 == data.use_count());
     CHECK (not wmove);
     CHECK (wcopy);
     
     Wrap wmove2{move (data)};
     CHECK (0 == data.use_count());
     CHECK (3 == wmove2->use_count());
     CHECK (not data);
     CHECK (wmove2);
     CHECK (wrap);
     
     wmove2 = move (wcopy);
     CHECK (2 == wmove2->use_count());
     CHECK (not wcopy);
     CHECK (wmove2);
     CHECK (wrap);
     
     wmove2 = move (wrap);
     CHECK (1 == wmove2->use_count());
     CHECK (not wrap);
     CHECK (wmove2);
     
     wmove2 = move (wmove);
     CHECK (not wcopy);
     CHECK (not wmove);
     CHECK (not wmove2);
   }
 void
 verifyCreation_and_Copy()
   {
     typedef PV Holder;
     typedef IMP ImpType;
     typedef typename PV::Interface Api;
     
     long prevSum = _checkSum;
     uint prevCnt = _created;
     
     Holder val = Holder::template build<ImpType>();
     CHECK (prevSum+111 == _checkSum);            // We got one primary ctor call
     CHECK (prevCnt+1   <= _created);             // Note: usually, the compiler optimises
     CHECK (prevCnt+2   >= _created);             //       and skips the spurious copy-operation
     CHECK (sizeof(Holder) >= sizeof(ImpType));
     Api& embedded = val;
     CHECK (isSameObject(embedded,val));
     CHECK (INSTANCEOF(ImpType, &embedded));
     
     prevCnt = _created;
     Holder val2(val);       // invoke copy ctor without knowing the implementation type
     embedded.apiFunc();
     CHECK (val != val2);    // invoking the API function had an sideeffect on the state
     val = val2;             // assignment of copy back to the original...
     CHECK (val == val2);    // cancels the side effect
     
     CHECK (prevCnt+1 == _created); // one new embedded instance was created by copy ctor
   }
 void
 produce_simple_values()
   {
     using TestFactory = factory::MultiFact<string, theID>;
     
     TestFactory theFact;
     
     // the first "production line" is wired to a free function
     theFact.defineProduction (ONE, buildOne);
     
     // second "production line" uses a explicit partial closure
     theFact.defineProduction (TWO, bind (buildSome<theID>, TWO));
     
     // for the third "production line" we set up a function object
     auto memberFunction = bind (&MultiFact_test::callMe, this, "lalü");
     theFact.defineProduction (THR, memberFunction);
     
     // and the fourth "production line" uses a lambda, closed with a local reference
     string backdoor("backdoor");
     theFact.defineProduction (FOU, [&] {
                                       return backdoor;
                                    });
     
     CHECK (!isnil (theFact));
     CHECK (theFact(ONE) == "1");
     CHECK (theFact(TWO) == "2");
     
     CHECK (theFact(THR) == "lalü");
     CHECK (invocations_ == 1);
     
     CHECK (theFact(FOU) == "backdoor");
     backdoor = "I am " + backdoor.substr(0,4);
     CHECK (theFact(FOU) == "I am back");
     
     
     TestFactory anotherFact;
     CHECK (isnil (anotherFact));
     VERIFY_ERROR (INVALID, anotherFact(ONE) );
     
     anotherFact.defineProduction (ONE, memberFunction);
     CHECK (anotherFact(ONE) == "lalü");
     CHECK (invocations_ == 2);
     
     CHECK (theFact(THR) == "lalü");
     CHECK (invocations_ == 3);
     
     
     CHECK ( theFact.contains (FOU));
     CHECK (!anotherFact.contains (FOU));
     
     anotherFact = theFact;
     CHECK (anotherFact.contains (FOU));
     CHECK (!isSameObject(theFact, anotherFact));
     
     CHECK (anotherFact(ONE) == "1");
     CHECK (anotherFact(TWO) == "2");
     CHECK (anotherFact(THR) == "lalü");
     CHECK (anotherFact(FOU) == "I am back");
     CHECK (invocations_ == 4);
   }
 /** @test verify the allocation/de-allocation handling as
  *        embedded into the CommandRegistry operation.
  *        Simulates on low level what normally happens
  *        during command lifecycle.
  */
 void
 checkAllocation (CommandRegistry& registry)
   {
     // simulate what normally happens within a CommandDef
     typedef void Sig_oper(int);
     typedef long Sig_capt(int);
     typedef void Sig_undo(int,long);
     
     function<Sig_oper> o_Fun (command1::operate);
     function<Sig_capt> c_Fun (command1::capture);
     function<Sig_undo> u_Fun (command1::undoIt);
     
     CHECK (o_Fun && c_Fun && u_Fun);
     CHECK (cnt_inst == registry.instance_count());
     
     // when the CommandDef is complete, it issues the
     // allocation call to the registry behind the scenes....
     
     typedef shared_ptr<CommandImpl> PImpl;
     
     PImpl pImpl = registry.newCommandImpl(o_Fun,c_Fun,u_Fun);
     CHECK (1+cnt_inst == registry.instance_count());
     
     CHECK (pImpl);
     CHECK (pImpl->isValid());
     CHECK (!pImpl->canExec());
     CHECK (1 == pImpl.use_count());   // no magic involved, we hold the only instance
     
     PImpl clone = registry.createCloneImpl(*pImpl);
     CHECK (clone->isValid());
     CHECK (!clone->canExec());
     CHECK (1 == clone.use_count());
     CHECK (1 == pImpl.use_count());
     CHECK (2+cnt_inst == registry.instance_count());
     
     CHECK (!isSameObject (*pImpl, *clone));
     CHECK (*pImpl == *clone);
     
     CHECK (!pImpl->canExec());
     typedef Types<int> ArgType;
     TypedArguments<Tuple<ArgType>> arg{Tuple<ArgType>(98765)};
     pImpl->setArguments(arg);
     CHECK (pImpl->canExec());
     
     CHECK (!clone->canExec()); // this proves the clone has indeed a separate identity
     CHECK (*pImpl != *clone);
     
     // discard the first clone and overwrite with a new one
     clone = registry.createCloneImpl(*pImpl);
     CHECK (2+cnt_inst == registry.instance_count());
     CHECK (*pImpl == *clone);
     CHECK (clone->canExec());
     
     clone.reset();
     pImpl.reset();
     // corresponding allocation slots cleared automatically
     CHECK (cnt_inst == registry.instance_count());
   }
Beispiel #6
0
 Provision&
 operator= (Provision const& o)
 {
     if (!isSameObject(*this, o))
     {
         AdviceLink::operator= (o);
         setSolution ( NULL );
     }
     return *this;
 }
 /** @test verify especially that we can wrap and handle
  *        a reference "value" in a pointer-like manner
  */
 void
 verifyWrappedRef ()
   {
     int x = 5;
     ItemWrapper<int&> refWrap;
     CHECK (!refWrap);
     
     refWrap = x;
     CHECK (refWrap);
     CHECK (5 == *refWrap);
     CHECK (x == *refWrap);
     
     *refWrap += 5;
     CHECK (x == 10);
     
     ItemWrapper<int*> ptrWrap (& *refWrap);
     CHECK ( isSameObject (**ptrWrap,  x));
     CHECK (!isSameObject ( *ptrWrap, &x));
     **ptrWrap += 13;
     CHECK (x == 23);
   }
 void
 produce_smart_pointers()
   {
     using TestFactory = factory::MultiFact<Interface, theID, factory::BuildRefcountPtr>;
     using PIfa = shared_ptr<Interface>;
     
     TestFactory theFact;
     
     // set up the "production lines" by lambda
     theFact.defineProduction (ONE, [] { return new Implementation<ONE>; });
     theFact.defineProduction (TWO, [] { return new Implementation<TWO>; });
     theFact.defineProduction (THR, [] { return new Implementation<THR>; });
     theFact.defineProduction (FOU, [] { return new Implementation<FOU>; });
     CHECK (!isnil (theFact));
     
     PIfa p1 = theFact(ONE);
     PIfa p2 = theFact(TWO);
     PIfa p3 = theFact(THR);
     PIfa p4 = theFact(FOU);
     
     PIfa p11 = theFact(ONE);
     
     CHECK ("Impl-1" == string(*p1));
     CHECK ("Impl-2" == string(*p2));
     CHECK ("Impl-3" == string(*p3));
     CHECK ("Impl-4" == string(*p4));
     
     CHECK ("Impl-1" == string(*p11));
     CHECK (!isSameObject(*p1, *p11));
     
     PIfa p12(p11);
     CHECK (isSameObject(*p11, *p12));
     CHECK ("Impl-1" == string(*p12));
     CHECK (1 == p1.use_count());
     CHECK (2 == p11.use_count());
     CHECK (2 == p12.use_count());
   }
 static void
 operate (PolyVal& elm)
   {
     PolyVal myLocalVal(elm);
     CHECK (elm == myLocalVal);
     
     long prevSum = _callSum;
     long randVal = myLocalVal->apiFunc();
     CHECK (prevSum + randVal == _callSum);
     CHECK (elm != myLocalVal);
     
     elm = myLocalVal;
     CHECK (elm == myLocalVal);
     CHECK (!isSameObject (elm, myLocalVal));
     
     CHECK (sizeof(myLocalVal) <= MAX_SIZ + polyvalue::Trait<Interface>::ADMIN_OVERHEAD + _ALIGN_);
   }
 virtual void
 run (Arg) 
   {
     CHECK (0 == checksum_);
     
     TypedAllocationManager allocator;
     
     typedef shared_ptr<DummyObj<1>>  PD1;
     typedef shared_ptr<DummyObj<22>> PD22;
     CHECK (sizeof(DummyObj<1>) != sizeof(DummyObj<22>));
     
       {
         PD1  pD11 = allocator.create<DummyObj<1> >();
         PD1  pD12 = allocator.create<DummyObj<1> >();
         PD22 pD21 = allocator.create<DummyObj<22>>();
         PD22 pD22 = allocator.create<DummyObj<22>>();
         CHECK (pD11);
         CHECK (pD12);
         CHECK (pD21);
         CHECK (pD22);
         CHECK (1 == pD11.use_count());
         CHECK (1 == pD12.use_count());
         CHECK (1 == pD21.use_count());
         CHECK (1 == pD22.use_count());
         CHECK (!isSameObject (*pD11, *pD12));
         CHECK (!isSameObject (*pD11, *pD21));
         CHECK (!isSameObject (*pD11, *pD22));
         CHECK (!isSameObject (*pD12, *pD21));
         CHECK (!isSameObject (*pD12, *pD22));
         CHECK (!isSameObject (*pD21, *pD22));
         
         PD22 pD2x = pD21;
         CHECK (pD2x);
         CHECK (2 == pD21.use_count());
         CHECK (2 == pD2x.use_count());
         CHECK (isSameObject (*pD21, *pD2x));
         
         CHECK (2 == allocator.numSlots<DummyObj<1> >());
         CHECK (2 == allocator.numSlots<DummyObj<22>>());
         
         CHECK (0 == allocator.numSlots<long>()); // query just some unrelated type...
       }
     
     CHECK (0 == allocator.numSlots<DummyObj<1> >());
     CHECK (0 == allocator.numSlots<DummyObj<22>>());
     CHECK (0 == checksum_);
   }
Beispiel #11
0
 void
 pass_additional_arguments()
   {
     using TestFactory = factory::MultiFact<Interface*(string), theID>;
     
     TestFactory theFact;
     
     // set up the "production lines"
     theFact.defineProduction (ONE, [](string   ) { return new Implementation<ONE>;        });
     theFact.defineProduction (TWO, [](string   ) { return new Implementation<TWO>("X");   });
     theFact.defineProduction (THR, [](string id) { return new Implementation<THR>(id);    });
     theFact.defineProduction (FOU, [](string id) { return new Implementation<FOU>("Z"+id);});
     
     Interface *p1 = theFact(ONE, "irrelevant"),
               *p2 = theFact(TWO, "ignored"),
               *p3 = theFact(THR, "idiocy"),
               *p4 = theFact(FOU, "omg"),
               *p5 = theFact(FOU, "z");
     
     // does not compile...
     // theFact(ONE);
     // theFact(ONE, "foo", bar);
     
     CHECK ("Impl-1" == string(*p1));
     CHECK ("X2"     == string(*p2));
     CHECK ("idiocy3"== string(*p3));
     CHECK ("Zomg4"  == string(*p4));
     CHECK ("Zz4"    == string(*p5));
     
     CHECK (!isSameObject(*p4, *p5));
     CHECK (INSTANCEOF(Implementation<ONE>, p1));
     CHECK (INSTANCEOF(Implementation<TWO>, p2));
     CHECK (INSTANCEOF(Implementation<THR>, p3));
     CHECK (INSTANCEOF(Implementation<FOU>, p4));
     CHECK (INSTANCEOF(Implementation<FOU>, p5));
     
     delete p1;
     delete p2;
     delete p3;
     delete p4;
     delete p5;
   }
Beispiel #12
0
      /** @test cover the basic situations of object handling,
       *        especially copy operations and re-assignments
       */
      void
      checkHandling (TestList& objs)
        {
          Opaque oo;
          CHECK (!oo);
          CHECK (isnil(oo));
          
          oo = objs[1];
          CHECK (oo);
          CHECK (!isnil(oo));
          
          typedef DD<3> D3;
          typedef DD<5> D5;
          D3 d3 (oo.get<D3>() );
          CHECK (3 == oo->getIt());    // re-access through Base interface
          CHECK (!isSameObject (d3, *oo));
          VERIFY_ERROR (WRONG_TYPE, oo.get<D5>() );
          
          // direct assignment of target into Buffer
          oo = D5();
          CHECK (oo);
          CHECK (5 == oo->getIt());
          VERIFY_ERROR (WRONG_TYPE, oo.get<D3>() );
          
          // can get a direct reference to contained object
          D5 &rd5 (oo.get<D5>()); 
          CHECK (isSameObject (rd5, *oo));
          
          CHECK (!isnil(oo));
          oo = objs[3];     // copy construction also works on non-empty object
          CHECK (7 == oo->getIt());
          
          // WARNING: direct ref has been messed up through the backdoor!
          CHECK (7 == rd5.getIt());
          CHECK (isSameObject (rd5, *oo));
          
          uint cnt_before = _create_count;
          
          oo.clear();
          CHECK (!oo);
          oo = D5();        // direct assignment also works on empty object
          CHECK (oo);
          CHECK (5 == oo->getIt());
          CHECK (_create_count == 2 + cnt_before);
          // one within buff and one for the anonymous temporary D5()
          
          
          // verify that self-assignment is properly detected...
          cnt_before = _create_count;
          oo = oo;
          CHECK (oo);
          CHECK (_create_count == cnt_before);
          oo = oo.get<D5>();
          CHECK (_create_count == cnt_before);
          oo = *oo;
          CHECK (_create_count == cnt_before);
          CHECK (oo);
          
          oo.clear();
          CHECK (!oo);
          CHECK (isnil(oo));
          VERIFY_ERROR (BOTTOM_VALUE, oo.get<D5>() );
#if false ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT
          VERIFY_ERROR (ASSERTION, oo->getIt() );
#endif    ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT
          // can't access empty holder...
          
          Opaque o1 (oo);
          CHECK (!o1);
          
          Opaque o2 (d3);
          CHECK (!isSameObject (d3, *o2));
          CHECK (3 == o2->getIt());
          
          CHECK (sizeof(Opaque) <= sizeof(Base) + sizeof(void*) + _ALIGN_);
        }