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
42template <class T>
43class BTList;
44template <class T>
45class DLink;
46class Constraint;
47class Variable;
48class Separator;
49class ConstraintLink;
50
51/*
52 * Storable stack
53 *
54 */
55template <class T, class V>
56class 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
67public:
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 */
209template <class T>
210class StoreBasic {
211 T v;
212
213public:
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 && v != elt.v) {
235 mystore.store(&v);
236 v = elt.v;
237 }
238 return *this;
239 }
240
241 StoreBasic& operator=(const T vv)
242 {
243 if (v != vv) {
244 mystore.store(&v);
245 v = vv;
246 }
247 return *this;
248 }
249 StoreBasic& operator+=(const T vv)
250 {
251 if (vv != 0) {
252 mystore.store(&v);
253 v += vv;
254 }
255 return *this;
256 }
257 StoreBasic& operator-=(const T vv)
258 {
259 if (vv != 0) {
260 mystore.store(&v);
261 v -= vv;
262 }
263 return *this;
264 }
265
266 static StoreStack<T, T> mystore;
267};
268
269template <class T>
270StoreStack<T, T> StoreBasic<T>::mystore(STORE_SIZE);
271
272typedef StoreBasic<Value> StoreValue;
273typedef StoreValue StoreInt;
274typedef StoreBasic<Cost> StoreCost;
275typedef StoreBasic<BigInteger> StoreBigInteger;
276typedef StoreCost StoreLong;
277
278/*
279 * Container for all storable stacks
280 */
281class Store {
282protected:
283 virtual ~Store() = 0; // Trick to avoid any instantiation of Store
284
285public:
286 static int depth;
287 static StoreStack<BTList<Value>, DLink<Value>*> storeDomain;
288 static StoreStack<BTList<ConstraintLink>, DLink<ConstraintLink>*> storeConstraint;
289 static StoreStack<BTList<Variable*>, DLink<Variable*>*> storeVariable;
290 static StoreStack<BTList<Separator*>, DLink<Separator*>*> storeSeparator;
291
293 static int getDepth()
294 {
295 return depth;
296 }
297
299 static void store()
300 {
301 depth++;
302 StoreValue::store();
303 StoreCost::store();
304 StoreBigInteger::store();
305 storeDomain.store();
306 storeConstraint.store();
307 storeVariable.store();
308 storeSeparator.store();
309 }
310
312 static void restore()
313 {
314 depth--;
315 StoreValue::restore();
316 StoreCost::restore();
317 StoreBigInteger::restore();
318 storeDomain.restore();
319 storeConstraint.restore();
320 storeVariable.restore();
321 storeSeparator.restore();
322 }
323
325 static void restore(int newDepth)
326 {
327 assert(depth >= newDepth);
328 while (depth > newDepth)
329 restore();
330 }
331};
332
333#define storeIndexList storeDomain
334
335#endif /*TB2STORE_HPP_*/
336
337/* Local Variables: */
338/* c-basic-offset: 4 */
339/* tab-width: 4 */
340/* indent-tabs-mode: nil */
341/* c-default-style: "k&r" */
342/* End: */