wait.hh gecode/kernel.hh Gecode::Kernel::UnaryWait Gecode::Kernel::NaryWait Gecode Gecode::Kernel /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> * *Copyright: *ChristianSchulte,2009 * *Lastmodified: *$Date:2013-07-0417:03:13+0200(Thu,04Jul2013)$by$Author:schulte$ *$Revision:13801$ * *ThisfileispartofGecode,thegenericconstraint *developmentenvironment: *http://www.gecode.org * *Permissionisherebygranted,freeofcharge,toanypersonobtaining *acopyofthissoftwareandassociateddocumentationfiles(the *"Software"),todealintheSoftwarewithoutrestriction,including *withoutlimitationtherightstouse,copy,modify,merge,publish, *distribute,sublicense,and/orsellcopiesoftheSoftware,andto *permitpersonstowhomtheSoftwareisfurnishedtodoso,subjectto *thefollowingconditions: * *Theabovecopyrightnoticeandthispermissionnoticeshallbe *includedinallcopiesorsubstantialportionsoftheSoftware. * *THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND, *EXPRESSORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOF *MERCHANTABILITY,FITNESSFORAPARTICULARPURPOSEAND *NONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSORCOPYRIGHTHOLDERSBE *LIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHERINANACTION *OFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORINCONNECTION *WITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. * */ #ifndef__GECODE_KERNEL_WAIT_HH__ #define__GECODE_KERNEL_WAIT_HH__ #include<gecode/kernel.hh> namespaceGecode{namespaceKernel{ template<classView> classUnaryWait:publicPropagator{ protected: Viewx; void(*c)(Space&); UnaryWait(Homehome,Viewx,void(*c0)(Space&)); UnaryWait(Space&home,boolshared,UnaryWait&p); public: virtualActor*copy(Space&home,boolshare); virtualPropCostcost(constSpace&home,constModEventDelta&med)const; virtualExecStatuspropagate(Space&home,constModEventDelta&med); staticExecStatuspost(Space&home,Viewx,void(*c)(Space&)); virtualsize_tdispose(Space&home); }; template<classView> classNaryWait:publicPropagator{ protected: ViewArray<View>x; void(*c)(Space&); NaryWait(Homehome,ViewArray<View>&x,void(*c0)(Space&)); NaryWait(Space&home,boolshared,NaryWait&p); public: virtualActor*copy(Space&home,boolshare); virtualPropCostcost(constSpace&home,constModEventDelta&med)const; virtualExecStatuspropagate(Space&home,constModEventDelta&med); staticExecStatuspost(Space&home,ViewArray<View>&x,void(*c)(Space&)); virtualsize_tdispose(Space&home); }; /* *Waitpropagatorforsingleview * */ template<classView> forceinline UnaryWait<View>::UnaryWait(Homehome,Viewx0,void(*c0)(Space&)) :Propagator(home),x(x0),c(c0){ x.subscribe(home,*this,PC_GEN_ASSIGNED); } template<classView> forceinline UnaryWait<View>::UnaryWait(Space&home,boolshared,UnaryWait&p) :Propagator(home,shared,p),c(p.c){ x.update(home,shared,p.x); } template<classView> Actor* UnaryWait<View>::copy(Space&home,boolshare){ returnnew(home)UnaryWait<View>(home,share,*this); } template<classView> PropCost UnaryWait<View>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::unary(PropCost::LO); } template<classView> ExecStatus UnaryWait<View>::propagate(Space&home,constModEventDelta&){ assert(x.assigned()); c(home); returnhome.failed()?ES_FAILED:home.ES_SUBSUMED(*this); } template<classView> ExecStatus UnaryWait<View>::post(Space&home,Viewx,void(*c)(Space&)){ if(x.assigned()){ c(home); returnhome.failed()?ES_FAILED:ES_OK; }else{ (void)new(home)UnaryWait<View>(home,x,c); returnES_OK; } } template<classView> size_t UnaryWait<View>::dispose(Space&home){ x.cancel(home,*this,PC_GEN_ASSIGNED); (void)Propagator::dispose(home); returnsizeof(*this); } /* *Waitpropagatorforseveralviews * */ template<classView> forceinline NaryWait<View>::NaryWait(Homehome,ViewArray<View>&x0, void(*c0)(Space&)) :Propagator(home),x(x0),c(c0){ assert(!x[0].assigned()); x[0].subscribe(home,*this,PC_GEN_ASSIGNED); } template<classView> forceinline NaryWait<View>::NaryWait(Space&home,boolshared,NaryWait&p) :Propagator(home,shared,p),c(p.c){ x.update(home,shared,p.x); } template<classView> Actor* NaryWait<View>::copy(Space&home,boolshare){ assert(!x[0].assigned()); for(inti=x.size()-1;i>0;i--) if(x[i].assigned()) x.move_lst(i); assert(x.size()>0); returnnew(home)NaryWait<View>(home,share,*this); } template<classView> PropCost NaryWait<View>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::unary(PropCost::HI); } template<classView> ExecStatus NaryWait<View>::propagate(Space&home,constModEventDelta&){ assert(x[0].assigned()); for(inti=x.size()-1;i>0;i--) if(x[i].assigned()) x.move_lst(i); assert(x.size()>0); if(x.size()==1){ x.size(0); c(home); returnhome.failed()?ES_FAILED:home.ES_SUBSUMED(*this); }else{ //Createnewsubscription x.move_lst(0); assert(!x[0].assigned()); x[0].subscribe(home,*this,PC_GEN_ASSIGNED,false); returnES_OK; } } template<classView> ExecStatus NaryWait<View>::post(Space&home,ViewArray<View>&x,void(*c)(Space&)){ for(inti=x.size();i--;) if(x[i].assigned()) x.move_lst(i); if(x.size()==0){ c(home); returnhome.failed()?ES_FAILED:ES_OK; }else{ x.unique(home); if(x.size()==1){ returnUnaryWait<View>::post(home,x[0],c); }else{ (void)new(home)NaryWait<View>(home,x,c); returnES_OK; } } } template<classView> size_t NaryWait<View>::dispose(Space&home){ if(x.size()>0) x[0].cancel(home,*this,PC_GEN_ASSIGNED); (void)Propagator::dispose(home); returnsizeof(*this); } }} #endif //STATISTICS:kernel-prop