Generated on Mon Aug 25 11:35:40 2008 for Gecode by doxygen 1.5.6

reflection.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2007
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-07-11 09:39:08 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7297 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "gecode/kernel.hh"
00039 
00040 namespace Gecode { namespace Reflection {
00041 
00042   // Registry
00043 
00045   class Registry::RegistryObject {
00046   public:
00048     Support::SymbolMap<poster> posters;
00050     Support::SymbolMap<varCreator> varCreators;
00052     Support::SymbolMap<varConstrainer> varConstrainers;
00054     Support::SymbolMap<varUpdater> varUpdaters;
00056     Support::SymbolMap<varPrinter> varPrinters;
00058     Support::SymbolMap<varSpec> varSpecs;
00059   };
00060   
00061   Registry::Registry(void) : ro(new RegistryObject()) {}
00062 
00063   Registry::~Registry(void) { delete ro; }
00064 
00065   Registry& registry(void) {
00066     static Registry r;
00067     return r;
00068   }
00069   
00070   VarImpBase*
00071   Registry::createVar(Space* home, VarSpec& spec) const {
00072     varCreator vc = NULL;
00073     if (!ro->varCreators.get(spec.vti(),vc)) {
00074       throw Reflection::ReflectionException("VTI not found");
00075     }
00076     return vc(home, spec);
00077   }
00078 
00079   void
00080   Registry::constrainVar(Space* home, VarImpBase* v, VarSpec& spec) const {
00081     varConstrainer vc = NULL;
00082     if (!ro->varConstrainers.get(spec.vti(),vc)) {
00083       throw Reflection::ReflectionException("VTI not found");
00084     }
00085     vc(home, v, spec);
00086   }
00087 
00088   VarImpBase*
00089   Registry::updateVariable(Space* home, bool share, VarImpBase* v,
00090                            const Support::Symbol& vti) const {
00091     varUpdater vu = NULL;
00092     if (!ro->varUpdaters.get(vti,vu)) {
00093       throw Reflection::ReflectionException("VTI not found");
00094     }
00095     return vu(home, share, v);
00096   }
00097 
00098   std::ostream&
00099   Registry::printVariable(std::ostream& os, VarImpBase* v,
00100                           const Support::Symbol& vti) const {
00101     varPrinter vp = NULL;
00102     if (!ro->varPrinters.get(vti,vp)) {
00103       throw Reflection::ReflectionException("VTI not found");
00104     }
00105     return vp(os, v);
00106   }
00107 
00108   Arg*
00109   Registry::spec(const Space* home, VarMap& vm,
00110                  VarImpBase* v, const Support::Symbol& vti) const {
00111     varSpec vs = NULL;
00112     if (!ro->varSpecs.get(vti,vs)) {
00113       throw Reflection::ReflectionException("VTI not found");      
00114     }
00115     return vs(home, vm, v);
00116   }
00117 
00118   void
00119   Registry::post(Space* home, VarMap& vm, const ActorSpec& spec) const {
00120     poster p = NULL;
00121     if (!ro->posters.get(spec.ati(),p)) {
00122       throw Reflection::ReflectionException("Constraint not found");
00123     }
00124     p(home, vm, spec);
00125   }
00126 
00127   void
00128   Registry::add(Support::Symbol vti, varCreator vc) {
00129     ro->varCreators.put(vti, vc);
00130   }
00131 
00132   void
00133   Registry::add(Support::Symbol vti, varConstrainer vc) {
00134     ro->varConstrainers.put(vti, vc);
00135   }
00136 
00137   void
00138   Registry::add(Support::Symbol vti, varUpdater vu) {
00139     ro->varUpdaters.put(vti, vu);
00140   }
00141 
00142   void
00143   Registry::add(Support::Symbol vti, varPrinter vp) {
00144     ro->varPrinters.put(vti, vp);
00145   }
00146 
00147   void
00148   Registry::add(Support::Symbol vti, varSpec vs) {
00149     ro->varSpecs.put(vti, vs);
00150   }
00151 
00152   void
00153   Registry::add(const Support::Symbol& id, poster p) {
00154     ro->posters.put(id, p);
00155   }
00156 
00157   void
00158   Registry::print(std::ostream&) {
00159   }
00160 
00161   /*
00162    * Arguments
00163    *
00164    */
00165 
00166   Arg::Arg(argtype t0) : t(t0) {}
00167   
00168   bool
00169   Arg::isInt(void) const {
00170     return t == INT_ARG;
00171   }
00172   int
00173   Arg::toInt(void) const {
00174     if (!isInt())
00175       throw ReflectionException("not an IntArg");
00176     return arg1.i;
00177   }
00178   Arg*
00179   Arg::newInt(int i) {
00180     Arg* ret = new Arg(INT_ARG);
00181     ret->arg1.i = i;
00182     return ret;
00183   }
00184   void
00185   Arg::initInt(int i) {
00186     t = INT_ARG;
00187     arg1.i = i;
00188   }
00189 
00190   bool
00191   Arg::isVar(void) const {
00192     return (t == VAR_ARG);
00193   }
00194   int
00195   Arg::toVar(void) const {
00196     if (!isVar())
00197       throw ReflectionException("not a VarArg");
00198     return arg1.i;
00199   }
00200   Arg*
00201   Arg::newVar(int i) {
00202     Arg* ret = new Arg(VAR_ARG);
00203     ret->arg1.i = i;
00204     return ret;
00205   }
00206   void
00207   Arg::initVar(int i) {
00208     t = VAR_ARG;
00209     arg1.i = i;
00210   }
00211 
00212   bool
00213   Arg::isArray(void) const {
00214     return (t == ARRAY_ARG);
00215   }
00216   ArrayArg*
00217   Arg::toArray(void) {
00218     if (!isArray())
00219       throw ReflectionException("not an ArrayArg");
00220     return static_cast<ArrayArg*>(this);
00221   }
00222   const ArrayArg*
00223   Arg::toArray(void) const {
00224     if (!isArray())
00225       throw ReflectionException("not an ArrayArg");
00226     return static_cast<const ArrayArg*>(this);
00227   }
00228   ArrayArg*
00229   Arg::newArray(int n) {
00230     Arg* ret = new Arg(ARRAY_ARG);
00231     ret->arg1.i = n;
00232     if (n > 0)
00233       ret->arg2.aa = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*n));
00234     else
00235       ret->arg2.aa = NULL;
00236     return static_cast<ArrayArg*>(ret);
00237   }
00238   void
00239   Arg::initArray(int n) {
00240     t = ARRAY_ARG;
00241     arg1.i = n;
00242     arg2.aa = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*n));
00243   }
00244 
00245   bool
00246   Arg::isIntArray(void) const {
00247     return (t == INT_ARRAY_ARG);
00248   }
00249   IntArrayArg*
00250   Arg::toIntArray(void) {
00251     if (!isIntArray())
00252       throw ReflectionException("not an IntArrayArg");
00253     return static_cast<IntArrayArg*>(this);
00254   }
00255   const IntArrayArg*
00256   Arg::toIntArray(void) const {
00257     if (!isIntArray())
00258       throw ReflectionException("not an IntArrayArg");
00259     return static_cast<const IntArrayArg*>(this);
00260   }
00261   IntArrayArg*
00262   Arg::newIntArray(int n) {
00263     Arg* ret = new Arg(INT_ARRAY_ARG);
00264     ret->arg1.i = n;
00265     if (n > 0)
00266       ret->arg2.ia = static_cast<int*>(Memory::malloc(sizeof(int)*n));
00267     else
00268       ret->arg2.ia = NULL;
00269     return static_cast<IntArrayArg*>(ret);
00270   }
00271   void
00272   Arg::initIntArray(int n) {
00273     t = INT_ARRAY_ARG;
00274     arg1.i = n;
00275     arg2.ia = static_cast<int*>(Memory::malloc(sizeof(int)*n));
00276   }
00277 
00278   bool
00279   Arg::isString(void) const {
00280     return (t == STRING_ARG);
00281   }
00282   const char*
00283   Arg::toString(void) const {
00284     if (!isString())
00285       throw ReflectionException("not a StringArg");
00286     return arg1.s;
00287   }
00288 
00289 #if defined(_MSC_VER)
00290 #define strdup _strdup
00291 #endif
00292 
00293   Arg*
00294   Arg::newString(const char* s) {
00295     Arg* ret = new Arg(STRING_ARG);
00296     ret->arg1.s = strdup(s);
00297     return ret;    
00298   }
00299   void
00300   Arg::initString(const char* s) {
00301     t = STRING_ARG;
00302     arg1.s = strdup(s);
00303   }
00304 
00305 #if defined(_MSC_VER)
00306 #undef strdup
00307 #endif
00308 
00309   bool
00310   Arg::isPair(void) const {
00311     return (t == PAIR_ARG);
00312   }
00313   Arg*
00314   Arg::first(void) {
00315     if (!isPair())
00316       throw ReflectionException("not a PairArg");
00317     return arg1.first;
00318   }
00319   const Arg*
00320   Arg::first(void) const {
00321     if (!isPair())
00322       throw ReflectionException("not a PairArg");
00323     return arg1.first;
00324   }
00325   Arg*
00326   Arg::second(void) {
00327     if (!isPair())
00328       throw ReflectionException("not a PairArg");
00329     return arg2.second;
00330   }
00331   const Arg*
00332   Arg::second(void) const {
00333     if (!isPair())
00334       throw ReflectionException("not a PairArg");
00335     return arg2.second;
00336   }
00337   Arg*
00338   Arg::newPair(Arg* a, Arg* b) {
00339     Arg* ret = new Arg(PAIR_ARG);
00340     ret->arg1.first = a;
00341     ret->arg2.second = b;
00342     return ret;
00343   }
00344   void
00345   Arg::initPair(Arg* a, Arg* b) {
00346     t = PAIR_ARG;
00347     arg1.first = a;
00348     arg2.second = b;
00349   }
00350 
00351   bool
00352   Arg::isSharedObject(void) const {
00353     return (t == SHARED_OBJECT_ARG);
00354   }
00355   Arg*
00356   Arg::toSharedObject(void) {
00357     if (!isSharedObject())
00358       throw ReflectionException("not a SharedObjectArg");
00359     return arg1.first;
00360   }
00361   const Arg*
00362   Arg::toSharedObject(void) const {
00363     if (!isSharedObject())
00364       throw ReflectionException("not a SharedObjectArg");
00365     return arg1.first;
00366   }
00367   Arg*
00368   Arg::newSharedObject(Arg* a) {
00369     Arg* ret = new Arg(SHARED_OBJECT_ARG);
00370     ret->arg1.first = a;
00371     return ret;
00372   }
00373   void
00374   Arg::initSharedObject(Arg* a) {
00375     t = SHARED_OBJECT_ARG;
00376     arg1.first = a;
00377   }
00378   
00379   bool
00380   Arg::isSharedReference(void) const {
00381     return (t == SHARED_REF_ARG);
00382   }
00383   int
00384   Arg::toSharedReference(void) const {
00385     if (!isSharedReference())
00386       throw ReflectionException("not a SharedReferenceArg");
00387     return arg1.i;
00388   }
00389   Arg*
00390   Arg::newSharedReference(int ref) {
00391     Arg* ret = new Arg(SHARED_REF_ARG);
00392     ret->arg1.i = ref;
00393     return ret;
00394   }
00395   void
00396   Arg::initSharedReference(int ref) {
00397     t = SHARED_REF_ARG;
00398     arg1.i = ref;
00399   }
00400 
00401   Arg::~Arg(void) {
00402     switch (t) {
00403     case ARRAY_ARG:
00404       for (int i=arg1.i; i--;)
00405         delete arg2.aa[i];
00406       if (arg2.aa != NULL)
00407         Memory::free(arg2.aa);
00408       break;
00409     case INT_ARRAY_ARG:
00410       if (arg2.ia != NULL)
00411         Memory::free(arg2.ia);
00412       break;
00413     case PAIR_ARG:
00414       delete arg1.first;
00415       delete arg2.second;
00416       break;
00417     case STRING_ARG:
00418       ::free(arg1.s);
00419       break;
00420     case SHARED_OBJECT_ARG:
00421       delete arg1.first;
00422       break;
00423     default:
00424       break;
00425     }
00426   }
00427 
00428   const Arg*
00429   ArrayArg::operator[](int i) const {
00430     if (i >= arg1.i)
00431       throw ReflectionException("Array index out of range");
00432     return arg2.aa[i];
00433   }
00434   Arg*&
00435   ArrayArg::operator[](int i) {
00436     if (i >= arg1.i)
00437       throw ReflectionException("Array index out of range");
00438     return arg2.aa[i];
00439   }
00440   int
00441   ArrayArg::size(void) const {
00442     return arg1.i;
00443   }
00444 
00445   const int&
00446   IntArrayArg::operator[](int i) const {
00447     if (i >= arg1.i)
00448       throw ReflectionException("Array index out of range");
00449     return arg2.ia[i];
00450   }
00451   int&
00452   IntArrayArg::operator[](int i) {
00453     if (i >= arg1.i)
00454       throw ReflectionException("Array index out of range");
00455     return arg2.ia[i];
00456   }
00457   int
00458   IntArrayArg::size(void) const {
00459     return arg1.i;
00460   }
00461 
00462   IntArrayArgRanges::IntArrayArgRanges(Reflection::IntArrayArg* a0) 
00463     : a(a0), n(0) {}
00464 
00465   bool
00466   IntArrayArgRanges::operator()(void) { return n < a->size(); }
00467 
00468   void
00469   IntArrayArgRanges::operator++(void) { n += 2; }
00470 
00471   int
00472   IntArrayArgRanges::min(void) const { return (*a)[n]; }
00473 
00474   int
00475   IntArrayArgRanges::max(void) const { return (*a)[n+1]; }
00476 
00477   unsigned int
00478   IntArrayArgRanges::width(void) const { 
00479     return static_cast<unsigned int>(max() - min()) + 1; 
00480   }
00481 
00482   //
00483   // VarSpec
00484   //
00485 
00487   class VarSpec::Domain {
00488   private:
00490     Arg* _dom;
00491   public:
00493     Support::Symbol _vti;
00495     Support::Symbol _n;
00497     int r;
00499     Arg* dom(void) const;
00501     bool assigned(void) const;
00503     Domain(Support::Symbol vti, Arg* domain, bool assigned);
00505     ~Domain(void);
00506   };
00507 
00508   /*
00509    * Variable specifications
00510    *
00511    */
00512 
00513   inline
00514   VarSpec::Domain::Domain(Support::Symbol vti, Arg* domain, bool assigned)
00515   : _dom(assigned ? static_cast<Arg*>(Support::mark(domain)) : domain),
00516     _vti(vti),
00517     r(1) {}
00518 
00519   inline
00520   VarSpec::Domain::~Domain(void) {
00521     if (Support::marked(_dom))
00522       delete static_cast<Arg*>(Support::unmark(_dom));
00523     else
00524       delete _dom;
00525   }
00526 
00527   inline Arg*
00528   VarSpec::Domain::dom(void) const {
00529     if (Support::marked(_dom))
00530       return static_cast<Arg*>(Support::unmark(_dom));
00531     else
00532       return _dom;    
00533   }
00534 
00535   inline bool
00536   VarSpec::Domain::assigned(void) const {
00537     return Support::marked(_dom);
00538   }
00539 
00540   VarSpec::VarSpec(void) : _dom(NULL) {}
00541   
00542   VarSpec::VarSpec(Support::Symbol vti, Arg* dom, bool assigned) 
00543   : _dom(new Domain(vti,dom,assigned)) {}
00544 
00545   VarSpec::VarSpec(const VarSpec& s) : _dom(s._dom) {
00546     if (_dom)
00547       _dom->r++;
00548   }
00549   
00550   const VarSpec&
00551   VarSpec::operator=(const VarSpec& s) {
00552     if (this != &s) {
00553       if (_dom && --_dom->r == 0)
00554         delete _dom;
00555       _dom = s._dom;
00556       if (_dom)
00557         _dom->r++;
00558     }
00559     return *this;
00560   }
00561   
00562   VarSpec::~VarSpec(void) {
00563     if (_dom && --_dom->r == 0)
00564       delete _dom;
00565   }
00566 
00567   void
00568   VarSpec::name(const Support::Symbol& n) {
00569     if (_dom == NULL)
00570       throw ReflectionException("Empty VarSpec");
00571     _dom->_n = n;
00572   }
00573   
00574   Support::Symbol
00575   VarSpec::name(void) const {
00576     if (_dom == NULL)
00577       throw ReflectionException("Empty VarSpec");
00578     return _dom->_n;
00579   }
00580 
00581   bool
00582   VarSpec::hasName(void) const {
00583     if (_dom == NULL)
00584       throw ReflectionException("Empty VarSpec");
00585     return !_dom->_n.empty();
00586   }
00587 
00588   Support::Symbol
00589   VarSpec::vti(void) const {
00590     if (_dom == NULL)
00591       throw ReflectionException("Empty VarSpec");
00592     return _dom->_vti;
00593   }
00594 
00595   Arg*
00596   VarSpec::dom(void) const {
00597     if (_dom == NULL)
00598       throw ReflectionException("Empty VarSpec");
00599     return _dom->dom();
00600   }
00601 
00602   bool
00603   VarSpec::assigned(void) const {
00604     if (_dom == NULL)
00605       throw ReflectionException("Empty VarSpec");
00606     return _dom->assigned();    
00607   }
00608 
00609   //
00610   // ActorSpec
00611   //
00612 
00614   class ActorSpec::Arguments {
00615   public:
00617     Support::Symbol _ati;
00619     int   size;
00621     int   n;
00623     Arg** a;
00625     int queue;
00627     int r;
00629     Arguments(const Support::Symbol&);
00631     ~Arguments(void);
00632   };
00633 
00634   /*
00635    * Actor specifications
00636    *
00637    */
00638 
00639   inline
00640   ActorSpec::Arguments::Arguments(const Support::Symbol& ati)
00641    :  _ati(ati), size(4), n(0), r(1) {
00642      a = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*size));
00643   }
00644 
00645   inline
00646   ActorSpec::Arguments::~Arguments(void) {
00647     for (int i=n; i--;)
00648       delete a[i];
00649     Memory::free(a);
00650   }
00651 
00652   void
00653   ActorSpec::resize(void) {
00654     assert(_args != NULL);
00655     _args->size = _args->size * 3 / 2;
00656     Arg** newargs =
00657       static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*_args->size));
00658     for (int i=_args->n; i--;)
00659       newargs[i] = _args->a[i];
00660     Memory::free(_args->a);
00661     _args->a = newargs;
00662   }
00663 
00664   ActorSpec::ActorSpec(void) : _args(NULL) {}
00665 
00666   ActorSpec::ActorSpec(const Support::Symbol& ati) {
00667     _args = new Arguments(ati);
00668   }
00669 
00670   ActorSpec::ActorSpec(const ActorSpec& s) : _args(s._args) {
00671     if (_args != NULL)
00672       _args->r++;
00673   }
00674   
00675   const ActorSpec&
00676   ActorSpec::operator=(const ActorSpec& s) {
00677     if (this != &s) {
00678       if (_args && --_args->r == 0)
00679         delete _args;
00680       _args = s._args;
00681       if (_args)
00682         _args->r++;
00683     }
00684     return *this;
00685   }
00686 
00687   Arg*
00688   ActorSpec::operator[](int i) const {
00689     if (_args == NULL || i < 0 || i >= _args->n)
00690       throw ReflectionException("Array index out of range");
00691     return _args->a[i];
00692   }
00693 
00694   int
00695   ActorSpec::noOfArgs(void) const {
00696     return _args == NULL ? 0 : _args->n;
00697   }
00698 
00699   void
00700   ActorSpec::checkArity(int n) const {
00701     if (_args == NULL || _args->n != n) {
00702       throw ReflectionException("Illegal arity in ActorSpec");
00703     }
00704   }
00705 
00706   Support::Symbol
00707   ActorSpec::ati(void) const {
00708     if (_args == NULL)
00709       throw ReflectionException("Empty ActorSpec");
00710     return _args->_ati;
00711   }
00712 
00713   bool
00714   ActorSpec::isBranching(void) const {
00715     if (_args == NULL)
00716       throw ReflectionException("Empty ActorSpec");
00717     return _args->queue < 0;
00718   }
00719 
00720   int
00721   ActorSpec::queue(void) const {
00722     if (_args == NULL)
00723       throw ReflectionException("Empty ActorSpec");
00724     return _args->queue-1;
00725   }
00726 
00727   unsigned int
00728   ActorSpec::branchingId(void) const {
00729     if (_args == NULL)
00730       throw ReflectionException("Empty ActorSpec");
00731     assert(isBranching());
00732     return static_cast<unsigned int>(-_args->queue-1);
00733   }
00734 
00735   ActorSpec::~ActorSpec(void) {
00736     if (_args && --_args->r == 0)
00737       delete _args;
00738   }
00739 
00740   void
00741   ActorSpec::add(Arg* arg) {
00742     if (_args == NULL)
00743       throw ReflectionException("Empty ActorSpec");
00744     if (_args->n == _args->size)
00745       resize();
00746     _args->a[_args->n] = arg;
00747     _args->n++;
00748   }
00749 
00750   void
00751   ActorSpec::queue(int q) {
00752     if (_args == NULL)
00753       throw ReflectionException("Empty ActorSpec");
00754     _args->queue = q;
00755   }
00756 
00757   /*
00758    * Branch specification
00759    *
00760    */
00761    
00763   class BranchingSpec::Arguments {
00764   public:
00766     unsigned int   n;
00768     Arg** a;
00770     unsigned int id;
00772     int r;
00774     Arguments(unsigned int id, unsigned int a);
00776     ~Arguments(void);
00777   };
00778 
00779   inline
00780   BranchingSpec::Arguments::Arguments(unsigned int id0, unsigned int n0)
00781    : n(n0), id(id0), r(1) {
00782      a = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*n));
00783      for (unsigned int i=n; i--;)
00784        a[i] = NULL;
00785   }
00786 
00787   inline
00788   BranchingSpec::Arguments::~Arguments(void) {
00789     for (unsigned int i=n; i--;)
00790       delete a[i];
00791     Memory::free(a);
00792   }
00793   
00794   BranchingSpec::BranchingSpec(void) : _args(NULL) {}
00795   
00796   BranchingSpec::BranchingSpec(const BranchingDesc* d) {
00797     _args = new Arguments(d->id(), d->alternatives());
00798   }
00799 
00800   BranchingSpec::BranchingSpec(const BranchingSpec& s) : _args(s._args) {
00801     if (_args)
00802       _args->r++;
00803   }
00804   
00805   const BranchingSpec&
00806   BranchingSpec::operator=(const BranchingSpec& s) {
00807     if (this != &s) {
00808       if (_args && --_args->r == 0)
00809         delete _args;
00810       _args = s._args;
00811       if (_args)
00812         _args->r++;
00813     }
00814     return *this;
00815   }
00816 
00817   Arg*
00818   BranchingSpec::operator[](int i) const {
00819     if (_args == NULL || i < 0 || static_cast<unsigned int>(i) >= _args->n)
00820       throw ReflectionException("Array index out of range");
00821     return _args->a[i];
00822   }
00823 
00824   Arg*&
00825   BranchingSpec::operator[](int i) {
00826     if (_args == NULL || i < 0 || static_cast<unsigned int>(i) >= _args->n)
00827       throw ReflectionException("Array index out of range");
00828     return _args->a[i];
00829   }
00830 
00831   BranchingSpec::~BranchingSpec(void) {
00832     if (_args && --_args->r == 0)
00833       delete _args;
00834   }
00835   
00836   bool
00837   BranchingSpec::createdBy(const ActorSpec& b) const {
00838     if (!b.isBranching())
00839       throw ReflectionException("ActorSpec does not belong to a Branching");
00840     return _args != NULL && _args->id == b.branchingId();
00841   }
00842 
00843   unsigned int
00844   BranchingSpec::alternatives(void) const {
00845     return _args == NULL ? 0 : _args->n;
00846   }
00847   
00848 
00849   /*
00850    * Specification iterator
00851    *
00852    */
00853    
00854   bool
00855   ActorSpecIter::operator()(void) const {
00856     return cur != &s->a_actors;
00857   }
00858 
00859   void
00860   ActorSpecIter::operator++(void) {
00861     cur = cur->next();
00862     while (active > &s->pc.p.queue[0] && (cur == active)) {
00863       active--;
00864       cur = active;
00865       cur = cur->next();
00866     }
00867     if (active == &s->pc.p.queue[0] && cur == active) {
00868       active--;
00869       cur = s->a_actors.next();
00870     }
00871     if (cur == s->b_commit)
00872       isBranching = true;
00873   }
00874 
00875   ActorSpecIter::ActorSpecIter(const Space* s0, VarMap& m0)
00876   : m(&m0), s(s0),
00877     active(s0->pc.p.active == NULL ?
00878            &s->pc.p.queue[PC_MAX] : s0->pc.p.active),
00879     cur(active),
00880     isBranching(false) {
00881     if (s->stable() && !s->failed())
00882       cur = &s->a_actors;
00883     ++(*this);
00884   }
00885 
00886   ActorSpec
00887   ActorSpecIter::actor(void) const {
00888     ActorSpec spec = static_cast<const Actor*>(cur)->spec(s,*m);
00889     if (isBranching)
00890       spec.queue(-1-static_cast<const Branching*>(cur)->id);
00891     else
00892       spec.queue( (active - &s->pc.p.queue[0]) + 1);
00893     return spec;
00894   }
00895 
00896   Unreflector::Unreflector(Space* home0, Reflection::VarMap& m0)
00897     : home(home0), m(m0) {}
00898 
00899   Unreflector::~Unreflector(void) {}
00900     
00901   Reflection::VarMap&
00902   Unreflector::varMap(void) const {
00903     return m;
00904   }
00905 
00906   void
00907   Unreflector::var(Reflection::VarSpec& spec) {
00908     VarImpBase* vb = NULL;
00909     if (!spec.name().empty() &&
00910         (vb = m.varImpBase(spec.name())) != NULL) {
00911       // TODO: assert that spec and original var are compatible,
00912       // constrain domain of var to spec
00913       Reflection::registry().constrainVar(home, vb, spec);
00914     } else {
00915       vb = Reflection::registry().createVar(home, spec);
00916     }
00917     (void) m.put(vb, new Reflection::VarSpec(spec));
00918   }
00919 
00920   void
00921   Unreflector::post(Reflection::ActorSpec& spec) {
00922     Reflection::registry().post(home, m, spec);
00923   }
00924 
00925   /* Generic variable */
00926   
00927   void
00928   Var::update(Space* home, bool share, Var& v) {
00929     new (&_vti) Support::Symbol(v._vti);
00930     _var = registry().updateVariable(home, share, v._var, v._vti);
00931   }
00932 
00933   std::ostream&
00934   Var::print(std::ostream& os) const {
00935     return registry().printVariable(os, _var, _vti);
00936   }
00937   
00938   Arg*
00939   Var::spec(const Space* home, VarMap& vm) const {
00940     return registry().spec(home, vm, _var, _vti);
00941   }
00942 
00943 }}
00944 
00945 std::ostream&
00946 operator<<(std::ostream& os, const Gecode::Reflection::Var& v) {
00947   return v.print(os);
00948 }
00949 
00950 
00951 // STATISTICS: kernel-other