aGrUM  0.16.0
scheduleMultiDim_tpl.h
Go to the documentation of this file.
1 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 # include <sstream>
32 # include <string>
33 
34 # include <agrum/agrum.h>
35 
37 
38 namespace gum {
39 
41  template < typename GUM_SCALAR >
43  static Idx __abstract_id = 0;
44  return ++__abstract_id;
45  }
46 
48  template < typename GUM_SCALAR >
49  HashTable< Idx, const MultiDimImplementation< GUM_SCALAR >* >&
51  static HashTable< Idx, const MultiDimImplementation< GUM_SCALAR >* >
52  __multidims;
53 # ifdef GUM_DEBUG_MODE
54  // for debugging purposes, we should inform the aGrUM's debugger that
55  // the static hashtable used here will be removed at the end of the
56  // program's execution.
57  static bool first_time = true;
58 
59  if (first_time) {
60  first_time = false;
61  __debug__::__inc_deletion(
62  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__multidims);
63  }
64 
65 # endif /* GUM_DEBUG_MODE */
66  return __multidims;
67  }
68 
70  template < typename GUM_SCALAR >
71  HashTable< const MultiDimImplementation< GUM_SCALAR >*, Idx >&
73  static HashTable< const MultiDimImplementation< GUM_SCALAR >*, Idx >
74  __multidim_ids;
75 # ifdef GUM_DEBUG_MODE
76  // for debugging purposes, we should inform the aGrUM's debugger that
77  // the static hashtable used here will be removed at the end of the
78  // program's execution.
79  static bool first_time = true;
80 
81  if (first_time) {
82  first_time = false;
83  __debug__::__inc_deletion(
84  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__multidim_ids);
85  }
86 
87 # endif /* GUM_DEBUG_MODE */
88  return __multidim_ids;
89  }
90 
92  template < typename GUM_SCALAR >
94  static HashTable< Idx, Idx > __ids;
95 # ifdef GUM_DEBUG_MODE
96  // for debugging purposes, we should inform the aGrUM's debugger that
97  // the static hashtable used here will be removed at the end of the
98  // program's execution.
99  static bool first_time = true;
100 
101  if (first_time) {
102  first_time = false;
103  __debug__::__inc_deletion(
104  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__ids);
105  }
106 
107 # endif /* GUM_DEBUG_MODE */
108  return __ids;
109  }
110 
112  template < typename GUM_SCALAR >
113  HashTable< Idx, const Sequence< const DiscreteVariable* >* >&
115  static HashTable< Idx, const Sequence< const DiscreteVariable* >* > __vars;
116 # ifdef GUM_DEBUG_MODE
117  // for debugging purposes, we should inform the aGrUM's debugger that
118  // the static hashtable used here will be removed at the end of the
119  // program's execution.
120  static bool first_time = true;
121 
122  if (first_time) {
123  first_time = false;
124  __debug__::__inc_deletion(
125  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__vars);
126  }
127 
128 # endif /* GUM_DEBUG_MODE */
129  return __vars;
130  }
131 
133  template < typename GUM_SCALAR >
134  HashTable< Idx, Size >& ScheduleMultiDim< GUM_SCALAR >::__id2size() {
135  static HashTable< Idx, Size > __size;
136 # ifdef GUM_DEBUG_MODE
137  // for debugging purposes, we should inform the aGrUM's debugger that
138  // the static hashtable used here will be removed at the end of the
139  // program's execution.
140  static bool first_time = true;
141 
142  if (first_time) {
143  first_time = false;
144  __debug__::__inc_deletion(
145  "HashTable", __FILE__, __LINE__, "destructor of", (void*)&__size);
146  }
147 
148 # endif /* GUM_DEBUG_MODE */
149  return __size;
150  }
151 
153  template < typename GUM_SCALAR >
155  const MultiDimImplementation< GUM_SCALAR >& multidim) {
156  // for debugging purposes
157  GUM_CONSTRUCTOR(ScheduleMultiDim);
158 
159  // check whether the multidimImplementation has already been stored
160 
161  if (__multidim2id().exists(&multidim)) {
162  // get the id already allocated to the implementation
163  __id = __multidim2id().operator[](&multidim);
164 
165  // update the number of references of __id
166  HashTable< Idx, Idx >& refs = __id2refs();
167  ++refs[__id];
168  } else {
169  // assign a new id to the implementation
170  __id = __newId();
171 
172  // store the multidim into the set of all mappings id<->multidim
173  __id2multidim().insert(__id, &multidim);
174  __multidim2id().insert(&multidim, __id);
175 
176  // indicate that the id is currently used once
177  __id2refs().insert(__id, 1);
178 
179  // store the variables of the multidim
180  const Sequence< const DiscreteVariable* >* vars =
181  new Sequence< const DiscreteVariable* >(multidim.variablesSequence());
182  __id2vars().insert(__id, vars);
183 
184  // store the domain size of the multidim
185  __id2size().insert(__id, multidim.domainSize());
186  }
187  }
188 
190  template < typename GUM_SCALAR >
192  const MultiDimDecorator< GUM_SCALAR >& multidim) {
193  // for debugging purposes
194  GUM_CONSTRUCTOR(ScheduleMultiDim);
195 
196  const MultiDimImplementation< GUM_SCALAR >* impl = multidim.content();
197 
198  // check whether the multidimImplementation has already been stored
199 
200  if (__multidim2id().exists(impl)) {
201  // get the id already allocated to the implementation
202  __id = __multidim2id().operator[](impl);
203 
204  // update the number of references of __id
205  HashTable< Idx, Idx >& refs = __id2refs();
206  ++refs[__id];
207  } else {
208  // assign a new id to the implementation
209  __id = __newId();
210 
211  // store the multidim into the set of all mappings id<->multidim
212  __id2multidim().insert(__id, impl);
213  __multidim2id().insert(impl, __id);
214 
215  // indicate that the id is currently used once
216  __id2refs().insert(__id, 1);
217 
218  // store the variables of the multidim
219  const Sequence< const DiscreteVariable* >* vars =
220  new Sequence< const DiscreteVariable* >(multidim.variablesSequence());
221  __id2vars().insert(__id, vars);
222 
223  // store the domain size of the multidim
224  __id2size().insert(__id, multidim.domainSize());
225  }
226  }
227 
229  template < typename GUM_SCALAR >
231  const Sequence< const DiscreteVariable* >& vars) :
232  __id(__newId()) {
233  // for debugging purposes
234  GUM_CONSTRUCTOR(ScheduleMultiDim);
235 
236  // indicate that the id is currently used once
237  __id2refs().insert(__id, 1);
238 
239  // store the variables of the multidim
240  const Sequence< const DiscreteVariable* >* new_vars =
241  new Sequence< const DiscreteVariable* >(vars);
242  __id2vars().insert(__id, new_vars);
243 
244  // compute and store the domain size
245  Size size = 1;
246 
247  for (const auto var : *new_vars)
248  size *= var->domainSize();
249 
250  __id2size().insert(__id, size);
251  }
252 
254  template < typename GUM_SCALAR >
256  const ScheduleMultiDim< GUM_SCALAR >& from) :
257  __id(from.__id) {
258  // for debugging purposes
259  GUM_CONS_CPY(ScheduleMultiDim);
260 
261  // update the number of references of __id
263  ++refs[__id];
264  }
265 
267  template < typename GUM_SCALAR >
269  // for debugging purposes
270  GUM_DESTRUCTOR(ScheduleMultiDim);
271 
272  // get the number of scheduleMultiDims that reference the same id
274  Idx& nb_refs = refs[__id];
275 
276  if (nb_refs == 1) {
277  // remove the id and the multidimdecorator from the mappings
278  if (__id2multidim().exists(__id)) {
279  __multidim2id().erase(__id2multidim().operator[](__id));
280  __id2multidim().erase(__id);
281  }
282 
283  refs.erase(__id);
284 
285  delete __id2vars().operator[](__id);
286  __id2vars().erase(__id);
287  __id2size().erase(__id);
288  } else
289  --nb_refs;
290  }
291 
293  template < typename GUM_SCALAR >
294  ScheduleMultiDim< GUM_SCALAR >& ScheduleMultiDim< GUM_SCALAR >::
295  operator=(const ScheduleMultiDim< GUM_SCALAR >& from) {
296  // avoid self assignment
297  if (__id != from.__id) {
298  // remove the old id
300  Idx& nb_refs = refs[__id];
301 
302  if (nb_refs == 1) {
303  // remove the id and the multidimdecorator from the mappings
304  if (__id2multidim().exists(__id)) {
305  __multidim2id().erase(__id2multidim().operator[](__id));
306  __id2multidim().erase(__id);
307  }
308 
309  refs.erase(__id);
310 
311  delete __id2vars().operator[](__id);
312  __id2vars().erase(__id);
313  __id2size().erase(__id);
314  } else
315  --nb_refs;
316 
317  __id = from.__id;
318 
319  ++refs[__id];
320  }
321 
322  return *this;
323  }
324 
326  template < typename GUM_SCALAR >
328  operator==(const ScheduleMultiDim< GUM_SCALAR >& m) const {
329  return (__id == m.__id);
330  }
331 
333  template < typename GUM_SCALAR >
335  operator!=(const ScheduleMultiDim< GUM_SCALAR >& m) const {
336  return (__id != m.__id);
337  }
338 
341  template < typename GUM_SCALAR >
342  INLINE const MultiDimImplementation< GUM_SCALAR >&
344  return *(__id2multidim().operator[](__id));
345  }
346 
349  template < typename GUM_SCALAR >
350  INLINE bool ScheduleMultiDim< GUM_SCALAR >::isAbstract() const {
351  return !__id2multidim().exists(__id);
352  }
353 
355  template < typename GUM_SCALAR >
356  INLINE Idx ScheduleMultiDim< GUM_SCALAR >::id() const {
357  return __id;
358  }
359 
361  template < typename GUM_SCALAR >
362  INLINE const Sequence< const DiscreteVariable* >&
364  return *(__id2vars().operator[](__id));
365  }
366 
368  template < typename GUM_SCALAR >
370  return __id2size().operator[](__id);
371  }
372 
374  template < typename GUM_SCALAR >
376  const MultiDimImplementation< GUM_SCALAR >& m) {
377  // check whether the same Multidimimplementation has not already been
378  // wrapped with another ID. In this case, we shall throw a DuplicateElement
379  // exception
380  if (__multidim2id().exists(&m)) {
381  if (__multidim2id().operator[](&m) != __id) {
382  GUM_ERROR(DuplicateElement,
383  "the multidim table has already been "
384  "wrapped into a ScheduleMultidim with another id");
385  }
386  } else {
387  // here, the multidim has never been stored into a ScheduleMultiDim
388 
389  // if the current ScheduleMultiDim already contained a
390  // multidimImplementation
391  // we should remove it first and, then, add the new one
392  if (__id2multidim().exists(__id)) {
393  const MultiDimImplementation< GUM_SCALAR >* impl =
394  __id2multidim(). operator[](__id);
395 
396  if (impl == &m) return;
397 
398  __multidim2id().erase(impl);
399 
400  __id2multidim().operator[](__id) = &m;
401  } else {
402  // store the new multidim
403  __id2multidim().insert(__id, &m);
404  }
405 
406  __multidim2id().insert(&m, __id);
407 
408  // update the variables of the scheduleMultiDim
409  const Sequence< const DiscreteVariable* >& m_vars = m.variablesSequence();
410  Sequence< const DiscreteVariable* >* vars =
411  const_cast< Sequence< const DiscreteVariable* >* >(
412  __id2vars().operator[](__id));
413  *vars = m_vars;
414 
415  // update the size of the wrapper
416  __id2size().operator[](__id) = m.domainSize();
417  }
418  }
419 
421  template < typename GUM_SCALAR >
423  const MultiDimDecorator< GUM_SCALAR >& m) {
424  setMultiDim(*(m.content()));
425  }
426 
428  template < typename GUM_SCALAR >
429  std::string ScheduleMultiDim< GUM_SCALAR >::toString() const {
430  std::stringstream str;
431  str << "<";
432 
433  // get the pointer of the multidim if it exists
434 
435  try {
436  str << __id2multidim().operator[](__id);
437  } catch (NotFound&) { str << __id; }
438 
439  str << ">";
440 
441  return str.str();
442  }
443 
444 } /* namespace gum */
445 
446 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
const Sequence< const DiscreteVariable *> & variablesSequence() const
returns the set of variables involved in the multidim
static HashTable< const MultiDimImplementation< GUM_SCALAR > *, Idx > & __multidim2id()
returns the id corresponding to a given multidim
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
ScheduleMultiDim(const MultiDimImplementation< GUM_SCALAR > &)
constructs a ScheduleMultiDim containing an already built implementation
std::string toString() const
displays the content of the multidim
bool isAbstract() const
returns whether the ScheduleMultiDim contains a real multiDimImplementation
Idx id() const
returns the id of the ScheduleMultiDim
void erase(const Key &key)
Removes a given element from the hash table.
Size domainSize() const
returns the domain size of the multidim
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
bool operator!=(const ScheduleMultiDim< GUM_SCALAR > &) const
checks whether two ScheduleMultiDim are related to different tables
ScheduleMultiDim< GUM_SCALAR > & operator=(const ScheduleMultiDim< GUM_SCALAR > &)
copy operator
~ScheduleMultiDim()
destructor
const MultiDimImplementation< GUM_SCALAR > & multiDim() const
returns the multiDimImplementation actually contained in the ScheduleMultiDim
static HashTable< Idx, const Sequence< const DiscreteVariable *> *> & __id2vars()
returns a table with the variables of the table corresponding to id
static HashTable< Idx, Idx > & __id2refs()
returns a table indicating how many ScheduleMultiDim have the same id
static Idx __newId()
returns a new distinct ID for each abtract scheduleMultiDim
static HashTable< Idx, Size > & __id2size()
returns a table with the domain size of the table corresponding to id
Idx __id
the unique Id of the ScheduleMultiDim
static HashTable< Idx, const MultiDimImplementation< GUM_SCALAR > *> & __id2multidim()
returns a mapping from id to multidimImplementations
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
void setMultiDim(const MultiDimImplementation< GUM_SCALAR > &)
sets a new multiDimImplementation inside the wrapper
bool operator==(const ScheduleMultiDim< GUM_SCALAR > &) const
checks whether two ScheduleMultiDim are related to the same table
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55