aGrUM  0.16.0
bijection_tpl.h
Go to the documentation of this file.
1 
30 // To simply IDE parsing
31 #include <agrum/core/bijection.h>
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  __iter = toCopy.__iter;
972  return *this;
973  }
974 
976  template < typename T1, typename T2 >
979  __iter = std::move(toCopy.__iter);
980  return *this;
981  }
982 
984  template < typename T1, typename T2 >
986  operator++() noexcept {
987  ++__iter;
988  return *this;
989  }
990 
992  template < typename T1, typename T2 >
994  operator+=(Size nb) noexcept {
995  __iter += nb;
996  return *this;
997  }
998 
1000  template < typename T1, typename T2 >
1002  operator+(Size nb) noexcept {
1003  return BijectionIteratorSafe< T1, T2 >{*this} += nb;
1004  }
1005 
1007  template < typename T1, typename T2 >
1009  operator!=(const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1010  return __iter != toCompare.__iter;
1011  }
1012 
1014  template < typename T1, typename T2 >
1016  operator==(const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1017  return __iter == toCompare.__iter;
1018  }
1019 
1021  template < typename T1, typename T2 >
1022  INLINE const T1& BijectionIteratorSafe< T1, T2 >::first() const {
1023  return __iter.key();
1024  }
1025 
1027  template < typename T1, typename T2 >
1028  INLINE const T2& BijectionIteratorSafe< T1, T2 >::second() const {
1029  return Getter::op_second(__iter.val());
1030  }
1031 
1032  /* ===========================================================================
1033  */
1034  /* === BIJECTION UNSAFE ITERATORS ===
1035  */
1036  /* ===========================================================================
1037  */
1038 
1040  template < typename T1, typename T2 >
1042  GUM_CONSTRUCTOR(BijectionIterator);
1043  }
1044 
1046  template < typename T1, typename T2 >
1047  template < typename Alloc, bool Gen >
1050  __iter{bijection.__firstToSecond.cbegin()} {
1051  GUM_CONSTRUCTOR(BijectionIterator);
1052  }
1053 
1055  template < typename T1, typename T2 >
1056  template < typename Alloc >
1058  const Bijection< T1, T2, Alloc >& bijection) :
1059  __iter{bijection.__firstToSecond.cbegin()} {
1060  GUM_CONSTRUCTOR(BijectionIterator);
1061  }
1062 
1064  template < typename T1, typename T2 >
1066  const BijectionIterator< T1, T2 >& toCopy) :
1067  __iter{toCopy.__iter} {
1068  GUM_CONS_CPY(BijectionIterator);
1069  }
1070 
1072  template < typename T1, typename T2 >
1074  BijectionIterator< T1, T2 >&& from) noexcept :
1075  __iter{std::move(from.__iter)} {
1076  GUM_CONS_MOV(BijectionIterator);
1077  }
1078 
1080  template < typename T1, typename T2 >
1082  GUM_DESTRUCTOR(BijectionIterator);
1083  }
1084 
1086  template < typename T1, typename T2 >
1089  __iter = toCopy.__iter;
1090  return *this;
1091  }
1092 
1094  template < typename T1, typename T2 >
1097  __iter = std::move(toCopy.__iter);
1098  return *this;
1099  }
1100 
1102  template < typename T1, typename T2 >
1104  operator++() noexcept {
1105  ++__iter;
1106  return *this;
1107  }
1108 
1110  template < typename T1, typename T2 >
1112  operator+=(Size nb) noexcept {
1113  __iter += nb;
1114  return *this;
1115  }
1116 
1118  template < typename T1, typename T2 >
1120  operator+(Size nb) noexcept {
1121  return BijectionIterator< T1, T2 >{*this} += nb;
1122  }
1123 
1125  template < typename T1, typename T2 >
1126  INLINE bool BijectionIterator< T1, T2 >::
1127  operator!=(const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1128  return __iter != toCompare.__iter;
1129  }
1130 
1132  template < typename T1, typename T2 >
1133  INLINE bool BijectionIterator< T1, T2 >::
1134  operator==(const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1135  return __iter == toCompare.__iter;
1136  }
1137 
1139  template < typename T1, typename T2 >
1140  INLINE const T1& BijectionIterator< T1, T2 >::first() const {
1141  return __iter.key();
1142  }
1143 
1145  template < typename T1, typename T2 >
1146  INLINE const T2& BijectionIterator< T1, T2 >::second() const {
1147  return Getter::op_second(__iter.val());
1148  }
1149 
1150  // ============================================================================
1151  // BIJECTION
1152  // ============================================================================
1153 
1154  // Default constructor: creates a bijection without any association
1155  template < typename T1, typename T2, typename Alloc >
1156  INLINE Bijection< T1, T2, Alloc >::Bijection(Size size, bool resize_policy) :
1158  T2,
1159  Alloc,
1160  std::is_scalar< T1 >::value
1161  && std::is_scalar< T2 >::value >(size,
1162  resize_policy) {
1163  GUM_CONSTRUCTOR(Bijection);
1164  }
1165 
1166  // initializer list constructor
1167  template < typename T1, typename T2, typename Alloc >
1169  std::initializer_list< std::pair< T1, T2 > > list) :
1171  T2,
1172  Alloc,
1173  std::is_scalar< T1 >::value
1174  && std::is_scalar< T2 >::value >(list) {
1175  GUM_CONSTRUCTOR(Bijection);
1176  }
1177 
1178  // Copy constructor
1179  template < typename T1, typename T2, typename Alloc >
1181  const Bijection< T1, T2, Alloc >& toCopy) :
1183  T2,
1184  Alloc,
1185  std::is_scalar< T1 >::value
1186  && std::is_scalar< T2 >::value >(toCopy) {
1187  GUM_CONS_CPY(Bijection);
1188  }
1189 
1190  // Generalized copy constructor
1191  template < typename T1, typename T2, typename Alloc >
1192  template < typename OtherAlloc >
1194  const Bijection< T1, T2, OtherAlloc >& toCopy) :
1196  T2,
1197  Alloc,
1198  std::is_scalar< T1 >::value
1199  && std::is_scalar< T2 >::value >(toCopy) {
1200  GUM_CONS_CPY(Bijection);
1201  }
1202 
1203  // move constructor
1204  template < typename T1, typename T2, typename Alloc >
1206  Bijection< T1, T2, Alloc >&& from) noexcept :
1208  T2,
1209  Alloc,
1210  std::is_scalar< T1 >::value
1211  && std::is_scalar< T2 >::value >(
1212  std::move(from)) {
1213  GUM_CONS_MOV(Bijection);
1214  }
1215 
1216  // destructor
1217  template < typename T1, typename T2, typename Alloc >
1219  GUM_DESTRUCTOR(Bijection);
1220  }
1221 
1222  // copy operator
1223  template < typename T1, typename T2, typename Alloc >
1226  Implementation::operator=(toCopy);
1227  return *this;
1228  }
1229 
1230  // generalized copy operator
1231  template < typename T1, typename T2, typename Alloc >
1232  template < typename OtherAlloc >
1235  Implementation::operator=(toCopy);
1236  return *this;
1237  }
1238 
1239  // move operator
1240  template < typename T1, typename T2, typename Alloc >
1243  Implementation::operator=(std::move(bij));
1244  return *this;
1245  }
1246 
1247  // for friendly displaying the content of bijections
1248  template < typename T1, typename T2, typename Alloc >
1249  std::ostream& operator<<(std::ostream& stream,
1250  const Bijection< T1, T2, Alloc >& b) {
1251  stream << b.toString();
1252  return stream;
1253  }
1254 
1255 } /* 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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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:605
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
A non scalar implementation of a Bijection.
Definition: bijection.h:85
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55