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); }
const Asset::Ident createIdent (Query<STRU> const& query) { // does the query somehow specify the desired name-ID? string nameID = query.extractID (genericIdSymbol); if (isnil (nameID)) nameID = query.extractID (StructTraits<STRU>::idSymbol()); if (isnil (nameID)) { // no name-ID contained in the query... // so we'll create a new one static int i=0; nameID = _Fmt("%s.%d") % StructTraits<STRU>::namePrefix() % (++i); } ENSURE (!isnil (nameID)); // does the query actually demand the Nth instance/element? string seqID = query.extractID (seqNrPredicate); if (!isnil (seqID) && 1 < uNum(seqID)) nameID += "."+seqID; Category cat (STRUCT, StructTraits<STRU>::catFolder()); return Asset::Ident (nameID, cat ); }
void sigTerm (Subsys* susy, string* problem) ///< called from subsystem on termination { REQUIRE (susy); Lock sync (this); triggerEmergency(!isnil (problem)); INFO (subsystem, "Subsystem '%s' terminated.", cStr(*susy)); WARN_IF (!isnil(problem), subsystem, "Irregular shutdown caused by: %s", cStr(*problem)); ERROR_IF (susy->isRunning(), subsystem, "Subsystem '%s' signals termination, " "without resetting running state", cStr(*susy)); removeall (running_, susy); shutdownAll(); sync.notify(); }
virtual void run (Arg) { IterQueue<int> queue; CHECK (isnil (queue)); VERIFY_ERROR (ITER_EXHAUST, *queue ); VERIFY_ERROR (ITER_EXHAUST, ++queue ); queue.feed (1); queue.feed (3); queue.feed (5); CHECK (!isnil (queue)); CHECK (1 == *queue); ++queue; CHECK (3 == *queue); CHECK (3 == queue.pop()); CHECK (5 == *queue); ++queue; CHECK (isnil (queue)); VERIFY_ERROR (ITER_EXHAUST, *queue ); VERIFY_ERROR (ITER_EXHAUST, ++queue ); VERIFY_ERROR (ITER_EXHAUST, queue.pop() ); // use the generic builder API to feed // the contents of another iterator into the queue queue = build(queue).usingSequence (elements (23,45)); int i = queue.pop(); CHECK (i == 23); CHECK (45 == *queue); // feeding new elements and pulling / iteration can be mixed queue.feed(67); CHECK (45 == *queue); ++queue; CHECK (67 == *queue); ++queue; CHECK (isnil (queue)); queue.feed(89); CHECK (89 == *queue); queue.pop(); VERIFY_ERROR (ITER_EXHAUST, *queue ); }
/** @test OpaqueHolder with additional storage for subclass. * When a subclass requires more storage than the base class or * Interface, we need to create a custom OpaqueHolder, specifying the * actually necessary storage. Such a custom OpaqueHolder behaves exactly * like the standard variant, but there is protection against accidentally * using a standard variant to hold an instance of the larger subclass. * * @test Moreover, if the concrete class has a custom operator bool(), it * will be invoked automatically from OpaqueHolder's operator bool() * */ void checkSpecialSubclass () { typedef OpaqueHolder<Base, sizeof(Special)> SpecialOpaque; cout << showSizeof<Base>() << endl; cout << showSizeof<Special>() << endl; cout << showSizeof<Opaque>() << endl; cout << showSizeof<SpecialOpaque>() << endl; CHECK (sizeof(Special) > sizeof(Base)); CHECK (sizeof(SpecialOpaque) > sizeof(Opaque)); CHECK (sizeof(SpecialOpaque) <= sizeof(Special) + sizeof(void*) + _ALIGN_); Special s1 (6); Special s2 (3); CHECK (!s1); // even value CHECK (s2); // odd value CHECK (7 == s1.getIt()); // indeed subclass of DD<7> CHECK (7 == s2.getIt()); SpecialOpaque ospe0; SpecialOpaque ospe1 (s1); SpecialOpaque ospe2 (s2); CHECK (!ospe0); // note: bool test (isValid) CHECK (!ospe1); // also forwarded to contained object (myVal_==6 is even) CHECK ( ospe2); CHECK ( isnil(ospe0)); // while isnil just checks the empty state CHECK (!isnil(ospe1)); CHECK (!isnil(ospe2)); CHECK (7 == ospe1->getIt()); CHECK (6 == ospe1.get<Special>().myVal_); CHECK (3 == ospe2.get<Special>().myVal_); ospe1 = DD<5>(); // but can be reassigned like any normal Opaque CHECK (ospe1); CHECK (5 == ospe1->getIt()); VERIFY_ERROR (WRONG_TYPE, ospe1.get<Special>() ); Opaque normal = DD<5>(); CHECK (normal); CHECK (5 == normal->getIt()); #if false ////////////////////////////////////////////////////////TODO: restore throwing ASSERT // Assertion protects against SEGV VERIFY_ERROR (ASSERTION, normal = s1 ); #endif//////////////////////////////////////////////////////////// }
void checkSTLContainer() { typedef std::map<int,HO> MapHO; CHECK (0 == Dummy::checksum()); { MapHO maph; CHECK (isnil (maph)); for (uint i=0; i<100; ++i) { HO & contained = maph[i]; CHECK (!contained); } // 100 holder objects created by sideeffect // ..... without creating any contained object! CHECK (0 == Dummy::checksum()); CHECK (!isnil (maph)); CHECK (100==maph.size()); for (uint i=0; i<100; ++i) { create_contained_object (maph[i]); CHECK (maph[i]); CHECK (0 < maph[i]->acc(12)); } CHECK (100==maph.size()); CHECK (0 != Dummy::checksum()); long value55 = maph[55]->acc(0); long currSum = Dummy::checksum(); CHECK (1 == maph.erase(55)); CHECK (Dummy::checksum() == currSum - value55); // proves object#55's dtor has been invoked CHECK (maph.size() == 99); maph[55]; // create new empty holder by sideeffect... CHECK (&maph[55]); CHECK (!maph[55]); CHECK (maph.size() == 100); } CHECK (0 == Dummy::checksum()); }
void verify_transformIter() { WrappedList customList(NUM_ELMS); WrappedList::iterator sourceValues = customList.begin(); TimeIter tIt (transform (sourceValues, makeTime)); CHECK (!isnil (tIt)); pullOut (tIt); CHECK (!tIt); }
inline Pipe* StructFactoryImpl::fabricate (Query<Pipe> const& caps) { const Asset::Ident idi (createIdent (caps)); string streamID = caps.extractID ("stream"); if (isnil (streamID)) streamID = "default"; PProcPatt processingPattern = Session::current->defaults (Query<const ProcPatt>("stream("+streamID+")")); return new Pipe( idi , streamID , processingPattern ); ///////////////////////TICKET #565 maybe store the capabilities query within the Struct asset somehow? }
bool allDead () { if (isEmergencyExit()) { Lock sync(this); if (!sync.isTimedWait()) sync.setTimeout(EMERGENCYTIMEOUT); } return isnil (running_); // end wait if no running subsystem left }
void verify_simpleIters() { // build the test data sources WrappedList customList(NUM_ELMS); TestSource dedicatedSource(NUM_ELMS); list<int>& rawList(customList.data_); IntIter iii (eachEntry (customList)); IntIter isi (eachEntry (rawList.begin(), rawList.end())); StrIter cii (IterSource<CStr>::build(dedicatedSource)); CHECK (!isnil (iii)); CHECK (!isnil (isi)); CHECK (!isnil (cii)); pullOut (iii); pullOut (isi); pullOut (cii); CHECK (!iii); CHECK (!isi); CHECK (!cii); }
inline Timeline* StructFactoryImpl::fabricate (Query<Timeline> const& caps) { TODO ("extract additional properties/capabilities from the query..."); const Asset::Ident idi (createIdent (caps)); string sequenceID = caps.extractID ("sequence"); Query<Sequence> desiredSequence (isnil (sequenceID)? "" : "id("+sequenceID+")"); PSequence sequence = recursive_create_(desiredSequence); ASSERT (sequence); RBinding newBinding = Session::current->getRoot().attach (MObject::create (sequence)); ASSERT (newBinding); PTimeline newTimeline = Timeline::create (idi, newBinding); ENSURE (newTimeline); ///////////////////////TICKET #565 maybe store the capabilities query within the Struct asset somehow? return newTimeline.get(); }
inline Sequence* StructFactoryImpl::fabricate (Query<Sequence> const& caps) { // when we reach this point it is clear a suitable sequence doesn't yet exist in the model TODO ("actually extract properties/capabilities from the query..."); string forkID = caps.extractID ("fork"); Query<Fork> desiredFork (isnil (forkID)? "" : "id("+forkID+")"); // PFork fork = Session::current->query (desiredFork); ///////////////////////////////////TICKET #639 // TODO: handle the following cases // - fork doesn't exist --> create and attach it as root // - fork exists and is root attached, but belongs already to a sequence --> throw // - fork exists, but isn't root attached ---> what do do here? steal it?? PSequence newSequence = Sequence::create (createIdent (caps)); ///////////TODO fed fork in here ENSURE (newSequence); ///////////////////////TICKET #565 maybe store the capabilities query within the Struct asset somehow? return newSequence.get(); }
/** either fetch or build a suitable fork root for a new sequence */ RFork getFork_forSequence (string const& desiredID) { RFork fork; if (!isnil (desiredID)) fork = Session::current->elements.pick (match_specificFork (desiredID)); if (fork && !Scope::containing (fork.getRef()).isRoot()) { UNIMPLEMENTED ("how to deal with 'stealing' a fork sub-tree to a new sequence??"); } if (!fork) fork = Session::current->getRoot().attach (MObject::create (ForkID (desiredID))); return fork; }
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()); }
bool isValid() const { return isnil (failureLog_); }
/** @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_); }