aGrUM  0.16.0
idSet_tpl.h
Go to the documentation of this file.
1 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 
32 namespace gum {
33 
34  namespace learning {
35 
36 
38  template < template < typename > class ALLOC >
40  GUM_CONSTRUCTOR(IdSetIterator);
41  }
42 
43 
45  template < template < typename > class ALLOC >
46  INLINE IdSetIterator< ALLOC >::IdSetIterator(const IdSet< ALLOC >& idset) :
47  __seq(&(idset.ids())) {
48  GUM_CONSTRUCTOR(IdSetIterator);
49  }
50 
51 
53  template < template < typename > class ALLOC >
54  INLINE
55  IdSetIterator< ALLOC >::IdSetIterator(const IdSetIterator< ALLOC >& from) :
56  __seq(from.__seq),
57  __index(from.__index) {
58  GUM_CONS_CPY(IdSetIterator);
59  }
60 
61 
63  template < template < typename > class ALLOC >
64  INLINE IdSetIterator< ALLOC >::IdSetIterator(IdSetIterator< ALLOC >&& from) :
65  __seq(from.__seq), __index(from.__index) {
66  GUM_CONS_MOV(IdSetIterator);
67  }
68 
69 
71  template < template < typename > class ALLOC >
72  INLINE IdSetIterator< ALLOC >::~IdSetIterator() {
73  GUM_DESTRUCTOR(IdSetIterator);
74  }
75 
76 
78  template < template < typename > class ALLOC >
79  INLINE void IdSetIterator< ALLOC >::__gotoEnd() {
80  if (__seq != nullptr)
81  __index = __seq->size();
82  else
83  __index = std::size_t(0);
84  }
85 
86 
88  template < template < typename > class ALLOC >
89  INLINE IdSetIterator< ALLOC >& IdSetIterator< ALLOC >::
90  operator=(const IdSetIterator< ALLOC >& from) {
91  __seq = from.__seq;
92  __index = from.__index;
93  return *this;
94  }
95 
96 
98  template < template < typename > class ALLOC >
99  INLINE IdSetIterator< ALLOC >& IdSetIterator< ALLOC >::
100  operator=(IdSetIterator< ALLOC >&& from) {
101  __seq = from.__seq;
102  __index = from.__index;
103  return *this;
104  }
105 
106 
108  template < template < typename > class ALLOC >
110  return __seq->operator[](__index);
111  }
112 
113 
115  template < template < typename > class ALLOC >
116  INLINE bool IdSetIterator< ALLOC >::
117  operator!=(const IdSetIterator< ALLOC >& from) const {
118  return (__index != from.__index) || (__seq != from.__seq);
119  }
120 
121 
123  template < template < typename > class ALLOC >
124  INLINE bool IdSetIterator< ALLOC >::
125  operator==(const IdSetIterator< ALLOC >& from) const {
126  return !operator!=(from);
127  }
128 
129 
131  template < template < typename > class ALLOC >
132  INLINE IdSetIterator< ALLOC >& IdSetIterator< ALLOC >::operator++() {
133  ++__index;
134  return *this;
135  }
136 
137 
139  template < template < typename > class ALLOC >
140  INLINE IdSetIterator< ALLOC >& IdSetIterator< ALLOC >::
141  operator+=(const std::size_t i) {
142  __index += i;
143  return *this;
144  }
145 
146 
148  template < template < typename > class ALLOC >
149  IdSetIterator< ALLOC > IdSetIterator< ALLOC >::operator+(const std::size_t i) {
150  IdSetIterator< ALLOC > res(*this);
151  res += i;
152  return res;
153  }
154 
155 
157  template < template < typename > class ALLOC >
158  std::size_t IdSetIterator< ALLOC >::pos() const {
159  if (__seq == nullptr)
160  GUM_ERROR(UndefinedIteratorValue,
161  "The IdSet is empty, so its iterators have no position");
162  if (__index >= __seq->size())
163  GUM_ERROR(UndefinedIteratorValue,
164  "the IdSet iterator has no position because it reached "
165  "the set's end.");
166  return __index;
167  }
168 
169 
172 
173 
175  template < template < typename > class ALLOC >
176  INLINE typename IdSet< ALLOC >::allocator_type
177  IdSet< ALLOC >::getAllocator() const {
178  return *this;
179  }
180 
181 
183  template < template < typename > class ALLOC >
184  INLINE IdSet< ALLOC >::IdSet(
185  const typename IdSet< ALLOC >::allocator_type& alloc) :
186  ALLOC< NodeId >(alloc),
187  __end_safe(*this) {
188  GUM_CONSTRUCTOR(IdSet);
189  }
190 
191 
193  template < template < typename > class ALLOC >
194  INLINE IdSet< ALLOC >::IdSet(
195  const std::vector< NodeId, ALLOC< NodeId > >& ids,
196  const bool rhs_ids,
197  const bool ordered_ids,
198  const typename IdSet< ALLOC >::allocator_type& alloc) :
199  ALLOC< NodeId >(alloc),
200  __end_safe(*this) {
201  __ids.resize(ids.size());
202 
203  // if the rhs_ids should be considered as unordered, we sort them by
204  // increasing order so that we can compare easily two different rhs_ids
205  if (!ordered_ids) {
206  std::vector< NodeId, ALLOC< NodeId > > vect(ids);
207  std::sort(vect.begin(), vect.end());
208  for (const auto id : vect)
209  __ids << id;
210  } else {
211  for (const auto id : ids)
212  __ids << id;
213  }
214 
215  if (!rhs_ids) __nb_lhs_ids = __ids.size();
216 
217  // update the end iterator
218  __end_safe.__gotoEnd();
219 
220  GUM_CONSTRUCTOR(IdSet);
221  }
222 
223 
225  template < template < typename > class ALLOC >
226  INLINE IdSet< ALLOC >::IdSet(
227  NodeId var1,
228  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids,
229  const bool ordered_rhs_ids,
230  const typename IdSet< ALLOC >::allocator_type& alloc) :
231  ALLOC< NodeId >(alloc),
232  __nb_lhs_ids(std::size_t(1)), __end_safe(*this) {
233  __ids.resize(rhs_ids.size() + std::size_t(1));
234  __ids << var1;
235 
236  // if the rhs_ids should be considered as unordered, we sort them by
237  // increasing order so that we can compare easily two different rhs_ids
238  if (!ordered_rhs_ids) {
239  std::vector< NodeId, ALLOC< NodeId > > vect(rhs_ids);
240  std::sort(vect.begin(), vect.end());
241  for (const auto id : vect)
242  __ids << id;
243  } else {
244  for (const auto id : rhs_ids)
245  __ids << id;
246  }
247 
248  // update the end iterator
249  __end_safe.__gotoEnd();
250 
251  GUM_CONSTRUCTOR(IdSet);
252  }
253 
254 
256  template < template < typename > class ALLOC >
257  INLINE IdSet< ALLOC >::IdSet(
258  NodeId var1,
259  NodeId var2,
260  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids,
261  const bool ordered_lhs_vars,
262  const bool ordered_rhs_ids,
263  const typename IdSet< ALLOC >::allocator_type& alloc) :
264  ALLOC< NodeId >(alloc),
265  __nb_lhs_ids(std::size_t(2)), __end_safe(*this) {
266  __ids.resize(rhs_ids.size() + std::size_t(2));
267 
268  // if the variables on the left side are unordered, sort them by
269  // increasing order
270  if (!ordered_lhs_vars && (var1 > var2)) std::swap(var1, var2);
271  __ids << var1;
272  __ids << var2;
273 
274  // if the rhs_ids should be considered as unordered, we sort them by
275  // increasing order so that we can compare easily two different rhs_ids
276  if (!ordered_rhs_ids) {
277  std::vector< NodeId, ALLOC< NodeId > > vect(rhs_ids);
278  std::sort(vect.begin(), vect.end());
279  for (const auto id : vect)
280  __ids << id;
281  } else {
282  for (const auto id : rhs_ids)
283  __ids << id;
284  }
285 
286  // update the end iterator
287  __end_safe.__gotoEnd();
288 
289  GUM_CONSTRUCTOR(IdSet);
290  }
291 
292 
294  template < template < typename > class ALLOC >
295  INLINE IdSet< ALLOC >::IdSet(
296  NodeId var1,
297  NodeId var2,
298  NodeId var3,
299  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids,
300  const bool ordered_lhs_vars,
301  const bool ordered_rhs_ids,
302  const typename IdSet< ALLOC >::allocator_type& alloc) :
303  ALLOC< NodeId >(alloc),
304  __nb_lhs_ids(std::size_t(3)), __end_safe(*this) {
305  __ids.resize(rhs_ids.size() + std::size_t(3));
306 
307  // if the variables on the left side are unordered, sort them by
308  // increasing order
309  if (!ordered_lhs_vars) {
310  if (var1 > var2) std::swap(var1, var2);
311  if (var1 > var3) std::swap(var1, var3);
312  if (var2 > var3) std::swap(var2, var3);
313  }
314  __ids << var1;
315  __ids << var2;
316  __ids << var3;
317 
318  // if the rhs_ids should be considered as unordered, we sort them by
319  // increasing order so that we can compare easily two different rhs_ids
320  if (!ordered_rhs_ids) {
321  std::vector< NodeId, ALLOC< NodeId > > vect(rhs_ids);
322  std::sort(vect.begin(), vect.end());
323  for (const auto id : vect)
324  __ids << id;
325  } else {
326  for (const auto id : rhs_ids)
327  __ids << id;
328  }
329 
330  // update the end iterator
331  __end_safe.__gotoEnd();
332 
333  GUM_CONSTRUCTOR(IdSet);
334  }
335 
336 
338  template < template < typename > class ALLOC >
339  INLINE IdSet< ALLOC >::IdSet(
340  const IdSet< ALLOC >& from,
341  const typename IdSet< ALLOC >::allocator_type& alloc) :
342  ALLOC< NodeId >(alloc),
343  __ids(from.__ids), __nb_lhs_ids(from.__nb_lhs_ids), __end_safe(*this) {
344  __end_safe.__gotoEnd();
345  GUM_CONS_CPY(IdSet);
346  }
347 
348 
350  template < template < typename > class ALLOC >
351  INLINE IdSet< ALLOC >::IdSet(const IdSet< ALLOC >& from) :
352  IdSet< ALLOC >(from, from.getAllocator()) {}
353 
354 
356  template < template < typename > class ALLOC >
357  INLINE IdSet< ALLOC >::IdSet(
358  IdSet< ALLOC >&& from,
359  const typename IdSet< ALLOC >::allocator_type& alloc) :
360  ALLOC< NodeId >(alloc),
361  __ids(std::move(from.__ids)), __nb_lhs_ids(from.__nb_lhs_ids),
362  __end_safe(*this) {
363  __end_safe.__gotoEnd();
364  GUM_CONS_MOV(IdSet);
365  }
366 
367 
369  template < template < typename > class ALLOC >
370  INLINE IdSet< ALLOC >::IdSet(IdSet< ALLOC >&& from) :
371  IdSet< ALLOC >(std::move(from), from.getAllocator()) {}
372 
373 
375  template < template < typename > class ALLOC >
376  IdSet< ALLOC >* IdSet< ALLOC >::clone(
377  const typename IdSet< ALLOC >::allocator_type& alloc) const {
378  ALLOC< IdSet< ALLOC > > allocator(alloc);
379  IdSet< ALLOC >* new_set = allocator.allocate(1);
380  try {
381  allocator.construct(new_set, *this, alloc);
382  } catch (...) {
383  allocator.deallocate(new_set, 1);
384  throw;
385  }
386 
387  return new_set;
388  }
389 
390 
392  template < template < typename > class ALLOC >
393  IdSet< ALLOC >* IdSet< ALLOC >::clone() const {
394  return clone(this->getAllocator());
395  }
396 
397 
399  template < template < typename > class ALLOC >
400  INLINE IdSet< ALLOC >::~IdSet() {
401  GUM_DESTRUCTOR(IdSet);
402  }
403 
404 
406  template < template < typename > class ALLOC >
407  INLINE IdSet< ALLOC >& IdSet< ALLOC >::operator=(const IdSet< ALLOC >& from) {
408  if (this != &from) {
409  __ids = from.__ids;
410  __nb_lhs_ids = from.__nb_lhs_ids;
411  __end_safe.__gotoEnd();
412  }
413  return *this;
414  }
415 
416 
418  template < template < typename > class ALLOC >
419  INLINE IdSet< ALLOC >& IdSet< ALLOC >::operator=(IdSet< ALLOC >&& from) {
420  if (this != &from) {
421  __ids = std::move(from.__ids);
422  __nb_lhs_ids = from.__nb_lhs_ids;
423  __end_safe.__gotoEnd();
424  }
425  return *this;
426  }
427 
428 
430  template < template < typename > class ALLOC >
431  INLINE NodeId IdSet< ALLOC >::operator[](const std::size_t index) const {
432  return __ids.atPos(index);
433  }
434 
435 
437  template < template < typename > class ALLOC >
438  INLINE bool IdSet< ALLOC >::operator==(const IdSet< ALLOC >& from) const {
439  if (__nb_lhs_ids != from.__nb_lhs_ids) return false;
440 
441  const std::size_t size = __ids.size();
442 
443  if (size != from.__ids.size()) return false;
444 
445  for (std::size_t i = std::size_t(0); i < size; ++i) {
446  if (__ids[i] != from.__ids[i]) return false;
447  }
448 
449  return true;
450  }
451 
452 
454  template < template < typename > class ALLOC >
455  INLINE bool IdSet< ALLOC >::operator!=(const IdSet< ALLOC >& from) const {
456  return !operator==(from);
457  }
458 
459 
461  template < template < typename > class ALLOC >
462  INLINE typename IdSet< ALLOC >::iterator_safe
463  IdSet< ALLOC >::beginSafe() const {
464  return IdSetIterator< ALLOC >(*this);
465  }
466 
467 
469  template < template < typename > class ALLOC >
470  INLINE const typename IdSet< ALLOC >::iterator_safe&
471  IdSet< ALLOC >::endSafe() const {
472  return __end_safe;
473  }
474 
475 
477  template < template < typename > class ALLOC >
478  INLINE typename IdSet< ALLOC >::iterator IdSet< ALLOC >::begin() const {
479  return IdSetIterator< ALLOC >(*this);
480  }
481 
482 
484  template < template < typename > class ALLOC >
485  INLINE const typename IdSet< ALLOC >::iterator& IdSet< ALLOC >::end() const {
486  return __end_safe;
487  }
488 
489 
491  template < template < typename > class ALLOC >
492  INLINE const Sequence< NodeId, ALLOC< NodeId > >& IdSet< ALLOC >::ids() const {
493  return __ids;
494  }
495 
496 
498  template < template < typename > class ALLOC >
499  IdSet< ALLOC > IdSet< ALLOC >::conditionalIdSet() const {
500  IdSet< ALLOC > set(this->getAllocator());
501  const std::size_t size = __ids.size();
502  for (std::size_t i = __nb_lhs_ids; i < size; ++i)
503  set.__ids << __ids[i];
504  set.__end_safe.__gotoEnd();
505  return set;
506  }
507 
508 
510  template < template < typename > class ALLOC >
511  void IdSet< ALLOC >::erase(const NodeId id) {
512  // search for id in Sequence __ids
513  const std::size_t size = __ids.size();
514  std::size_t pos = std::size_t(0);
515  for (; pos < size; ++pos) {
516  if (__ids[pos] == id) break;
517  }
518 
519  // if we found the id, remove it
520  if (pos < size) {
521  __ids.erase(SequenceIteratorSafe< NodeId >(__ids, pos));
522  if (pos < __nb_lhs_ids) --__nb_lhs_ids;
523  __end_safe.__gotoEnd();
524  }
525  }
526 
527 
529  template < template < typename > class ALLOC >
530  std::string IdSet< ALLOC >::toString() const {
531  std::stringstream str;
532 
533  str << '{';
534  bool deja = false;
535 
536  for (std::size_t i = std::size_t(0); i < __nb_lhs_ids; ++i) {
537  if (deja)
538  str << " , ";
539  else
540  deja = true;
541  str << __ids[i];
542  }
543 
544  deja = false;
545  for (auto iter = __ids.begin() + __nb_lhs_ids; iter != __ids.end(); ++iter) {
546  if (deja)
547  str << " , ";
548  else {
549  deja = true;
550  str << " | ";
551  }
552  str << *iter;
553  }
554 
555  str << '}';
556 
557  return str.str();
558  }
559 
560 
562  template < template < typename > class ALLOC >
563  INLINE std::size_t IdSet< ALLOC >::nbLHSIds() const {
564  return __nb_lhs_ids;
565  }
566 
567 
569  template < template < typename > class ALLOC >
570  INLINE std::size_t IdSet< ALLOC >::nbRHSIds() const {
571  return __ids.size() - __nb_lhs_ids;
572  }
573 
574 
576  template < template < typename > class ALLOC >
577  bool IdSet< ALLOC >::contains(const IdSet< ALLOC >& set) const {
578  if (set.__ids.size() > __ids.size()) return false;
579  for (const auto node : set.__ids) {
580  if (!__ids.exists(node)) return false;
581  }
582  return true;
583  }
584 
585 
587  template < template < typename > class ALLOC >
588  INLINE void IdSet< ALLOC >::clear() {
589  __ids.clear();
590  __nb_lhs_ids = std::size_t(0);
591  __end_safe.__gotoEnd();
592  }
593 
594 
596  template < template < typename > class ALLOC >
597  INLINE std::size_t IdSet< ALLOC >::size() const {
598  return __ids.size();
599  }
600 
601 
603  template < template < typename > class ALLOC >
604  INLINE std::size_t IdSet< ALLOC >::pos(const NodeId id) const {
605  return __ids.pos(id);
606  }
607 
608 
610  template < template < typename > class ALLOC >
611  INLINE bool IdSet< ALLOC >::exists(const NodeId id) const {
612  return __ids.exists(id);
613  }
614 
615 
617  template < template < typename > class ALLOC >
618  INLINE bool IdSet< ALLOC >::hasConditioningSet() const {
619  return __nb_lhs_ids != __ids.size();
620  }
621 
622 
624  template < template < typename > class ALLOC >
625  INLINE bool IdSet< ALLOC >::empty() const {
626  return __ids.empty();
627  }
628 
629 
630  // the display operator
631  template < template < typename > class ALLOC >
632  std::ostream& operator<<(std::ostream& stream, const IdSet< ALLOC >& idset) {
633  return stream << idset.toString();
634  }
635 
636  } /* namespace learning */
637 
638 
639  // Returns the value of a key as a Size.
640  template < template < typename > class ALLOC >
641  Size HashFunc< learning::IdSet< ALLOC > >::castToSize(
642  const learning::IdSet< ALLOC >& key) {
643  Size h = Size(key.nbLHSIds());
644  const Sequence< NodeId, ALLOC< NodeId > >& vect = key.ids();
645  const std::size_t size = vect.size();
646 
647  std::size_t i = std::size_t(0);
648  while (i < size) {
649  const Size id = Size(vect[i]);
650  ++i;
651  h += Size(i) * id;
652  }
653 
654  return h;
655  }
656 
657 
658  // the hash function for idSets
659  template < template < typename > class ALLOC >
660  INLINE Size HashFunc< learning::IdSet< ALLOC > >::
661  operator()(const learning::IdSet< ALLOC >& key) const {
662  return (castToSize(key) * HashFuncConst::gold) & this->_hash_mask;
663  }
664 
665 } /* namespace gum */
666 
667 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
static constexpr Size gold
Definition: hashFunc.h:76
STL namespace.
void swap(HashTable< LpCol, double > *&a, HashTable< LpCol, double > *&b)
Swap the addresses of two pointers to hashTables.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
LpExpr operator+(LpExpr &&lhs, const T2 &rhs)
Overload of operator + between anything ( a scalar, a variable or an expression ) and anything except...
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:243
IdSetIterator()
default constructor
LpExpr operator*(const SCALAR &lhs, const LpCol &rhs)
Overload of operator * between a scalar and a variable.
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:251
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
Size NodeId
Type for node ids.
Definition: graphElements.h:98
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55