var-map.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "gecode/kernel.hh"
00039
00040 namespace Gecode { namespace Reflection {
00041
00042
00043
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
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