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

var-map.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:38:30 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7296 $
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   /*
00043    * Variable maps
00044    *
00045    */
00046 
00048   class VarMap::VarMapObj {
00049   public:
00050     VarMapObj(void);
00052     Support::SymbolMap<VarImpBase*> nameToVar;
00054     Support::PtrMap<VarImpBase,Support::Symbol> varToName;
00056     Support::PtrMap<VarImpBase,int> m;
00058     Support::PtrMap<void,int>    sharedObjectMap;
00059 
00061     Support::DynamicArray<VarImpBase*>  vars;
00063     Support::DynamicArray<VarSpec*>  specs;
00065     Support::DynamicArray<void*>     sharedObjects;
00066 
00068     int n;
00070     int so;
00071 
00073     int r;
00074   };
00075 
00076   VarMap::VarMapObj::VarMapObj(void) : n(0), so(0), r(1) {}
00077 
00078   VarMap::VarMap(void) : vo(new VarMapObj()) {}
00079 
00080   VarMap::VarMap(const VarMap& v) : vo(v.vo) { vo->r++; }
00081 
00082   VarMap&
00083   VarMap::operator=(const VarMap& v) {
00084     if (this != &v) {
00085       if (--vo->r == 0) {
00086         for (int i=vo->n; i--;)
00087           delete vo->specs[i];
00088         delete vo;        
00089       }
00090       vo = v.vo;
00091       vo->r++;
00092     }
00093     return *this;
00094   }
00095 
00096   VarMap::~VarMap(void) {
00097     if (--vo->r == 0) {
00098       for (int i=vo->n; i--;)
00099         delete vo->specs[i];
00100       delete vo;
00101     }
00102   }
00103 
00104   int
00105   VarMap::size(void) const {
00106     return vo->n;
00107   }
00108   
00109   int
00110   VarMap::index(const VarImpBase* cx) const {
00111     int i;
00112     VarImpBase* x = const_cast<VarImpBase*>(cx);
00113     return vo->m.get(x,i) ? i : -1;
00114   }
00115 
00116   int
00117   VarMap::index(const Support::Symbol& n) const {
00118     VarImpBase* v;      
00119     return vo->nameToVar.get(n, v) ? index(v) : -1;
00120   }
00121 
00122   bool
00123   VarMap::nameIsKnown(const Support::Symbol& n) const {
00124     VarImpBase* v;
00125     return vo->nameToVar.get(n,v);
00126   }
00127 
00128   bool
00129   VarMap::hasName(const VarImpBase* cx) const {
00130     Support::Symbol s;
00131     VarImpBase* x = const_cast<VarImpBase*>(cx);
00132     return vo->varToName.get(x,s);
00133   }
00134 
00135   bool
00136   VarMap::hasName(int i) const {
00137     Support::Symbol s;
00138     return vo->varToName.get(vo->vars[i], s);
00139   }
00140 
00141   Support::Symbol
00142   VarMap::name(const VarImpBase* cx) const {
00143     Support::Symbol s;
00144     VarImpBase* x = const_cast<VarImpBase*>(cx);
00145     vo->varToName.get(x,s);
00146     return s;
00147   }
00148 
00149   Support::Symbol
00150   VarMap::name(int i) const {
00151     Support::Symbol s;
00152     vo->varToName.get(vo->vars[i],s);
00153     return s;
00154   }
00155 
00156   VarImpBase*
00157   VarMap::varImpBase(const Support::Symbol& n) const {
00158     VarImpBase* v;
00159     return vo->nameToVar.get(n,v) ? v : NULL;
00160   }
00161 
00162   VarImpBase*
00163   VarMap::varImpBase(int i) const {
00164     if (i<0 || i>=vo->n)
00165       throw ReflectionException("Variable not in VarMap");
00166     return vo->vars[i];
00167   }
00168 
00169   VarSpec&
00170   VarMap::spec(const VarImpBase* cx) const {
00171     int i;
00172     VarImpBase* x = const_cast<VarImpBase*>(cx);
00173     if (!vo->m.get(x,i))
00174       throw ReflectionException("Variable not in VarMap");
00175     return *vo->specs[i];
00176   }
00177 
00178   VarSpec&
00179   VarMap::spec(int i) const {
00180     if (i<0 || i>=vo->n)
00181       throw ReflectionException("Variable not in VarMap");
00182     return *vo->specs[i];
00183   }
00184 
00185   VarSpec&
00186   VarMap::spec(const Support::Symbol& n) const {
00187     return spec(varImpBase(n));
00188   }
00189 
00190   void
00191   VarMap::name(VarImpBase* x, const Support::Symbol& n) {
00192     VarImpBase* y;
00193     if (vo->nameToVar.get(n, y) && x != y)
00194       throw
00195         ReflectionException("Variable with the same name already in VarMap");
00196     vo->nameToVar.put(n, x);
00197     vo->varToName.put(x, n);
00198   }
00199 
00200   int
00201   VarMap::put(const VarImpBase* cx, VarSpec* spec) {
00202     VarImpBase* x = const_cast<VarImpBase*>(cx);
00203     int newIndex = vo->n++;
00204     vo->m.put(x, newIndex);
00205     vo->specs[newIndex] = spec;
00206     vo->vars[newIndex] = x;
00207     if (hasName(x)) {
00208       spec->name(name(x));
00209     } else if (spec != NULL && spec->hasName()) {
00210       vo->nameToVar.put(spec->name(), x);
00211       vo->varToName.put(x, spec->name());
00212     }
00213     return newIndex;
00214   }
00215   
00216   void
00217   VarMap::putMasterObject(void* obj) {
00218     vo->sharedObjectMap.put(obj, vo->so);
00219     vo->sharedObjects[vo->so++] = obj;
00220   }
00221 
00222   int
00223   VarMap::getSharedIndex(void* obj) const {
00224     int idx;
00225     if (vo->sharedObjectMap.get(obj, idx))
00226       return idx;
00227     return -1;
00228   }
00229   
00230   void*
00231   VarMap::getSharedObject(int i) const {
00232     assert(i < vo->so);
00233     return vo->sharedObjects[i];
00234   }
00235 
00236   Var
00237   VarMap::var(const Support::Symbol& n) const {
00238     return Var(varImpBase(n), spec(n).vti());
00239   }
00240 
00241   Var
00242   VarMap::var(int i) const {
00243     return Var(varImpBase(i), spec(i).vti());
00244   }
00245 
00246   /* Variable map iterator */
00247 
00248   VarMapIter::VarMapIter(VarMap& m0) : m(&m0), i(0) {}
00249 
00250   bool
00251   VarMapIter::operator()(void) const { return i<m->vo->n; }
00252 
00253   VarSpec&
00254   VarMapIter::spec(void) const { return *m->vo->specs[i]; }
00255 
00256   VarImpBase*
00257   VarMapIter::varImpBase(void) const { return m->vo->vars[i]; }
00258 
00259   void
00260   VarMapIter::operator++(void) { i++; }  
00261 
00262   Var
00263   VarMapIter::var(void) const {
00264     return Var(varImpBase(), spec().vti());
00265   }
00266 
00267 }}
00268 
00269 // STATISTICS: kernel-other