toulbar2
tb2store.hpp
1 
24 #ifndef TB2STORE_HPP_
25 #define TB2STORE_HPP_
26 
27 #include "core/tb2types.hpp"
28 
29 #ifndef NUMBERJACK
30 #ifdef BOOST
31 #include <boost/version.hpp>
32 #if (BOOST_VERSION >= 105600)
33 #include <boost/type_index.hpp>
34 #else
35 #include <typeinfo>
36 #endif
37 #else
38 #include <typeinfo>
39 #endif
40 #endif
41 
42 template <class T>
43 class BTList;
44 template <class T>
45 class DLink;
46 class Constraint;
47 class Variable;
48 class Separator;
49 class ConstraintLink;
50 
51 /*
52  * Storable stack
53  *
54  */
55 template <class T, class V>
56 class StoreStack {
57  T** pointers;
58  V* content;
59  ptrdiff_t index;
60  ptrdiff_t indexMax;
61  ptrdiff_t base;
62 
63  // make it private because we don't want copy nor assignment
64  StoreStack(const StoreStack& s);
65  StoreStack& operator=(const StoreStack& s);
66 
67 public:
68  StoreStack(int powbckmemory = STORE_SIZE)
69  {
70  if (pow(2., powbckmemory) >= SIZE_MAX) {
71  cerr << "command-line initial memory size parameter " << powbckmemory << " power of two too large!" << endl;
72  exit(EXIT_FAILURE);
73  }
74  indexMax = (ptrdiff_t)pow(2., powbckmemory);
75  pointers = new T*[indexMax];
76  content = new V[indexMax];
77  index = 0;
78  base = 0;
79  if (ToulBar2::verbose > 0) {
80  cout << "c " << indexMax * (sizeof(V) + sizeof(T*)) << " Bytes allocated for "
81 #ifndef NUMBERJACK
82 #if (BOOST_VERSION >= 105600)
83  << boost::typeindex::type_id<T>().pretty_name()
84 #else
85  << typeid(T).name()
86 #endif
87 #endif
88  << " stack." << endl;
89  }
90  }
91 
92  ~StoreStack()
93  {
94  delete[] pointers;
95  delete[] content;
96  }
97 
98  void realloc()
99  {
100  T** newpointers = new T*[indexMax * 2];
101  V* newcontent = new V[indexMax * 2];
102  if (!newpointers || !newcontent) {
103  cerr
104 #ifndef NUMBERJACK
105 #if (BOOST_VERSION >= 105600)
106  << boost::typeindex::type_id<T>().pretty_name()
107 #else
108  << typeid(T).name()
109 #endif
110 #endif
111  << " stack out of memory!" << endl;
112  exit(EXIT_FAILURE);
113  }
114  std::copy(pointers, pointers + indexMax, newpointers);
115  std::copy(content, content + indexMax, newcontent);
116 
117  delete[] pointers;
118  delete[] content;
119  pointers = newpointers;
120  content = newcontent;
121  indexMax *= 2;
122  if (ToulBar2::verbose >= 0) {
123  cout << "c " << indexMax * (sizeof(V) + sizeof(T*)) << " Bytes allocated for "
124 #ifndef NUMBERJACK
125 #if (BOOST_VERSION >= 105600)
126  << boost::typeindex::type_id<T>().pretty_name()
127 #else
128  << typeid(T).name()
129 #endif
130 #endif
131  << " stack." << endl;
132  }
133  }
134 
135  void store(T* x, V y)
136  {
137  if (index > 0) {
138  index++;
139  if (index >= indexMax)
140  realloc();
141  content[index] = y;
142  pointers[index] = x;
143  }
144  }
145 
146  void store(T* x)
147  {
148  if (index > 0) {
149  index++;
150  if (index >= indexMax)
151  realloc();
152  content[index] = *x;
153  pointers[index] = x;
154  }
155  }
156 
157  void store()
158  {
159  index++;
160  if (index >= indexMax)
161  realloc();
162  pointers[index] = (T*)(intptr_t)base;
163  base = index;
164  }
165 
166  // void restore(int **adr, int *val, ptrdiff_t x) {
167  // *adr[x] = val[x];
168  // }
169 
170  void restore(Value** adr, Value* val, ptrdiff_t x)
171  {
172  *adr[x] = val[x];
173  }
174 
175 #ifndef INT_COST
176  void restore(Cost** adr, Cost* val, ptrdiff_t x)
177  {
178  *adr[x] = val[x];
179  }
180 #endif
181 
182  void restore(BigInteger** adr, BigInteger* val, ptrdiff_t x)
183  {
184  *adr[x] = val[x];
185  }
186  template <class Q>
187  void restore(BTList<Q>** l, DLink<Q>** elt, ptrdiff_t& x);
188 
189  void restore()
190  {
191  if (index > 0) { // do nothing if already at depth = 0
192  ptrdiff_t x, y;
193 
194  x = index + 1;
195  y = base;
196  while (--x != y) {
197  restore(pointers, content, x);
198  }
199 
200  index = y - 1;
201  base = (ptrdiff_t)pointers[y];
202  }
203  }
204 };
205 
206 /*
207  * Storable basic types
208  */
209 template <class T>
210 class StoreBasic {
211  T v;
212 
213 public:
214  StoreBasic(T vv)
215  : v(vv)
216  {
217  }
218 
219  operator T() const
220  {
221  return v;
222  }
223 
224  StoreBasic(const StoreBasic& elt)
225  : v(elt.v)
226  {
227  }
228 
229  static void store() { mystore.store(); };
230  static void restore() { mystore.restore(); };
231 
232  StoreBasic& operator=(const StoreBasic& elt)
233  {
234  if (&elt != this) {
235  mystore.store(&v);
236  v = elt.v;
237  }
238  return *this;
239  }
240 
241  StoreBasic& operator=(const T vv)
242  {
243  mystore.store(&v);
244  v = vv;
245  return *this;
246  }
247  StoreBasic& operator+=(const T vv)
248  {
249  mystore.store(&v);
250  v += vv;
251  return *this;
252  }
253  StoreBasic& operator-=(const T vv)
254  {
255  mystore.store(&v);
256  v -= vv;
257  return *this;
258  }
259 
260  static StoreStack<T, T> mystore;
261 };
262 
263 template <class T>
264 StoreStack<T, T> StoreBasic<T>::mystore(STORE_SIZE);
265 
266 typedef StoreBasic<Value> StoreValue;
267 typedef StoreValue StoreInt;
268 typedef StoreBasic<Cost> StoreCost;
269 typedef StoreBasic<BigInteger> StoreBigInteger;
270 
271 /*
272  * Container for all storable stacks
273  */
274 class Store {
275 protected:
276  virtual ~Store() = 0; // Trick to avoid any instantiation of Store
277 
278 public:
279  static int depth;
280  static StoreStack<BTList<Value>, DLink<Value>*> storeDomain;
281  static StoreStack<BTList<ConstraintLink>, DLink<ConstraintLink>*> storeConstraint;
282  static StoreStack<BTList<Variable*>, DLink<Variable*>*> storeVariable;
283  static StoreStack<BTList<Separator*>, DLink<Separator*>*> storeSeparator;
284 
286  static int getDepth()
287  {
288  return depth;
289  }
290 
292  static void store()
293  {
294  depth++;
295  StoreValue::store();
296  StoreCost::store();
297  StoreBigInteger::store();
298  storeDomain.store();
299  storeConstraint.store();
300  storeVariable.store();
301  storeSeparator.store();
302  }
303 
305  static void restore()
306  {
307  depth--;
308  StoreValue::restore();
309  StoreCost::restore();
310  StoreBigInteger::restore();
311  storeDomain.restore();
312  storeConstraint.restore();
313  storeVariable.restore();
314  storeSeparator.restore();
315  }
316 
318  static void restore(int newDepth)
319  {
320  assert(depth >= newDepth);
321  while (depth > newDepth)
322  restore();
323  }
324 };
325 
326 #define storeIndexList storeDomain
327 
328 #endif /*TB2STORE_HPP_*/
329 
330 /* Local Variables: */
331 /* c-basic-offset: 4 */
332 /* tab-width: 4 */
333 /* indent-tabs-mode: nil */
334 /* c-default-style: "k&r" */
335 /* End: */