aGrUM  0.13.2
bijection_tpl.h
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
27 // To simply IDE parsing
28 #include <agrum/core/bijection.h>
29 
30 namespace gum {
31 
32  // ===========================================================================
33  // === NON SCALAR BIJECTION IMPLEMENTATION ===
34  // ===========================================================================
35 
36  // returns the end iterator for other classes' statics
37  template < typename T1, typename T2, typename Alloc, bool Gen >
38  const BijectionIteratorSafe< T1, T2 >&
40  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
42  }
43 
44  // returns the end iterator for other classes' statics
45  template < typename T1, typename T2, typename Alloc, bool Gen >
48  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
50  }
51 
52  // a function that performs a complete copy of another bijection
53  template < typename T1, typename T2, typename Alloc, bool Gen >
54  template < typename OtherAlloc >
57  // parse f2s and perform copies
58  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
59  typename HashTable12::value_type* val1 =
60  &(__firstToSecond.insert(iter.key(), nullptr));
61  typename HashTable21::value_type* val2;
62 
63  try {
64  val2 = &(__secondToFirst.insert(*(iter.val()), nullptr));
65  } catch (...) {
66  __firstToSecond.erase(iter.key());
67  throw;
68  }
69 
70  val1->second = &(const_cast< T2& >(val2->first));
71  val2->second = &(const_cast< T1& >(val1->first));
72  }
73 
74  // note that __iter_end is actually a constant, whatever we add/remove
75  // to/from __firstToSecond. As a consequence, it need not be updated
76  // after __copy
77  }
78 
79  // Default constructor: creates a bijection without association
80  template < typename T1, typename T2, typename Alloc, bool Gen >
82  Size size, bool resize_policy) :
83  // warning: below, we create the internal hashTables with a key
84  // uniqueness
85  // policy set to false because we will do the uniqueness tests ourselves
86  // (this
87  // will speed-up the process)
88  __firstToSecond(size, resize_policy, false),
89  __secondToFirst(size, resize_policy, false) {
90  GUM_CONSTRUCTOR(BijectionImplementation);
91 
92  // make sure the end() iterator is constructed properly
93  end4Statics();
95  }
96 
97  // initializer list constructor
98  template < typename T1, typename T2, typename Alloc, bool Gen >
100  std::initializer_list< std::pair< T1, T2 > > list) :
101  __firstToSecond(Size(list.size()) / 2, true, false),
102  __secondToFirst(Size(list.size()) / 2, true, false) {
103  GUM_CONSTRUCTOR(BijectionImplementation);
104 
105  for (const auto& elt : list) {
106  insert(elt.first, elt.second);
107  }
108 
109  // make sure the end() iterator is constructed properly
110  end4Statics();
111  endSafe4Statics();
112  }
113 
114  // Copy constructor
115  template < typename T1, typename T2, typename Alloc, bool Gen >
118  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
119  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
120  GUM_CONS_CPY(BijectionImplementation);
121  __copy(toCopy.__firstToSecond);
122  }
123 
124  // Generalized copy constructor
125  template < typename T1, typename T2, typename Alloc, bool Gen >
126  template < typename OtherAlloc >
129  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
130  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
131  GUM_CONS_CPY(BijectionImplementation);
132  __copy(toCopy.__firstToSecond);
133  }
134 
135  // move constructor
136  template < typename T1, typename T2, typename Alloc, bool Gen >
139  __firstToSecond(std::move(from.__firstToSecond)),
140  __secondToFirst(std::move(from.__secondToFirst)) {
141  GUM_CONS_MOV(BijectionImplementation);
142  }
143 
144  // destructor
145  template < typename T1, typename T2, typename Alloc, bool Gen >
146  INLINE
148  GUM_DESTRUCTOR(BijectionImplementation);
149  }
150 
151  // removes all the associations from the bijection
152  template < typename T1, typename T2, typename Alloc, bool Gen >
156  // note that __iter_end is actually a constant, whatever we add/remove
157  // to/from __firstToSecond. As a consequence, it need not be updated
158  // after the clear's
159  }
160 
161  // Copy operator
162  template < typename T1, typename T2, typename Alloc, bool Gen >
166  // avoid self assignment
167  if (this != &toCopy) {
168  clear();
169  __copy(toCopy.__firstToSecond);
170  }
171 
172  // note that __iter_end is actually a constant, whatever we add/remove
173  // to/from __firstToSecond. As a consequence, it need not be updated
174  // after __copy
175  return *this;
176  }
177 
178  // Generalized copy operator
179  template < typename T1, typename T2, typename Alloc, bool Gen >
180  template < typename OtherAlloc >
184  clear();
185  __copy(toCopy.__firstToSecond);
186 
187  // note that __iter_end is actually a constant, whatever we add/remove
188  // to/from __firstToSecond. As a consequence, it need not be updated
189  // after __copy
190  return *this;
191  }
192 
193  // move operator
194  template < typename T1, typename T2, typename Alloc, bool Gen >
198  // avoid self assignment
199  if (this != &from) {
200  clear();
201  __firstToSecond = std::move(from.__firstToSecond);
202  __secondToFirst = std::move(from.__secondToFirst);
203  }
204 
205  // note that __iter_end is actually a constant, whatever we add/remove
206  // to/from __firstToSecond. As a consequence, it need not be updated
207  // after __copy
208  return *this;
209  }
210 
211  // returns the iterator at the beginning of the bijection
212  template < typename T1, typename T2, typename Alloc, bool Gen >
215  return BijectionIterator< T1, T2 >{*this};
216  }
217 
218  // returns the iterator at the beginning of the bijection
219  template < typename T1, typename T2, typename Alloc, bool Gen >
222  return BijectionIterator< T1, T2 >{*this};
223  }
224 
225  // returns the iterator to the end of the bijection
226  template < typename T1, typename T2, typename Alloc, bool Gen >
229  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
231  }
232 
233  // returns the iterator to the end of the bijection
234  template < typename T1, typename T2, typename Alloc, bool Gen >
238  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
240  }
241 
242  // returns the iterator at the beginning of the bijection
243  template < typename T1, typename T2, typename Alloc, bool Gen >
246  return BijectionIteratorSafe< T1, T2 >{*this};
247  }
248 
249  // returns the iterator at the beginning of the bijection
250  template < typename T1, typename T2, typename Alloc, bool Gen >
251  INLINE
254  return BijectionIteratorSafe< T1, T2 >{*this};
255  }
256 
257  // returns the iterator to the end of the bijection
258  template < typename T1, typename T2, typename Alloc, bool Gen >
262  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
264  }
265 
266  // returns the iterator to the end of the bijection
267  template < typename T1, typename T2, typename Alloc, bool Gen >
271  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
273  }
274 
275  // returns the value associated to the element passed in argument
276  template < typename T1, typename T2, typename Alloc, bool Gen >
277  INLINE const T1&
279  return *(__secondToFirst[second]);
280  }
281 
282  // returns the value associated to the element passed in argument
283  template < typename T1, typename T2, typename Alloc, bool Gen >
284  INLINE const T2&
286  return *(__firstToSecond[first]);
287  }
288 
289  // Test whether the bijection contains the "first" value
290  template < typename T1, typename T2, typename Alloc, bool Gen >
292  const T1& first) const {
293  return __firstToSecond.exists(first);
294  }
295 
296  // Test whether the bijection contains the "second" value
297  template < typename T1, typename T2, typename Alloc, bool Gen >
299  const T2& second) const {
300  return __secondToFirst.exists(second);
301  }
302 
303  // inserts a new association in the bijection
304  template < typename T1, typename T2, typename Alloc, bool Gen >
306  value_type*
308  const T2& second) {
309  // check the uniqueness property
310  if (existsFirst(first) || existsSecond(second)) {
312  "the bijection contains an element with the same key");
313  }
314 
315  // insert copies of first and second
316  typename HashTable12::value_type* val1 =
317  &(__firstToSecond.insert(first, nullptr));
318  typename HashTable21::value_type* val2;
319 
320  try {
321  val2 = &(__secondToFirst.insert(second, nullptr));
322  } catch (...) {
323  __firstToSecond.erase(first);
324  throw;
325  }
326 
327  val1->second = &(const_cast< T2& >(val2->first));
328  val2->second = &(const_cast< T1& >(val1->first));
329 
330  return val1;
331  }
332 
333  // inserts a new association in the bijection
334  template < typename T1, typename T2, typename Alloc, bool Gen >
336  value_type*
338  T2&& second) {
339  // check the uniqueness property
342  "the bijection contains an element with the same key");
343  }
344 
345  // insert copies of first and second
346  typename HashTable12::value_type* val1 =
347  &(__firstToSecond.insert(std::move(first), nullptr));
348  typename HashTable21::value_type* val2;
349 
350  try {
351  val2 = &(__secondToFirst.insert(std::move(second), nullptr));
352  } catch (...) {
353  __firstToSecond.erase(val1->first);
354  throw;
355  }
356 
357  val1->second = &(const_cast< T2& >(val2->first));
358  val2->second = &(const_cast< T1& >(val1->first));
359 
360  return val1;
361  }
362 
363  /* @brief Same method as first, but if the value is not found, a default
364  * value is inserted into the bijection */
365  template < typename T1, typename T2, typename Alloc, bool Gen >
367  const T2& second, const T1& val) const {
368  try {
369  return first(second);
370  } catch (NotFound&) { return __insert(val, second)->first; }
371  }
372 
373  /* @brief Same method as second, but if the value is not found, a default
374  * value is inserted into the bijection */
375  template < typename T1, typename T2, typename Alloc, bool Gen >
376  INLINE const T2&
378  const T1& first, const T2& val) const {
379  try {
380  return second(first);
381  } catch (NotFound&) { return *(__insert(first, val)->second); }
382  }
383 
384  // inserts a new association in the bijection
385  template < typename T1, typename T2, typename Alloc, bool Gen >
386  INLINE void
388  const T2& second) {
389  __insert(first, second);
390  }
391 
392  // inserts a new association in the bijection
393  template < typename T1, typename T2, typename Alloc, bool Gen >
395  T2&& second) {
396  __insert(std::move(first), std::move(second));
397  }
398 
399  // emplace a new element in the bijection
400  template < typename T1, typename T2, typename Alloc, bool Gen >
401  template < typename... Args >
402  INLINE void
404  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
405  __insert(std::move(new_elt.first), std::move(new_elt.second));
406  }
407 
408  // returns true if the bijection doesn't contain any relation
409  template < typename T1, typename T2, typename Alloc, bool Gen >
411  noexcept {
412  GUM_ASSERT(__firstToSecond.empty() == __secondToFirst.empty());
413  return __firstToSecond.empty();
414  }
415 
416  // returns the number of associations stored within the bijection
417  template < typename T1, typename T2, typename Alloc, bool Gen >
419  noexcept {
420  GUM_ASSERT(__firstToSecond.size() == __secondToFirst.size());
421  return __firstToSecond.size();
422  }
423 
424  // erases an association containing the given first element
425  template < typename T1, typename T2, typename Alloc, bool Gen >
426  INLINE void
428  try {
430  __firstToSecond.erase(first);
431  } catch (NotFound&) {}
432  }
433 
434  // erase an association containing the given second element
435  template < typename T1, typename T2, typename Alloc, bool Gen >
436  INLINE void
438  try {
440  __secondToFirst.erase(second);
441  } catch (NotFound&) {}
442  }
443 
444  // returns the number of hashtables' slots used (@sa hashTable's capacity)
445  template < typename T1, typename T2, typename Alloc, bool Gen >
447  noexcept {
448  return __firstToSecond.capacity();
449  }
450 
451  // similar to the hashtable's resize
452  template < typename T1, typename T2, typename Alloc, bool Gen >
453  INLINE void
455  __firstToSecond.resize(new_size);
456  __secondToFirst.resize(new_size);
457  }
458 
459  // enables the user to change dynamically the resizing policy
460  template < typename T1, typename T2, typename Alloc, bool Gen >
462  const bool new_policy) noexcept {
463  __firstToSecond.setResizePolicy(new_policy);
464  __secondToFirst.setResizePolicy(new_policy);
465  }
466 
467  // returns the current resizing policy
468  template < typename T1, typename T2, typename Alloc, bool Gen >
470  noexcept {
471  return __firstToSecond.resizePolicy();
472  }
473 
474  // friendly displays the content of the CliqueGraph
475  template < typename T1, typename T2, typename Alloc, bool Gen >
477  std::stringstream stream;
478  stream << "{ ";
479  bool first = true;
480 
481  for (iterator iter = begin(); iter != end(); ++iter) {
482  if (!first)
483  stream << ", ";
484  else
485  first = false;
486 
487  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
488  }
489 
490  stream << " }";
491  return stream.str();
492  }
493 
494  // ===========================================================================
495  // === SCALAR BIJECTION IMPLEMENTATION ===
496  // ===========================================================================
497 
498  // returns the end iterator for other classes' statics
499  template < typename T1, typename T2, typename Alloc >
502  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
504  }
505 
506  // returns the end iterator for other classes' statics
507  template < typename T1, typename T2, typename Alloc >
510  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
512  }
513 
514  // Default constructor: creates a bijection without association
515  template < typename T1, typename T2, typename Alloc >
517  Size size, bool resize_policy) :
518  // warning: below, we create the internal hashTables with a key
519  // uniqueness
520  // policy set to false because we will do the uniqueness tests ourselves
521  // (this
522  // will speed-up the process)
523  __firstToSecond(size, resize_policy, false),
524  __secondToFirst(size, resize_policy, false) {
525  GUM_CONSTRUCTOR(BijectionImplementation);
526 
527  // make sure the end() iterator is constructed properly
528  end4Statics();
529  endSafe4Statics();
530  }
531 
532  // initializer list constructor
533  template < typename T1, typename T2, typename Alloc >
535  std::initializer_list< std::pair< T1, T2 > > list) :
536  __firstToSecond(Size(list.size()) / 2, true, false),
537  __secondToFirst(Size(list.size()) / 2, true, false) {
538  GUM_CONSTRUCTOR(BijectionImplementation);
539 
540  for (const auto& elt : list) {
541  insert(elt.first, elt.second);
542  }
543 
544  // make sure the end() iterator is constructed properly
545  end4Statics();
546  endSafe4Statics();
547  }
548 
549  // a function that performs a complete copy of another bijection
550  template < typename T1, typename T2, typename Alloc >
551  template < typename OtherAlloc >
553  const HashTable< T1, T2, OtherAlloc >& f2s) {
554  // parse f2s and perform copies
555  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
556  __firstToSecond.insert(iter.key(), iter.val());
557 
558  try {
559  __secondToFirst.insert(iter.val(), iter.key());
560  } catch (...) {
561  __firstToSecond.erase(iter.key());
562  throw;
563  }
564  }
565 
566  // note that __iter_end is actually a constant, whatever we add/remove
567  // to/from __firstToSecond. As a consequence, it need not be updated
568  // after __copy
569  }
570 
571  // Copy constructor
572  template < typename T1, typename T2, typename Alloc >
575  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
576  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
577  GUM_CONS_CPY(BijectionImplementation);
578  __copy(toCopy.__firstToSecond);
579  }
580 
581  // Generalized copy constructor
582  template < typename T1, typename T2, typename Alloc >
583  template < typename OtherAlloc >
586  __firstToSecond(toCopy.__firstToSecond.capacity(), true, false),
587  __secondToFirst(toCopy.__secondToFirst.capacity(), true, false) {
588  GUM_CONS_CPY(BijectionImplementation);
589  __copy(toCopy.__firstToSecond);
590  }
591 
592  // move constructor
593  template < typename T1, typename T2, typename Alloc >
596  __firstToSecond(std::move(toCopy.__firstToSecond)),
597  __secondToFirst(std::move(toCopy.__secondToFirst)) {
598  GUM_CONS_MOV(BijectionImplementation);
599  }
600 
601  // destructor
602  template < typename T1, typename T2, typename Alloc >
603  INLINE
605  GUM_DESTRUCTOR(BijectionImplementation);
606  }
607 
608  // returns the iterator at the beginning of the bijection
609  template < typename T1, typename T2, typename Alloc >
612  return BijectionIterator< T1, T2 >{*this};
613  }
614 
615  // returns the iterator at the beginning of the bijection
616  template < typename T1, typename T2, typename Alloc >
619  return BijectionIterator< T1, T2 >{*this};
620  }
621 
622  // returns the iterator to the end of the bijection
623  template < typename T1, typename T2, typename Alloc >
626  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
628  }
629 
630  // returns the iterator to the end of the bijection
631  template < typename T1, typename T2, typename Alloc >
635  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
637  }
638 
639  // returns the iterator at the beginning of the bijection
640  template < typename T1, typename T2, typename Alloc >
643  return BijectionIteratorSafe< T1, T2 >{*this};
644  }
645 
646  // returns the iterator at the beginning of the bijection
647  template < typename T1, typename T2, typename Alloc >
648  INLINE
651  return BijectionIteratorSafe< T1, T2 >{*this};
652  }
653 
654  // returns the iterator to the end of the bijection
655  template < typename T1, typename T2, typename Alloc >
659  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
661  }
662 
663  // returns the iterator to the end of the bijection
664  template < typename T1, typename T2, typename Alloc >
668  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
670  }
671 
672  // removes all the associations from the bijection
673  template < typename T1, typename T2, typename Alloc >
677  // note that __iter_end is actually a constant, whatever we add/remove
678  // to/from __firstToSecond. As a consequence, it need not be updated
679  // after the clear's
680  }
681 
682  // Copy operator
683  template < typename T1, typename T2, typename Alloc >
687  // avoid self assignment
688  if (this != &toCopy) {
689  clear();
690  __copy(toCopy.__firstToSecond);
691  }
692 
693  // note that __iter_end is actually a constant, whatever we add/remove
694  // to/from __firstToSecond. As a consequence, it need not be updated
695  // after __copy
696  return *this;
697  }
698 
699  // Generalized copy operator
700  template < typename T1, typename T2, typename Alloc >
701  template < typename OtherAlloc >
705  clear();
706  __copy(toCopy.__firstToSecond);
707 
708  // note that __iter_end is actually a constant, whatever we add/remove
709  // to/from __firstToSecond. As a consequence, it need not be updated
710  // after __copy
711  return *this;
712  }
713 
714  // move operator
715  template < typename T1, typename T2, typename Alloc >
719  // avoid self assignment
720  if (this != &toCopy) {
721  clear();
722  __firstToSecond = std::move(toCopy.__firstToSecond);
723  __secondToFirst = std::move(toCopy.__secondToFirst);
724  }
725 
726  // note that __iter_end is actually a constant, whatever we add/remove
727  // to/from __firstToSecond. As a consequence, it need not be updated
728  // after __copy
729  return *this;
730  }
731 
732  // returns the value associated to the element passed in argument
733  template < typename T1, typename T2, typename Alloc >
734  INLINE const T1&
736  return __secondToFirst[second];
737  }
738 
739  // returns the value associated to the element passed in argument
740  template < typename T1, typename T2, typename Alloc >
741  INLINE const T2&
743  return __firstToSecond[first];
744  }
745 
746  // Test whether the bijection contains the "first" value
747  template < typename T1, typename T2, typename Alloc >
748  INLINE bool
750  return __firstToSecond.exists(first);
751  }
752 
753  // Test whether the bijection contains the "second" value
754  template < typename T1, typename T2, typename Alloc >
755  INLINE bool
757  return __secondToFirst.exists(second);
758  }
759 
760  // inserts a new association in the bijection
761  template < typename T1, typename T2, typename Alloc >
763  T2 second) {
764  // check the uniqueness property
765  if (existsFirst(first) || existsSecond(second)) {
767  "the bijection contains an element with the same key");
768  }
769 
770  // insert copies of first and second
771  __firstToSecond.insert(first, second);
772 
773  try {
774  __secondToFirst.insert(second, first);
775  } catch (...) {
776  __firstToSecond.erase(first);
777  throw;
778  }
779  }
780 
781  // inserts a new association in the bijection
782  template < typename T1, typename T2, typename Alloc >
784  T2 second) {
785  __insert(first, second);
786  }
787 
788  // emplace a new element in the bijection
789  template < typename T1, typename T2, typename Alloc >
790  template < typename... Args >
791  INLINE void
793  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
794  __insert(new_elt.first, new_elt.second);
795  }
796 
797  /* @brief Same method as first, but if the value is not found, a default
798  * value is inserted into the bijection */
799  template < typename T1, typename T2, typename Alloc >
800  INLINE const T1&
802  T2 second, T1 val) const {
803  try {
804  return first(second);
805  } catch (NotFound&) {
806  __insert(val, second);
807  return val;
808  }
809  }
810 
811  /* @brief Same method as second, but if the value is not found, a default
812  * value is inserted into the bijection */
813  template < typename T1, typename T2, typename Alloc >
814  INLINE const T2&
816  T1 first, T2 val) const {
817  try {
818  return second(first);
819  } catch (NotFound&) {
820  __insert(first, val);
821  return val;
822  }
823  }
824 
825  // returns true if the bijection doesn't contain any relation
826  template < typename T1, typename T2, typename Alloc >
828  noexcept {
829  GUM_ASSERT(__firstToSecond.empty() == __secondToFirst.empty());
830  return __firstToSecond.empty();
831  }
832 
833  // returns the number of associations stored within the bijection
834  template < typename T1, typename T2, typename Alloc >
836  noexcept {
837  GUM_ASSERT(__firstToSecond.size() == __secondToFirst.size());
838  return __firstToSecond.size();
839  }
840 
841  // erases an association containing the given first element
842  template < typename T1, typename T2, typename Alloc >
843  INLINE void
845  try {
847  __firstToSecond.erase(first);
848  } catch (NotFound&) {}
849  }
850 
851  // erase an association containing the given second element
852  template < typename T1, typename T2, typename Alloc >
853  INLINE void
855  try {
857  __secondToFirst.erase(second);
858  } catch (NotFound&) {}
859  }
860 
861  // returns the number of hashtables' slots used (@sa hashTable's capacity)
862  template < typename T1, typename T2, typename Alloc >
864  noexcept {
865  return __firstToSecond.capacity();
866  }
867 
868  // similar to the hashtable's resize
869  template < typename T1, typename T2, typename Alloc >
870  INLINE void
872  __firstToSecond.resize(new_size);
873  __secondToFirst.resize(new_size);
874  }
875 
876  // enables the user to change dynamically the resizing policy
877  template < typename T1, typename T2, typename Alloc >
879  const bool new_policy) noexcept {
880  __firstToSecond.setResizePolicy(new_policy);
881  __secondToFirst.setResizePolicy(new_policy);
882  }
883 
884  // returns the current resizing policy
885  template < typename T1, typename T2, typename Alloc >
887  noexcept {
888  return __firstToSecond.resizePolicy();
889  }
890 
891  // friendly displays the content of the CliqueGraph
892  template < typename T1, typename T2, typename Alloc >
894  std::stringstream stream;
895  stream << "{ ";
896  bool first = true;
897 
898  for (iterator iter = begin(); iter != end(); ++iter) {
899  if (!first)
900  stream << ", ";
901  else
902  first = false;
903 
904  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
905  }
906 
907  stream << " }";
908  return stream.str();
909  }
910 
911  // ===========================================================================
912  // === BIJECTION SAFE ITERATORS ===
913  // ===========================================================================
914 
916  template < typename T1, typename T2 >
918  GUM_CONSTRUCTOR(BijectionIteratorSafe);
919  }
920 
922  template < typename T1, typename T2 >
923  template < typename Alloc, bool Gen >
926  __iter{bijection.__firstToSecond.cbeginSafe()} {
927  GUM_CONSTRUCTOR(BijectionIteratorSafe);
928  }
929 
931  template < typename T1, typename T2 >
932  template < typename Alloc >
934  const Bijection< T1, T2, Alloc >& bijection) :
935  __iter{bijection.__firstToSecond.cbeginSafe()} {
936  GUM_CONSTRUCTOR(BijectionIteratorSafe);
937  }
938 
940  template < typename T1, typename T2 >
942  const BijectionIteratorSafe< T1, T2 >& toCopy) :
943  __iter{toCopy.__iter} {
944  GUM_CONS_CPY(BijectionIteratorSafe);
945  }
946 
948  template < typename T1, typename T2 >
950  BijectionIteratorSafe< T1, T2 >&& from) noexcept :
951  __iter{std::move(from.__iter)} {
952  GUM_CONS_MOV(BijectionIteratorSafe);
953  }
954 
956  template < typename T1, typename T2 >
958  GUM_DESTRUCTOR(BijectionIteratorSafe);
959  }
960 
962  template < typename T1, typename T2 >
965  __iter = toCopy.__iter;
966  return *this;
967  }
968 
970  template < typename T1, typename T2 >
973  __iter = std::move(toCopy.__iter);
974  return *this;
975  }
976 
978  template < typename T1, typename T2 >
980  operator++() noexcept {
981  ++__iter;
982  return *this;
983  }
984 
986  template < typename T1, typename T2 >
988  operator+=(unsigned int nb) noexcept {
989  __iter += nb;
990  return *this;
991  }
992 
994  template < typename T1, typename T2 >
996  operator+(unsigned int nb) noexcept {
997  return BijectionIteratorSafe< T1, T2 >{*this} += nb;
998  }
999 
1001  template < typename T1, typename T2 >
1003  operator!=(const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1004  return __iter != toCompare.__iter;
1005  }
1006 
1008  template < typename T1, typename T2 >
1010  operator==(const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1011  return __iter == toCompare.__iter;
1012  }
1013 
1015  template < typename T1, typename T2 >
1016  INLINE const T1& BijectionIteratorSafe< T1, T2 >::first() const {
1017  return __iter.key();
1018  }
1019 
1021  template < typename T1, typename T2 >
1022  INLINE const T2& BijectionIteratorSafe< T1, T2 >::second() const {
1023  return Getter::op_second(__iter.val());
1024  }
1025 
1026  /* ===========================================================================
1027  */
1028  /* === BIJECTION UNSAFE ITERATORS ===
1029  */
1030  /* ===========================================================================
1031  */
1032 
1034  template < typename T1, typename T2 >
1036  GUM_CONSTRUCTOR(BijectionIterator);
1037  }
1038 
1040  template < typename T1, typename T2 >
1041  template < typename Alloc, bool Gen >
1044  __iter{bijection.__firstToSecond.cbegin()} {
1045  GUM_CONSTRUCTOR(BijectionIterator);
1046  }
1047 
1049  template < typename T1, typename T2 >
1050  template < typename Alloc >
1052  const Bijection< T1, T2, Alloc >& bijection) :
1053  __iter{bijection.__firstToSecond.cbegin()} {
1054  GUM_CONSTRUCTOR(BijectionIterator);
1055  }
1056 
1058  template < typename T1, typename T2 >
1060  const BijectionIterator< T1, T2 >& toCopy) :
1061  __iter{toCopy.__iter} {
1062  GUM_CONS_CPY(BijectionIterator);
1063  }
1064 
1066  template < typename T1, typename T2 >
1068  BijectionIterator< T1, T2 >&& from) noexcept :
1069  __iter{std::move(from.__iter)} {
1070  GUM_CONS_MOV(BijectionIterator);
1071  }
1072 
1074  template < typename T1, typename T2 >
1076  GUM_DESTRUCTOR(BijectionIterator);
1077  }
1078 
1080  template < typename T1, typename T2 >
1083  __iter = toCopy.__iter;
1084  return *this;
1085  }
1086 
1088  template < typename T1, typename T2 >
1091  __iter = std::move(toCopy.__iter);
1092  return *this;
1093  }
1094 
1096  template < typename T1, typename T2 >
1098  operator++() noexcept {
1099  ++__iter;
1100  return *this;
1101  }
1102 
1104  template < typename T1, typename T2 >
1106  operator+=(unsigned int nb) noexcept {
1107  __iter += nb;
1108  return *this;
1109  }
1110 
1112  template < typename T1, typename T2 >
1114  operator+(unsigned int nb) noexcept {
1115  return BijectionIterator< T1, T2 >{*this} += nb;
1116  }
1117 
1119  template < typename T1, typename T2 >
1120  INLINE bool BijectionIterator< T1, T2 >::
1121  operator!=(const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1122  return __iter != toCompare.__iter;
1123  }
1124 
1126  template < typename T1, typename T2 >
1127  INLINE bool BijectionIterator< T1, T2 >::
1128  operator==(const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1129  return __iter == toCompare.__iter;
1130  }
1131 
1133  template < typename T1, typename T2 >
1134  INLINE const T1& BijectionIterator< T1, T2 >::first() const {
1135  return __iter.key();
1136  }
1137 
1139  template < typename T1, typename T2 >
1140  INLINE const T2& BijectionIterator< T1, T2 >::second() const {
1141  return Getter::op_second(__iter.val());
1142  }
1143 
1144  // ============================================================================
1145  // BIJECTION
1146  // ============================================================================
1147 
1148  // Default constructor: creates a bijection without any association
1149  template < typename T1, typename T2, typename Alloc >
1150  INLINE Bijection< T1, T2, Alloc >::Bijection(Size size, bool resize_policy) :
1152  T2,
1153  Alloc,
1154  std::is_scalar< T1 >::value
1155  && std::is_scalar< T2 >::value >(size,
1156  resize_policy) {
1157  GUM_CONSTRUCTOR(Bijection);
1158  }
1159 
1160  // initializer list constructor
1161  template < typename T1, typename T2, typename Alloc >
1163  std::initializer_list< std::pair< T1, T2 > > list) :
1165  T2,
1166  Alloc,
1167  std::is_scalar< T1 >::value
1168  && std::is_scalar< T2 >::value >(list) {
1169  GUM_CONSTRUCTOR(Bijection);
1170  }
1171 
1172  // Copy constructor
1173  template < typename T1, typename T2, typename Alloc >
1175  const Bijection< T1, T2, Alloc >& toCopy) :
1177  T2,
1178  Alloc,
1179  std::is_scalar< T1 >::value
1180  && std::is_scalar< T2 >::value >(toCopy) {
1181  GUM_CONS_CPY(Bijection);
1182  }
1183 
1184  // Generalized copy constructor
1185  template < typename T1, typename T2, typename Alloc >
1186  template < typename OtherAlloc >
1188  const Bijection< T1, T2, OtherAlloc >& toCopy) :
1190  T2,
1191  Alloc,
1192  std::is_scalar< T1 >::value
1193  && std::is_scalar< T2 >::value >(toCopy) {
1194  GUM_CONS_CPY(Bijection);
1195  }
1196 
1197  // move constructor
1198  template < typename T1, typename T2, typename Alloc >
1200  Bijection< T1, T2, Alloc >&& from) noexcept :
1202  T2,
1203  Alloc,
1204  std::is_scalar< T1 >::value
1205  && std::is_scalar< T2 >::value >(
1206  std::move(from)) {
1207  GUM_CONS_MOV(Bijection);
1208  }
1209 
1210  // destructor
1211  template < typename T1, typename T2, typename Alloc >
1213  GUM_DESTRUCTOR(Bijection);
1214  }
1215 
1216  // copy operator
1217  template < typename T1, typename T2, typename Alloc >
1220  Implementation::operator=(toCopy);
1221  return *this;
1222  }
1223 
1224  // generalized copy operator
1225  template < typename T1, typename T2, typename Alloc >
1226  template < typename OtherAlloc >
1229  Implementation::operator=(toCopy);
1230  return *this;
1231  }
1232 
1233  // move operator
1234  template < typename T1, typename T2, typename Alloc >
1237  Implementation::operator=(std::move(bij));
1238  return *this;
1239  }
1240 
1241  // for friendly displaying the content of bijections
1242  template < typename T1, typename T2, typename Alloc >
1243  std::ostream& operator<<(std::ostream& stream,
1244  const Bijection< T1, T2, Alloc >& b) {
1245  stream << b.toString();
1246  return stream;
1247  }
1248 
1249 } /* namespace gum */
const T2 & second() const
Returns the second element of the current association.
BijectionIterator() noexcept
Default constructor.
void resize(Size new_size)
Changes the number of slots in the &#39;nodes&#39; vector of the hash table.
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:649
unsigned long Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:50
void __copy(const HashTable< T1, T2 *, OtherAlloc > &source)
A function that performs a complete copy of another gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
void clear()
Removes all the associations from the gum::Bijection.
static const BijectionIterator< int, int > * end4Statics()
Creates (if needed) and returns the iterator __BijectionIterEnd.
BijectionIteratorSafe() noexcept
Default constructor.
BijectionImplementation< T1, T2, Alloc, Gen > & operator=(const BijectionImplementation< T1, T2, Alloc, Gen > &toCopy)
Copy operator.
BijectionIterator< T1, T2 > & operator+=(unsigned int nb) noexcept
Moves the iterator by nb elements.
bool operator!=(const BijectionIterator< T1, T2 > &toCompare) const noexcept
Inequality operator.
const_iterator cbegin() const
Returns the constant unsafe iterator at the beginning of the gum::Bjection.
BijectionIterator< T1, T2 > & operator++() noexcept
Go to the next association, if it exists.
Size size() const noexcept
Returns the number of elements stored into the hashtable.
void eraseFirst(const T1 &first)
Erases an association containing the given first element.
bool operator!=(const BijectionIteratorSafe< T1, T2 > &toCompare) const noexcept
Inequality operator.
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
void erase(const Key &key)
Removes a given element from the hash table.
Safe iterators for bijectionIterator.
Definition: bijection.h:1409
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
STL namespace.
void setResizePolicy(const bool new_policy) noexcept
Enables the user to change dynamically the resizing policy.
bool resizePolicy() const noexcept
Returns the current resizing policy.
const T2 & second() const
Returns the second element of the current association.
HashIter __iter
The hashTable iterator that actually does all the job.
Definition: bijection.h:1591
const T1 & first() const
Returns the first element of the current association.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
static const iterator_safe & endSafe4Statics()
Returns the safe end iterator for other classes&#39; statics.
Definition: bijection_tpl.h:39
void resize(Size new_size)
Manually resize the gum::Bijection.
const_iterator_safe cbeginSafe() const
Returns the constant safe iterator at the begining of the gum::Bijection.
const const_iterator_safe & cendSafe() const noexcept
Returns the constant safe iterator at the end of the gum::Bijection.
~Bijection()
Class destructor.
The class for generic Hash Tables.
Definition: hashTable.h:676
static const BijectionIteratorSafe< int, int > * endSafe4Statics()
Creates (if needed) and returns the iterator __BijectionIterEndSafe.
const T2 & secondWithDefault(const T1 &second, const T2 &default_val) const
Returns the second value of a pair given its first value or default_val if first is unfound...
static INLINE const T & op_second(const T *x)
Returns a refeence over a pointer.
Definition: bijection.h:1368
const_iterator cbegin() const
Returns an unsafe const_iterator pointing to the beginning of the hashtable.
BijectionIterator< T1, T2 > operator+(unsigned int nb) noexcept
Return a new iterator.
void eraseSecond(const T2 &second)
Erases an association containing the given second element.
Size capacity() const noexcept
Returns the number of hashtables slots used.
const iterator & end() const noexcept
Returns the unsafe iterator at the end of the gum::Bijection.
Bijection< T1, T2, Alloc > & operator=(const Bijection< T1, T2, Alloc > &toCopy)
Copy operator.
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:573
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:658
Unsafe iterators for bijection.
Definition: bijection.h:1607
iterator begin() const
Returns the unsafe iterator at the beginning of the gum::Bijection.
bool existsSecond(const T2 &second) const
Returns true if second is the second element in a pair in the gum::Bijection.
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1803
iterator_safe beginSafe() const
Returns the safe iterator at the beginning of the gum::Bijection.
BijectionIteratorSafe< T1, T2 > operator+(unsigned int nb) noexcept
Returns a new iterator.
const const_iterator & cend() const noexcept
Returns the constant iterator at the end of the gum::Bijection.
bool operator==(const BijectionIterator< T1, T2 > &toCompare) const noexcept
Equality operator.
BijectionIteratorSafe< T1, T2 > & operator++() noexcept
Go to the next association, if it exists.
Size capacity() const noexcept
Returns the number of slots in the &#39;nodes&#39; vector of the hashtable.
static const BijectionIterator< int, int > * __BijectionIterEnd
The unsafe iterator used by everyone.
Definition: bijection.h:1335
std::string toString() const
Returns a friendly representatin of the gum::Bijection.
Size size() const noexcept
Returns the number of associations stored within the gum::Bijection.
std::pair< const T1, T2 * > value_type
Definition: hashTable.h:682
~BijectionIterator() noexcept
Class destructor.
~BijectionImplementation()
Destructor.
void clear()
Removes all the elements in the hash table.
static const BijectionIteratorSafe< int, int > * __BijectionIterEndSafe
The safe iterator used by everyone.
Definition: bijection.h:1332
BijectionIteratorSafe< T1, T2 > & operator=(const BijectionIteratorSafe< T1, T2 > &toCopy)
Copy operator.
HashIter __iter
The hashTable iterator that actually does all the job.
Definition: bijection.h:1780
const T1 & first() const
Returns the first element of the current association.
bool resizePolicy() const noexcept
Returns true if the resize policy is automatic.
Bijection(Size size=HashTableConst::default_size, bool resize_policy=HashTableConst::default_resize_policy)
Default constructor: creates a gum::Bijection without any association.
const iterator_safe & endSafe() const noexcept
Returns the safe iterator at the end of the gum::Bijection.
static const iterator & end4Statics()
Returns the unsafe end iterator for other classes&#39; statics.
Definition: bijection_tpl.h:47
HashTable21 __secondToFirst
The gum::HashTable associating T1 objects to T2 objects.
Definition: bijection.h:661
BijectionIteratorSafe< T1, T2 > & operator+=(unsigned int nb) noexcept
Moves the iterator by nb elements.
const T1 & first(const T2 &second) const
Returns the first value of a pair given its second value.
~BijectionIteratorSafe() noexcept
Class destructor.
BijectionIterator< T1, T2 > & operator=(const BijectionIterator< T1, T2 > &toCopy)
Copy operator.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
bool empty() const noexcept
Indicates whether the hash table is empty.
HashTable12::value_type * __insert(const T1 &first, const T2 &second)
Inserts a new association into the gum::Bijection.
void setResizePolicy(const bool new_policy) noexcept
Change the gum::Bijection resizing policy.
bool operator==(const BijectionIteratorSafe< T1, T2 > &toCompare) const noexcept
Equality operator.
Set of pairs of elements with fast search for both elements.
A non scalar implementation of a Bijection.
Definition: bijection.h:83
void emplace(Args &&...args)
Emplace a new element in the gum::Bijection.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:66
const T1 & firstWithDefault(const T2 &second, const T1 &default_val) const
Returns the first value of a pair given its second value or default_val if second is unfound...