aGrUM  0.17.2
a C++ library for (probabilistic) graphical models
bijection_tpl.h
Go to the documentation of this file.
1 
30 // To simply IDE parsing
32 
33 namespace gum {
34 
35  // ===========================================================================
36  // === NON SCALAR BIJECTION IMPLEMENTATION ===
37  // ===========================================================================
38 
39  // returns the end iterator for other classes' statics
40  template < typename T1, typename T2, typename Alloc, bool Gen >
41  const BijectionIteratorSafe< T1, T2 >&
43  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
45  }
46 
47  // returns the end iterator for other classes' statics
48  template < typename T1, typename T2, typename Alloc, bool Gen >
51  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
53  }
54 
55  // a function that performs a complete copy of another bijection
56  template < typename T1, typename T2, typename Alloc, bool Gen >
57  template < typename OtherAlloc >
60  // parse f2s and perform copies
61  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
62  typename HashTable12::value_type* val1 =
63  &(__firstToSecond.insert(iter.key(), nullptr));
64  typename HashTable21::value_type* val2;
65 
66  try {
67  val2 = &(__secondToFirst.insert(*(iter.val()), nullptr));
68  } catch (...) {
69  __firstToSecond.erase(iter.key());
70  throw;
71  }
72 
73  val1->second = &(const_cast< T2& >(val2->first));
74  val2->second = &(const_cast< T1& >(val1->first));
75  }
76 
77  // note that __iter_end is actually a constant, whatever we add/remove
78  // to/from __firstToSecond. As a consequence, it need not be updated
79  // after __copy
80  }
81 
82  // Default constructor: creates a bijection without association
83  template < typename T1, typename T2, typename Alloc, bool Gen >
85  Size size, bool resize_policy) :
86  // warning: below, we create the internal hashTables with a key
87  // uniqueness
88  // policy set to false because we will do the uniqueness tests ourselves
89  // (this
90  // will speed-up the process)
91  __firstToSecond(size, resize_policy, false),
92  __secondToFirst(size, resize_policy, false) {
93  GUM_CONSTRUCTOR(BijectionImplementation);
94 
95  // make sure the end() iterator is constructed properly
96  end4Statics();
97  endSafe4Statics();
98  }
99 
100  // initializer list constructor
101  template < typename T1, typename T2, typename Alloc, bool Gen >
103  std::initializer_list< std::pair< T1, T2 > > list) :
104  __firstToSecond(Size(list.size()) / 2, true, false),
105  __secondToFirst(Size(list.size()) / 2, true, false) {
106  GUM_CONSTRUCTOR(BijectionImplementation);
107 
108  for (const auto& elt: list) {
109  insert(elt.first, elt.second);
110  }
111 
112  // make sure the end() iterator is constructed properly
113  end4Statics();
114  endSafe4Statics();
115  }
116 
117  // Copy constructor
118  template < typename T1, typename T2, typename Alloc, bool Gen >
121  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
122  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
123  GUM_CONS_CPY(BijectionImplementation);
124  __copy(toCopy.__firstToSecond);
125  }
126 
127  // Generalized copy constructor
128  template < typename T1, typename T2, typename Alloc, bool Gen >
129  template < typename OtherAlloc >
132  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
133  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
134  GUM_CONS_CPY(BijectionImplementation);
135  __copy(toCopy.__firstToSecond);
136  }
137 
138  // move constructor
139  template < typename T1, typename T2, typename Alloc, bool Gen >
142  __firstToSecond(std::move(from.__firstToSecond)),
143  __secondToFirst(std::move(from.__secondToFirst)) {
144  GUM_CONS_MOV(BijectionImplementation);
145  }
146 
147  // destructor
148  template < typename T1, typename T2, typename Alloc, bool Gen >
149  INLINE
151  GUM_DESTRUCTOR(BijectionImplementation);
152  }
153 
154  // removes all the associations from the bijection
155  template < typename T1, typename T2, typename Alloc, bool Gen >
157  __firstToSecond.clear();
158  __secondToFirst.clear();
159  // note that __iter_end is actually a constant, whatever we add/remove
160  // to/from __firstToSecond. As a consequence, it need not be updated
161  // after the clear's
162  }
163 
164  // Copy operator
165  template < typename T1, typename T2, typename Alloc, bool Gen >
169  // avoid self assignment
170  if (this != &toCopy) {
171  clear();
172  __copy(toCopy.__firstToSecond);
173  }
174 
175  // note that __iter_end is actually a constant, whatever we add/remove
176  // to/from __firstToSecond. As a consequence, it need not be updated
177  // after __copy
178  return *this;
179  }
180 
181  // Generalized copy operator
182  template < typename T1, typename T2, typename Alloc, bool Gen >
183  template < typename OtherAlloc >
187  clear();
188  __copy(toCopy.__firstToSecond);
189 
190  // note that __iter_end is actually a constant, whatever we add/remove
191  // to/from __firstToSecond. As a consequence, it need not be updated
192  // after __copy
193  return *this;
194  }
195 
196  // move operator
197  template < typename T1, typename T2, typename Alloc, bool Gen >
201  // avoid self assignment
202  if (this != &from) {
203  clear();
204  __firstToSecond = std::move(from.__firstToSecond);
205  __secondToFirst = std::move(from.__secondToFirst);
206  }
207 
208  // note that __iter_end is actually a constant, whatever we add/remove
209  // to/from __firstToSecond. As a consequence, it need not be updated
210  // after __copy
211  return *this;
212  }
213 
214  // returns the iterator at the beginning of the bijection
215  template < typename T1, typename T2, typename Alloc, bool Gen >
218  return BijectionIterator< T1, T2 >{*this};
219  }
220 
221  // returns the iterator at the beginning of the bijection
222  template < typename T1, typename T2, typename Alloc, bool Gen >
225  return BijectionIterator< T1, T2 >{*this};
226  }
227 
228  // returns the iterator to the end of the bijection
229  template < typename T1, typename T2, typename Alloc, bool Gen >
232  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
233  BijectionIteratorStaticEnd::__BijectionIterEnd));
234  }
235 
236  // returns the iterator to the end of the bijection
237  template < typename T1, typename T2, typename Alloc, bool Gen >
238  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::
239  const_iterator&
241  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
242  BijectionIteratorStaticEnd::__BijectionIterEnd));
243  }
244 
245  // returns the iterator at the beginning of the bijection
246  template < typename T1, typename T2, typename Alloc, bool Gen >
249  return BijectionIteratorSafe< T1, T2 >{*this};
250  }
251 
252  // returns the iterator at the beginning of the bijection
253  template < typename T1, typename T2, typename Alloc, bool Gen >
254  INLINE
257  return BijectionIteratorSafe< T1, T2 >{*this};
258  }
259 
260  // returns the iterator to the end of the bijection
261  template < typename T1, typename T2, typename Alloc, bool Gen >
262  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::
263  iterator_safe&
265  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
266  BijectionIteratorStaticEnd::__BijectionIterEndSafe));
267  }
268 
269  // returns the iterator to the end of the bijection
270  template < typename T1, typename T2, typename Alloc, bool Gen >
271  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::
272  const_iterator_safe&
274  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
275  BijectionIteratorStaticEnd::__BijectionIterEndSafe));
276  }
277 
278  // returns the value associated to the element passed in argument
279  template < typename T1, typename T2, typename Alloc, bool Gen >
280  INLINE const T1&
282  return *(__secondToFirst[second]);
283  }
284 
285  // returns the value associated to the element passed in argument
286  template < typename T1, typename T2, typename Alloc, bool Gen >
287  INLINE const T2&
289  return *(__firstToSecond[first]);
290  }
291 
292  // Test whether the bijection contains the "first" value
293  template < typename T1, typename T2, typename Alloc, bool Gen >
295  const T1& first) const {
296  return __firstToSecond.exists(first);
297  }
298 
299  // Test whether the bijection contains the "second" value
300  template < typename T1, typename T2, typename Alloc, bool Gen >
302  const T2& second) const {
303  return __secondToFirst.exists(second);
304  }
305 
306  // inserts a new association in the bijection
307  template < typename T1, typename T2, typename Alloc, bool Gen >
309  value_type*
311  const T2& second) {
312  // check the uniqueness property
313  if (existsFirst(first) || existsSecond(second)) {
315  "the bijection contains an element with the same couple ("
316  << first << "," << second << ")");
317  }
318 
319  // insert copies of first and second
320  typename HashTable12::value_type* val1 =
321  &(__firstToSecond.insert(first, nullptr));
322  typename HashTable21::value_type* val2;
323 
324  try {
325  val2 = &(__secondToFirst.insert(second, nullptr));
326  } catch (...) {
327  __firstToSecond.erase(first);
328  throw;
329  }
330 
331  val1->second = &(const_cast< T2& >(val2->first));
332  val2->second = &(const_cast< T1& >(val1->first));
333 
334  return val1;
335  }
336 
337  // inserts a new association in the bijection
338  template < typename T1, typename T2, typename Alloc, bool Gen >
340  value_type*
342  T2&& second) {
343  // check the uniqueness property
344  if (existsFirst(first) || existsSecond(second)) {
346  "the bijection contains an element with the same couple ("
347  << first << "," << second << ")");
348  }
349 
350  // insert copies of first and second
351  typename HashTable12::value_type* val1 =
352  &(__firstToSecond.insert(std::move(first), nullptr));
353  typename HashTable21::value_type* val2;
354 
355  try {
356  val2 = &(__secondToFirst.insert(std::move(second), nullptr));
357  } catch (...) {
358  __firstToSecond.erase(val1->first);
359  throw;
360  }
361 
362  val1->second = &(const_cast< T2& >(val2->first));
363  val2->second = &(const_cast< T1& >(val1->first));
364 
365  return val1;
366  }
367 
368  /* @brief Same method as first, but if the value is not found, a default
369  * value is inserted into the bijection */
370  template < typename T1, typename T2, typename Alloc, bool Gen >
372  const T2& second, const T1& val) const {
373  try {
374  return first(second);
375  } catch (NotFound&) { return __insert(val, second)->first; }
376  }
377 
378  /* @brief Same method as second, but if the value is not found, a default
379  * value is inserted into the bijection */
380  template < typename T1, typename T2, typename Alloc, bool Gen >
381  INLINE const T2&
383  const T1& first, const T2& val) const {
384  try {
385  return second(first);
386  } catch (NotFound&) { return *(__insert(first, val)->second); }
387  }
388 
389  // inserts a new association in the bijection
390  template < typename T1, typename T2, typename Alloc, bool Gen >
391  INLINE void
393  const T2& second) {
394  __insert(first, second);
395  }
396 
397  // inserts a new association in the bijection
398  template < typename T1, typename T2, typename Alloc, bool Gen >
400  T2&& second) {
401  __insert(std::move(first), std::move(second));
402  }
403 
404  // emplace a new element in the bijection
405  template < typename T1, typename T2, typename Alloc, bool Gen >
406  template < typename... Args >
407  INLINE void
409  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
410  __insert(std::move(new_elt.first), std::move(new_elt.second));
411  }
412 
413  // returns true if the bijection doesn't contain any relation
414  template < typename T1, typename T2, typename Alloc, bool Gen >
416  noexcept {
417  GUM_ASSERT(__firstToSecond.empty() == __secondToFirst.empty());
418  return __firstToSecond.empty();
419  }
420 
421  // returns the number of associations stored within the bijection
422  template < typename T1, typename T2, typename Alloc, bool Gen >
424  noexcept {
425  GUM_ASSERT(__firstToSecond.size() == __secondToFirst.size());
426  return __firstToSecond.size();
427  }
428 
429  // erases an association containing the given first element
430  template < typename T1, typename T2, typename Alloc, bool Gen >
431  INLINE void
433  try {
434  __secondToFirst.erase(*__firstToSecond[first]);
435  __firstToSecond.erase(first);
436  } catch (NotFound&) {}
437  }
438 
439  // erase an association containing the given second element
440  template < typename T1, typename T2, typename Alloc, bool Gen >
441  INLINE void
443  try {
444  __firstToSecond.erase(*__secondToFirst[second]);
445  __secondToFirst.erase(second);
446  } catch (NotFound&) {}
447  }
448 
449  // returns the number of hashtables' slots used (@sa hashTable's capacity)
450  template < typename T1, typename T2, typename Alloc, bool Gen >
452  noexcept {
453  return __firstToSecond.capacity();
454  }
455 
456  // similar to the hashtable's resize
457  template < typename T1, typename T2, typename Alloc, bool Gen >
458  INLINE void
460  __firstToSecond.resize(new_size);
461  __secondToFirst.resize(new_size);
462  }
463 
464  // enables the user to change dynamically the resizing policy
465  template < typename T1, typename T2, typename Alloc, bool Gen >
467  const bool new_policy) noexcept {
468  __firstToSecond.setResizePolicy(new_policy);
469  __secondToFirst.setResizePolicy(new_policy);
470  }
471 
472  // returns the current resizing policy
473  template < typename T1, typename T2, typename Alloc, bool Gen >
475  noexcept {
476  return __firstToSecond.resizePolicy();
477  }
478 
479  // friendly displays the content of the CliqueGraph
480  template < typename T1, typename T2, typename Alloc, bool Gen >
482  std::stringstream stream;
483  stream << "{ ";
484  bool first = true;
485 
486  for (iterator iter = begin(); iter != end(); ++iter) {
487  if (!first)
488  stream << ", ";
489  else
490  first = false;
491 
492  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
493  }
494 
495  stream << " }";
496  return stream.str();
497  }
498 
499  // ===========================================================================
500  // === SCALAR BIJECTION IMPLEMENTATION ===
501  // ===========================================================================
502 
503  // returns the end iterator for other classes' statics
504  template < typename T1, typename T2, typename Alloc >
507  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
508  BijectionIteratorStaticEnd::endSafe4Statics()));
509  }
510 
511  // returns the end iterator for other classes' statics
512  template < typename T1, typename T2, typename Alloc >
515  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
516  BijectionIteratorStaticEnd::end4Statics()));
517  }
518 
519  // Default constructor: creates a bijection without association
520  template < typename T1, typename T2, typename Alloc >
522  Size size, bool resize_policy) :
523  // warning: below, we create the internal hashTables with a key
524  // uniqueness
525  // policy set to false because we will do the uniqueness tests ourselves
526  // (this
527  // will speed-up the process)
528  __firstToSecond(size, resize_policy, false),
529  __secondToFirst(size, resize_policy, false) {
530  GUM_CONSTRUCTOR(BijectionImplementation);
531 
532  // make sure the end() iterator is constructed properly
533  end4Statics();
534  endSafe4Statics();
535  }
536 
537  // initializer list constructor
538  template < typename T1, typename T2, typename Alloc >
539  INLINE BijectionImplementation< T1, T2, Alloc, true >::BijectionImplementation(
540  std::initializer_list< std::pair< T1, T2 > > list) :
541  __firstToSecond(Size(list.size()) / 2, true, false),
542  __secondToFirst(Size(list.size()) / 2, true, false) {
543  GUM_CONSTRUCTOR(BijectionImplementation);
544 
545  for (const auto& elt: list) {
546  insert(elt.first, elt.second);
547  }
548 
549  // make sure the end() iterator is constructed properly
550  end4Statics();
551  endSafe4Statics();
552  }
553 
554  // a function that performs a complete copy of another bijection
555  template < typename T1, typename T2, typename Alloc >
556  template < typename OtherAlloc >
558  const HashTable< T1, T2, OtherAlloc >& f2s) {
559  // parse f2s and perform copies
560  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
561  __firstToSecond.insert(iter.key(), iter.val());
562 
563  try {
564  __secondToFirst.insert(iter.val(), iter.key());
565  } catch (...) {
566  __firstToSecond.erase(iter.key());
567  throw;
568  }
569  }
570 
571  // note that __iter_end is actually a constant, whatever we add/remove
572  // to/from __firstToSecond. As a consequence, it need not be updated
573  // after __copy
574  }
575 
576  // Copy constructor
577  template < typename T1, typename T2, typename Alloc >
578  INLINE BijectionImplementation< T1, T2, Alloc, true >::BijectionImplementation(
580  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
581  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
582  GUM_CONS_CPY(BijectionImplementation);
583  __copy(toCopy.__firstToSecond);
584  }
585 
586  // Generalized copy constructor
587  template < typename T1, typename T2, typename Alloc >
588  template < typename OtherAlloc >
589  INLINE BijectionImplementation< T1, T2, Alloc, true >::BijectionImplementation(
591  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
592  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
593  GUM_CONS_CPY(BijectionImplementation);
594  __copy(toCopy.__firstToSecond);
595  }
596 
597  // move constructor
598  template < typename T1, typename T2, typename Alloc >
599  INLINE BijectionImplementation< T1, T2, Alloc, true >::BijectionImplementation(
601  __firstToSecond(std::move(toCopy.__firstToSecond)),
602  __secondToFirst(std::move(toCopy.__secondToFirst)) {
603  GUM_CONS_MOV(BijectionImplementation);
604  }
605 
606  // destructor
607  template < typename T1, typename T2, typename Alloc >
608  INLINE
610  GUM_DESTRUCTOR(BijectionImplementation);
611  }
612 
613  // returns the iterator at the beginning of the bijection
614  template < typename T1, typename T2, typename Alloc >
617  return BijectionIterator< T1, T2 >{*this};
618  }
619 
620  // returns the iterator at the beginning of the bijection
621  template < typename T1, typename T2, typename Alloc >
624  return BijectionIterator< T1, T2 >{*this};
625  }
626 
627  // returns the iterator to the end of the bijection
628  template < typename T1, typename T2, typename Alloc >
631  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
632  BijectionIteratorStaticEnd::__BijectionIterEnd));
633  }
634 
635  // returns the iterator to the end of the bijection
636  template < typename T1, typename T2, typename Alloc >
637  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::
638  const_iterator&
640  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
641  BijectionIteratorStaticEnd::__BijectionIterEnd));
642  }
643 
644  // returns the iterator at the beginning of the bijection
645  template < typename T1, typename T2, typename Alloc >
648  return BijectionIteratorSafe< T1, T2 >{*this};
649  }
650 
651  // returns the iterator at the beginning of the bijection
652  template < typename T1, typename T2, typename Alloc >
653  INLINE
656  return BijectionIteratorSafe< T1, T2 >{*this};
657  }
658 
659  // returns the iterator to the end of the bijection
660  template < typename T1, typename T2, typename Alloc >
661  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::
662  iterator_safe&
664  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
665  BijectionIteratorStaticEnd::__BijectionIterEndSafe));
666  }
667 
668  // returns the iterator to the end of the bijection
669  template < typename T1, typename T2, typename Alloc >
670  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::
671  const_iterator_safe&
673  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
674  BijectionIteratorStaticEnd::__BijectionIterEndSafe));
675  }
676 
677  // removes all the associations from the bijection
678  template < typename T1, typename T2, typename Alloc >
680  __firstToSecond.clear();
681  __secondToFirst.clear();
682  // note that __iter_end is actually a constant, whatever we add/remove
683  // to/from __firstToSecond. As a consequence, it need not be updated
684  // after the clear's
685  }
686 
687  // Copy operator
688  template < typename T1, typename T2, typename Alloc >
692  // avoid self assignment
693  if (this != &toCopy) {
694  clear();
695  __copy(toCopy.__firstToSecond);
696  }
697 
698  // note that __iter_end is actually a constant, whatever we add/remove
699  // to/from __firstToSecond. As a consequence, it need not be updated
700  // after __copy
701  return *this;
702  }
703 
704  // Generalized copy operator
705  template < typename T1, typename T2, typename Alloc >
706  template < typename OtherAlloc >
710  clear();
711  __copy(toCopy.__firstToSecond);
712 
713  // note that __iter_end is actually a constant, whatever we add/remove
714  // to/from __firstToSecond. As a consequence, it need not be updated
715  // after __copy
716  return *this;
717  }
718 
719  // move operator
720  template < typename T1, typename T2, typename Alloc >
724  // avoid self assignment
725  if (this != &toCopy) {
726  clear();
727  __firstToSecond = std::move(toCopy.__firstToSecond);
728  __secondToFirst = std::move(toCopy.__secondToFirst);
729  }
730 
731  // note that __iter_end is actually a constant, whatever we add/remove
732  // to/from __firstToSecond. As a consequence, it need not be updated
733  // after __copy
734  return *this;
735  }
736 
737  // returns the value associated to the element passed in argument
738  template < typename T1, typename T2, typename Alloc >
739  INLINE const T1&
741  return __secondToFirst[second];
742  }
743 
744  // returns the value associated to the element passed in argument
745  template < typename T1, typename T2, typename Alloc >
746  INLINE const T2&
748  return __firstToSecond[first];
749  }
750 
751  // Test whether the bijection contains the "first" value
752  template < typename T1, typename T2, typename Alloc >
753  INLINE bool
755  return __firstToSecond.exists(first);
756  }
757 
758  // Test whether the bijection contains the "second" value
759  template < typename T1, typename T2, typename Alloc >
761  T2 second) const {
762  return __secondToFirst.exists(second);
763  }
764 
765  // inserts a new association in the bijection
766  template < typename T1, typename T2, typename Alloc >
768  T2 second) {
769  // check the uniqueness property
770  if (existsFirst(first) || existsSecond(second)) {
772  "the bijection contains an element with the same couple ("
773  << first << "," << second << ")");
774  }
775 
776  // insert copies of first and second
777  __firstToSecond.insert(first, second);
778 
779  try {
780  __secondToFirst.insert(second, first);
781  } catch (...) {
782  __firstToSecond.erase(first);
783  throw;
784  }
785  }
786 
787  // inserts a new association in the bijection
788  template < typename T1, typename T2, typename Alloc >
790  T2 second) {
791  __insert(first, second);
792  }
793 
794  // emplace a new element in the bijection
795  template < typename T1, typename T2, typename Alloc >
796  template < typename... Args >
797  INLINE void
799  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
800  __insert(new_elt.first, new_elt.second);
801  }
802 
803  /* @brief Same method as first, but if the value is not found, a default
804  * value is inserted into the bijection */
805  template < typename T1, typename T2, typename Alloc >
806  INLINE const T1&
808  T2 second, T1 val) const {
809  try {
810  return first(second);
811  } catch (NotFound&) {
812  __insert(val, second);
813  return val;
814  }
815  }
816 
817  /* @brief Same method as second, but if the value is not found, a default
818  * value is inserted into the bijection */
819  template < typename T1, typename T2, typename Alloc >
820  INLINE const T2&
822  T1 first, T2 val) const {
823  try {
824  return second(first);
825  } catch (NotFound&) {
826  __insert(first, val);
827  return val;
828  }
829  }
830 
831  // returns true if the bijection doesn't contain any relation
832  template < typename T1, typename T2, typename Alloc >
834  noexcept {
835  GUM_ASSERT(__firstToSecond.empty() == __secondToFirst.empty());
836  return __firstToSecond.empty();
837  }
838 
839  // returns the number of associations stored within the bijection
840  template < typename T1, typename T2, typename Alloc >
842  noexcept {
843  GUM_ASSERT(__firstToSecond.size() == __secondToFirst.size());
844  return __firstToSecond.size();
845  }
846 
847  // erases an association containing the given first element
848  template < typename T1, typename T2, typename Alloc >
849  INLINE void
851  try {
852  __secondToFirst.erase(__firstToSecond[first]);
853  __firstToSecond.erase(first);
854  } catch (NotFound&) {}
855  }
856 
857  // erase an association containing the given second element
858  template < typename T1, typename T2, typename Alloc >
859  INLINE void
861  try {
862  __firstToSecond.erase(__secondToFirst[second]);
863  __secondToFirst.erase(second);
864  } catch (NotFound&) {}
865  }
866 
867  // returns the number of hashtables' slots used (@sa hashTable's capacity)
868  template < typename T1, typename T2, typename Alloc >
870  noexcept {
871  return __firstToSecond.capacity();
872  }
873 
874  // similar to the hashtable's resize
875  template < typename T1, typename T2, typename Alloc >
876  INLINE void
878  __firstToSecond.resize(new_size);
879  __secondToFirst.resize(new_size);
880  }
881 
882  // enables the user to change dynamically the resizing policy
883  template < typename T1, typename T2, typename Alloc >
885  const bool new_policy) noexcept {
886  __firstToSecond.setResizePolicy(new_policy);
887  __secondToFirst.setResizePolicy(new_policy);
888  }
889 
890  // returns the current resizing policy
891  template < typename T1, typename T2, typename Alloc >
893  noexcept {
894  return __firstToSecond.resizePolicy();
895  }
896 
897  // friendly displays the content of the CliqueGraph
898  template < typename T1, typename T2, typename Alloc >
900  std::stringstream stream;
901  stream << "{ ";
902  bool first = true;
903 
904  for (iterator iter = begin(); iter != end(); ++iter) {
905  if (!first)
906  stream << ", ";
907  else
908  first = false;
909 
910  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
911  }
912 
913  stream << " }";
914  return stream.str();
915  }
916 
917  // ===========================================================================
918  // === BIJECTION SAFE ITERATORS ===
919  // ===========================================================================
920 
922  template < typename T1, typename T2 >
924  GUM_CONSTRUCTOR(BijectionIteratorSafe);
925  }
926 
928  template < typename T1, typename T2 >
929  template < typename Alloc, bool Gen >
932  __iter{bijection.__firstToSecond.cbeginSafe()} {
933  GUM_CONSTRUCTOR(BijectionIteratorSafe);
934  }
935 
937  template < typename T1, typename T2 >
938  template < typename Alloc >
940  const Bijection< T1, T2, Alloc >& bijection) :
941  __iter{bijection.__firstToSecond.cbeginSafe()} {
942  GUM_CONSTRUCTOR(BijectionIteratorSafe);
943  }
944 
946  template < typename T1, typename T2 >
948  const BijectionIteratorSafe< T1, T2 >& toCopy) :
949  __iter{toCopy.__iter} {
950  GUM_CONS_CPY(BijectionIteratorSafe);
951  }
952 
954  template < typename T1, typename T2 >
956  BijectionIteratorSafe< T1, T2 >&& from) noexcept :
957  __iter{std::move(from.__iter)} {
958  GUM_CONS_MOV(BijectionIteratorSafe);
959  }
960 
962  template < typename T1, typename T2 >
964  GUM_DESTRUCTOR(BijectionIteratorSafe);
965  }
966 
968  template < typename T1, typename T2 >
971  const BijectionIteratorSafe< T1, T2 >& toCopy) {
972  __iter = toCopy.__iter;
973  return *this;
974  }
975 
977  template < typename T1, typename T2 >
980  BijectionIteratorSafe< T1, T2 >&& toCopy) noexcept {
981  __iter = std::move(toCopy.__iter);
982  return *this;
983  }
984 
986  template < typename T1, typename T2 >
989  ++__iter;
990  return *this;
991  }
992 
994  template < typename T1, typename T2 >
997  __iter += nb;
998  return *this;
999  }
1000 
1002  template < typename T1, typename T2 >
1005  return BijectionIteratorSafe< T1, T2 >{*this} += nb;
1006  }
1007 
1009  template < typename T1, typename T2 >
1011  const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1012  return __iter != toCompare.__iter;
1013  }
1014 
1016  template < typename T1, typename T2 >
1018  const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1019  return __iter == toCompare.__iter;
1020  }
1021 
1023  template < typename T1, typename T2 >
1024  INLINE const T1& BijectionIteratorSafe< T1, T2 >::first() const {
1025  return __iter.key();
1026  }
1027 
1029  template < typename T1, typename T2 >
1030  INLINE const T2& BijectionIteratorSafe< T1, T2 >::second() const {
1031  return Getter::op_second(__iter.val());
1032  }
1033 
1034  /* ===========================================================================
1035  */
1036  /* === BIJECTION UNSAFE ITERATORS ===
1037  */
1038  /* ===========================================================================
1039  */
1040 
1042  template < typename T1, typename T2 >
1044  GUM_CONSTRUCTOR(BijectionIterator);
1045  }
1046 
1048  template < typename T1, typename T2 >
1049  template < typename Alloc, bool Gen >
1052  __iter{bijection.__firstToSecond.cbegin()} {
1053  GUM_CONSTRUCTOR(BijectionIterator);
1054  }
1055 
1057  template < typename T1, typename T2 >
1058  template < typename Alloc >
1060  const Bijection< T1, T2, Alloc >& bijection) :
1061  __iter{bijection.__firstToSecond.cbegin()} {
1062  GUM_CONSTRUCTOR(BijectionIterator);
1063  }
1064 
1066  template < typename T1, typename T2 >
1068  const BijectionIterator< T1, T2 >& toCopy) :
1069  __iter{toCopy.__iter} {
1070  GUM_CONS_CPY(BijectionIterator);
1071  }
1072 
1074  template < typename T1, typename T2 >
1076  BijectionIterator< T1, T2 >&& from) noexcept :
1077  __iter{std::move(from.__iter)} {
1078  GUM_CONS_MOV(BijectionIterator);
1079  }
1080 
1082  template < typename T1, typename T2 >
1084  GUM_DESTRUCTOR(BijectionIterator);
1085  }
1086 
1088  template < typename T1, typename T2 >
1090  const BijectionIterator< T1, T2 >& toCopy) {
1091  __iter = toCopy.__iter;
1092  return *this;
1093  }
1094 
1096  template < typename T1, typename T2 >
1098  BijectionIterator< T1, T2 >&& toCopy) noexcept {
1099  __iter = std::move(toCopy.__iter);
1100  return *this;
1101  }
1102 
1104  template < typename T1, typename T2 >
1107  ++__iter;
1108  return *this;
1109  }
1110 
1112  template < typename T1, typename T2 >
1115  __iter += nb;
1116  return *this;
1117  }
1118 
1120  template < typename T1, typename T2 >
1123  return BijectionIterator< T1, T2 >{*this} += nb;
1124  }
1125 
1127  template < typename T1, typename T2 >
1129  const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1130  return __iter != toCompare.__iter;
1131  }
1132 
1134  template < typename T1, typename T2 >
1136  const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1137  return __iter == toCompare.__iter;
1138  }
1139 
1141  template < typename T1, typename T2 >
1142  INLINE const T1& BijectionIterator< T1, T2 >::first() const {
1143  return __iter.key();
1144  }
1145 
1147  template < typename T1, typename T2 >
1148  INLINE const T2& BijectionIterator< T1, T2 >::second() const {
1149  return Getter::op_second(__iter.val());
1150  }
1151 
1152  // ============================================================================
1153  // BIJECTION
1154  // ============================================================================
1155 
1156  // Default constructor: creates a bijection without any association
1157  template < typename T1, typename T2, typename Alloc >
1158  INLINE Bijection< T1, T2, Alloc >::Bijection(Size size, bool resize_policy) :
1160  T2,
1161  Alloc,
1162  std::is_scalar< T1 >::value
1163  && std::is_scalar< T2 >::value >(size,
1164  resize_policy) {
1165  GUM_CONSTRUCTOR(Bijection);
1166  }
1167 
1168  // initializer list constructor
1169  template < typename T1, typename T2, typename Alloc >
1171  std::initializer_list< std::pair< T1, T2 > > list) :
1173  T2,
1174  Alloc,
1175  std::is_scalar< T1 >::value
1176  && std::is_scalar< T2 >::value >(list) {
1177  GUM_CONSTRUCTOR(Bijection);
1178  }
1179 
1180  // Copy constructor
1181  template < typename T1, typename T2, typename Alloc >
1183  const Bijection< T1, T2, Alloc >& toCopy) :
1185  T2,
1186  Alloc,
1187  std::is_scalar< T1 >::value
1188  && std::is_scalar< T2 >::value >(toCopy) {
1189  GUM_CONS_CPY(Bijection);
1190  }
1191 
1192  // Generalized copy constructor
1193  template < typename T1, typename T2, typename Alloc >
1194  template < typename OtherAlloc >
1196  const Bijection< T1, T2, OtherAlloc >& toCopy) :
1198  T2,
1199  Alloc,
1200  std::is_scalar< T1 >::value
1201  && std::is_scalar< T2 >::value >(toCopy) {
1202  GUM_CONS_CPY(Bijection);
1203  }
1204 
1205  // move constructor
1206  template < typename T1, typename T2, typename Alloc >
1208  Bijection< T1, T2, Alloc >&& from) noexcept :
1210  T2,
1211  Alloc,
1212  std::is_scalar< T1 >::value
1213  && std::is_scalar< T2 >::value >(
1214  std::move(from)) {
1215  GUM_CONS_MOV(Bijection);
1216  }
1217 
1218  // destructor
1219  template < typename T1, typename T2, typename Alloc >
1221  GUM_DESTRUCTOR(Bijection);
1222  }
1223 
1224  // copy operator
1225  template < typename T1, typename T2, typename Alloc >
1227  const Bijection< T1, T2, Alloc >& toCopy) {
1228  Implementation::operator=(toCopy);
1229  return *this;
1230  }
1231 
1232  // generalized copy operator
1233  template < typename T1, typename T2, typename Alloc >
1234  template < typename OtherAlloc >
1236  const Bijection< T1, T2, OtherAlloc >& toCopy) {
1237  Implementation::operator=(toCopy);
1238  return *this;
1239  }
1240 
1241  // move operator
1242  template < typename T1, typename T2, typename Alloc >
1245  Implementation::operator=(std::move(bij));
1246  return *this;
1247  }
1248 
1249  // for friendly displaying the content of bijections
1250  template < typename T1, typename T2, typename Alloc >
1251  std::ostream& operator<<(std::ostream& stream,
1252  const Bijection< T1, T2, Alloc >& b) {
1253  stream << b.toString();
1254  return stream;
1255  }
1256 
1257 } /* namespace gum */
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
friend class BijectionImplementation
a friend to speed-up accesses
Definition: bijection.h:651
void __copy(const HashTable< T1, T2 *, OtherAlloc > &source)
A function that performs a complete copy of another gum::Bijection.
void clear()
Removes all the associations from the gum::Bijection.
static const BijectionIterator< int, int > * end4Statics()
Creates (if needed) and returns the iterator __BijectionIterEnd.
Safe iterators for bijectionIterator.
Definition: bijection.h:1411
STL namespace.
HashIter __iter
The hashTable iterator that actually does all the job.
Definition: bijection.h:1593
const_iterator cbegin() const
Returns the constant unsafe iterator at the beginning of the gum::Bjection.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
Definition: agrum.h:25
static const iterator_safe & endSafe4Statics()
Returns the safe end iterator for other classes&#39; statics.
Definition: bijection_tpl.h:42
void resize(Size new_size)
Manually resize the gum::Bijection.
The class for generic Hash Tables.
Definition: hashTable.h:679
static const BijectionIteratorSafe< int, int > * endSafe4Statics()
Creates (if needed) and returns the iterator __BijectionIterEndSafe.
Size capacity() const noexcept
Returns the number of hashtables slots used.
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Definition: BayesNet_tpl.h:626
bool empty() const noexcept
Returns true if the gum::Bijection doesn&#39;t contain any association.
const const_iterator & cend() const noexcept
Returns the unsafe const_iterator pointing to the end of the hashtable.
HashTable12 __firstToSecond
The gum::HashTable associating T2 objects to T1 objects.
Definition: bijection.h:660
LpExpr operator+(LpExpr &&lhs, const T2 &rhs)
Overload of operator + between anything ( a scalar, a variable or an expression ) and anything except...
Unsafe iterators for bijection.
Definition: bijection.h:1609
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:243
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1805
Size size() const noexcept
Returns the number of associations stored within the gum::Bijection.
const_iterator cbegin() const
Returns an unsafe const_iterator pointing to the beginning of the hashtable.
std::pair< const Idx, const std::string ** > value_type
Definition: hashTable.h:685
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:251
HashIter __iter
The hashTable iterator that actually does all the job.
Definition: bijection.h:1782
std::string toString() const
Returns a friendly representatin of the gum::Bijection.
bool resizePolicy() const noexcept
Returns true if the resize policy is automatic.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
static const iterator & end4Statics()
Returns the unsafe end iterator for other classes&#39; statics.
Definition: bijection_tpl.h:50
HashTable21 __secondToFirst
The gum::HashTable associating T1 objects to T2 objects.
Definition: bijection.h:663
const_iterator_safe cbeginSafe() const
Returns the constant safe iterator at the begining of the gum::Bijection.
void setResizePolicy(const bool new_policy) noexcept
Change the gum::Bijection resizing policy.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
A non scalar implementation of a Bijection.
Definition: bijection.h:85
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55