aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
bijection_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Class providing generic double hash tables
25  *
26  * @author Jean-Philippe DUBUS, Christophe GONZALES(@AMU) and Pierre-Henri
27  * WUILLEMIN(@LIP6)
28  */
29 
30 // To simply IDE parsing
31 #include <agrum/tools/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 >&
42  BijectionImplementation< T1, T2, Alloc, Gen >::endSafe4Statics() {
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 >
50  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
52  }
53 
54  // a function that performs a complete copy of another bijection
55  template < typename T1, typename T2, typename Alloc, bool Gen >
56  template < typename OtherAlloc >
58  const HashTable< T1, T2*, OtherAlloc >& f2s) {
59  // parse f2s and perform copies
60  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
61  typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(iter.key(), nullptr));
62  typename HashTable21::value_type* val2;
63 
64  try {
65  val2 = &(_secondToFirst_.insert(*(iter.val()), nullptr));
66  } catch (...) {
68  throw;
69  }
70 
71  val1->second = &(const_cast< T2& >(val2->first));
72  val2->second = &(const_cast< T1& >(val1->first));
73  }
74 
75  // note that _iter_end_ is actually a constant, whatever we add/remove
76  // to/from _firstToSecond_. As a consequence, it need not be updated
77  // after _copy_
78  }
79 
80  // Default constructor: creates a bijection without association
81  template < typename T1, typename T2, typename Alloc, bool Gen >
82  INLINE
84  bool resize_policy) :
85  // warning: below, we create the internal hashTables with a key
86  // uniqueness
87  // policy set to false because we will do the uniqueness tests ourselves
88  // (this
89  // will speed-up the process)
93 
94  // make sure the end() iterator is constructed properly
95  end4Statics();
97  }
98 
99  // initializer list constructor
100  template < typename T1, typename T2, typename Alloc, bool Gen >
102  std::initializer_list< std::pair< T1, T2 > > list) :
103  _firstToSecond_(Size(list.size()) / 2, true, false),
104  _secondToFirst_(Size(list.size()) / 2, true, false) {
106 
107  for (const auto& elt: list) {
109  }
110 
111  // make sure the end() iterator is constructed properly
112  end4Statics();
113  endSafe4Statics();
114  }
115 
116  // Copy constructor
117  template < typename T1, typename T2, typename Alloc, bool Gen >
119  const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy) :
124  }
125 
126  // Generalized copy constructor
127  template < typename T1, typename T2, typename Alloc, bool Gen >
128  template < typename OtherAlloc >
135  }
136 
137  // move constructor
138  template < typename T1, typename T2, typename Alloc, bool Gen >
140  BijectionImplementation< T1, T2, Alloc, Gen >&& from) noexcept :
144  }
145 
146  // destructor
147  template < typename T1, typename T2, typename Alloc, bool Gen >
150  }
151 
152  // removes all the associations from the bijection
153  template < typename T1, typename T2, typename Alloc, bool Gen >
157  // note that _iter_end_ is actually a constant, whatever we add/remove
158  // to/from _firstToSecond_. As a consequence, it need not be updated
159  // after the clear's
160  }
161 
162  // Copy operator
163  template < typename T1, typename T2, typename Alloc, bool Gen >
166  const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy) {
167  // avoid self assignment
168  if (this != &toCopy) {
169  clear();
171  }
172 
173  // note that _iter_end_ is actually a constant, whatever we add/remove
174  // to/from _firstToSecond_. As a consequence, it need not be updated
175  // after _copy_
176  return *this;
177  }
178 
179  // Generalized copy operator
180  template < typename T1, typename T2, typename Alloc, bool Gen >
181  template < typename OtherAlloc >
185  clear();
187 
188  // note that _iter_end_ is actually a constant, whatever we add/remove
189  // to/from _firstToSecond_. As a consequence, it need not be updated
190  // after _copy_
191  return *this;
192  }
193 
194  // move operator
195  template < typename T1, typename T2, typename Alloc, bool Gen >
199  // avoid self assignment
200  if (this != &from) {
201  clear();
204  }
205 
206  // note that _iter_end_ is actually a constant, whatever we add/remove
207  // to/from _firstToSecond_. As a consequence, it need not be updated
208  // after _copy_
209  return *this;
210  }
211 
212  // returns the iterator at the beginning of the bijection
213  template < typename T1, typename T2, typename Alloc, bool Gen >
216  return BijectionIterator< T1, T2 >{*this};
217  }
218 
219  // returns the iterator at the beginning of the bijection
220  template < typename T1, typename T2, typename Alloc, bool Gen >
223  return BijectionIterator< T1, T2 >{*this};
224  }
225 
226  // returns the iterator to the end of the bijection
227  template < typename T1, typename T2, typename Alloc, bool Gen >
228  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::iterator&
229  BijectionImplementation< T1, T2, Alloc, Gen >::end() const noexcept {
230  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
232  }
233 
234  // returns the iterator to the end of the bijection
235  template < typename T1, typename T2, typename Alloc, bool Gen >
237  BijectionImplementation< T1, T2, Alloc, Gen >::cend() const noexcept {
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 >
253  return BijectionIteratorSafe< T1, T2 >{*this};
254  }
255 
256  // returns the iterator to the end of the bijection
257  template < typename T1, typename T2, typename Alloc, bool Gen >
258  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::iterator_safe&
259  BijectionImplementation< T1, T2, Alloc, Gen >::endSafe() const noexcept {
260  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
262  }
263 
264  // returns the iterator to the end of the bijection
265  template < typename T1, typename T2, typename Alloc, bool Gen >
267  BijectionImplementation< T1, T2, Alloc, Gen >::cendSafe() const noexcept {
268  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
270  }
271 
272  // returns the value associated to the element passed in argument
273  template < typename T1, typename T2, typename Alloc, bool Gen >
274  INLINE const T1& BijectionImplementation< T1, T2, Alloc, Gen >::first(const T2& second) const {
275  return *(_secondToFirst_[second]);
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 T2& BijectionImplementation< T1, T2, Alloc, Gen >::second(const T1& first) const {
281  return *(_firstToSecond_[first]);
282  }
283 
284  // Test whether the bijection contains the "first" value
285  template < typename T1, typename T2, typename Alloc, bool Gen >
287  return _firstToSecond_.exists(first);
288  }
289 
290  // Test whether the bijection contains the "second" value
291  template < typename T1, typename T2, typename Alloc, bool Gen >
293  return _secondToFirst_.exists(second);
294  }
295 
296  // inserts a new association in the bijection
297  template < typename T1, typename T2, typename Alloc, bool Gen >
300  // check the uniqueness property
303  "the bijection contains an element with the same couple (" << first << "," << second
304  << ")");
305  }
306 
307  // insert copies of first and second
308  typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(first, nullptr));
309  typename HashTable21::value_type* val2;
310 
311  try {
312  val2 = &(_secondToFirst_.insert(second, nullptr));
313  } catch (...) {
315  throw;
316  }
317 
318  val1->second = &(const_cast< T2& >(val2->first));
319  val2->second = &(const_cast< T1& >(val1->first));
320 
321  return val1;
322  }
323 
324  // inserts a new association in the bijection
325  template < typename T1, typename T2, typename Alloc, bool Gen >
328  // check the uniqueness property
331  "the bijection contains an element with the same couple (" << first << "," << second
332  << ")");
333  }
334 
335  // insert copies of first and second
336  typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(std::move(first), nullptr));
337  typename HashTable21::value_type* val2;
338 
339  try {
340  val2 = &(_secondToFirst_.insert(std::move(second), nullptr));
341  } catch (...) {
343  throw;
344  }
345 
346  val1->second = &(const_cast< T2& >(val2->first));
347  val2->second = &(const_cast< T1& >(val1->first));
348 
349  return val1;
350  }
351 
352  /* @brief Same method as first, but if the value is not found, a default
353  * value is inserted into the bijection */
354  template < typename T1, typename T2, typename Alloc, bool Gen >
355  INLINE const T1&
357  const T1& val) const {
358  try {
359  return first(second);
360  } catch (NotFound&) { return _insert_(val, second)->first; }
361  }
362 
363  /* @brief Same method as second, 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 >
366  INLINE const T2&
368  const T2& val) const {
369  try {
370  return second(first);
371  } catch (NotFound&) { return *(_insert_(first, val)->second); }
372  }
373 
374  // inserts a new association in the bijection
375  template < typename T1, typename T2, typename Alloc, bool Gen >
377  const T2& second) {
379  }
380 
381  // inserts a new association in the bijection
382  template < typename T1, typename T2, typename Alloc, bool Gen >
385  }
386 
387  // emplace a new element in the bijection
388  template < typename T1, typename T2, typename Alloc, bool Gen >
389  template < typename... Args >
391  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
393  }
394 
395  // returns true if the bijection doesn't contain any relation
396  template < typename T1, typename T2, typename Alloc, bool Gen >
397  INLINE bool BijectionImplementation< T1, T2, Alloc, Gen >::empty() const noexcept {
399  return _firstToSecond_.empty();
400  }
401 
402  // returns the number of associations stored within the bijection
403  template < typename T1, typename T2, typename Alloc, bool Gen >
404  INLINE Size BijectionImplementation< T1, T2, Alloc, Gen >::size() const noexcept {
406  return _firstToSecond_.size();
407  }
408 
409  // erases an association containing the given first element
410  template < typename T1, typename T2, typename Alloc, bool Gen >
412  try {
415  } catch (NotFound&) {}
416  }
417 
418  // erase an association containing the given second element
419  template < typename T1, typename T2, typename Alloc, bool Gen >
421  try {
424  } catch (NotFound&) {}
425  }
426 
427  // returns the number of hashtables' slots used (@sa hashTable's capacity)
428  template < typename T1, typename T2, typename Alloc, bool Gen >
430  return _firstToSecond_.capacity();
431  }
432 
433  // similar to the hashtable's resize
434  template < typename T1, typename T2, typename Alloc, bool Gen >
438  }
439 
440  // enables the user to change dynamically the resizing policy
441  template < typename T1, typename T2, typename Alloc, bool Gen >
443  const bool new_policy) noexcept {
446  }
447 
448  // returns the current resizing policy
449  template < typename T1, typename T2, typename Alloc, bool Gen >
450  INLINE bool BijectionImplementation< T1, T2, Alloc, Gen >::resizePolicy() const noexcept {
451  return _firstToSecond_.resizePolicy();
452  }
453 
454  // friendly displays the content of the CliqueGraph
455  template < typename T1, typename T2, typename Alloc, bool Gen >
458  stream << "{ ";
459  bool first = true;
460 
461  for (iterator iter = begin(); iter != end(); ++iter) {
462  if (!first)
463  stream << ", ";
464  else
465  first = false;
466 
467  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
468  }
469 
470  stream << " }";
471  return stream.str();
472  }
473 
474  // ===========================================================================
475  // === SCALAR BIJECTION IMPLEMENTATION ===
476  // ===========================================================================
477 
478  // returns the end iterator for other classes' statics
479  template < typename T1, typename T2, typename Alloc >
480  const BijectionIteratorSafe< T1, T2 >&
482  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
484  }
485 
486  // returns the end iterator for other classes' statics
487  template < typename T1, typename T2, typename Alloc >
489  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
491  }
492 
493  // Default constructor: creates a bijection without association
494  template < typename T1, typename T2, typename Alloc >
495  INLINE
497  bool resize_policy) :
498  // warning: below, we create the internal hashTables with a key
499  // uniqueness
500  // policy set to false because we will do the uniqueness tests ourselves
501  // (this
502  // will speed-up the process)
506 
507  // make sure the end() iterator is constructed properly
508  end4Statics();
509  endSafe4Statics();
510  }
511 
512  // initializer list constructor
513  template < typename T1, typename T2, typename Alloc >
515  std::initializer_list< std::pair< T1, T2 > > list) :
516  _firstToSecond_(Size(list.size()) / 2, true, false),
517  _secondToFirst_(Size(list.size()) / 2, true, false) {
519 
520  for (const auto& elt: list) {
522  }
523 
524  // make sure the end() iterator is constructed properly
525  end4Statics();
526  endSafe4Statics();
527  }
528 
529  // a function that performs a complete copy of another bijection
530  template < typename T1, typename T2, typename Alloc >
531  template < typename OtherAlloc >
533  const HashTable< T1, T2, OtherAlloc >& f2s) {
534  // parse f2s and perform copies
535  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
537 
538  try {
540  } catch (...) {
542  throw;
543  }
544  }
545 
546  // note that _iter_end_ is actually a constant, whatever we add/remove
547  // to/from _firstToSecond_. As a consequence, it need not be updated
548  // after _copy_
549  }
550 
551  // Copy constructor
552  template < typename T1, typename T2, typename Alloc >
554  const BijectionImplementation< T1, T2, Alloc, true >& toCopy) :
559  }
560 
561  // Generalized copy constructor
562  template < typename T1, typename T2, typename Alloc >
563  template < typename OtherAlloc >
565  const BijectionImplementation< T1, T2, OtherAlloc, true >& toCopy) :
570  }
571 
572  // move constructor
573  template < typename T1, typename T2, typename Alloc >
575  BijectionImplementation< T1, T2, Alloc, true >&& toCopy) noexcept :
579  }
580 
581  // destructor
582  template < typename T1, typename T2, typename Alloc >
585  }
586 
587  // returns the iterator at the beginning of the bijection
588  template < typename T1, typename T2, typename Alloc >
589  INLINE typename BijectionImplementation< T1, T2, Alloc, true >::iterator
590  BijectionImplementation< T1, T2, Alloc, true >::begin() const {
591  return BijectionIterator< T1, T2 >{*this};
592  }
593 
594  // returns the iterator at the beginning of the bijection
595  template < typename T1, typename T2, typename Alloc >
597  BijectionImplementation< T1, T2, Alloc, true >::cbegin() const {
598  return BijectionIterator< T1, T2 >{*this};
599  }
600 
601  // returns the iterator to the end of the bijection
602  template < typename T1, typename T2, typename Alloc >
603  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::iterator&
604  BijectionImplementation< T1, T2, Alloc, true >::end() const noexcept {
605  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
607  }
608 
609  // returns the iterator to the end of the bijection
610  template < typename T1, typename T2, typename Alloc >
611  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::const_iterator&
612  BijectionImplementation< T1, T2, Alloc, true >::cend() const noexcept {
613  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
615  }
616 
617  // returns the iterator at the beginning of the bijection
618  template < typename T1, typename T2, typename Alloc >
620  BijectionImplementation< T1, T2, Alloc, true >::beginSafe() const {
621  return BijectionIteratorSafe< T1, T2 >{*this};
622  }
623 
624  // returns the iterator at the beginning of the bijection
625  template < typename T1, typename T2, typename Alloc >
627  BijectionImplementation< T1, T2, Alloc, true >::cbeginSafe() const {
628  return BijectionIteratorSafe< T1, T2 >{*this};
629  }
630 
631  // returns the iterator to the end of the bijection
632  template < typename T1, typename T2, typename Alloc >
633  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::iterator_safe&
634  BijectionImplementation< T1, T2, Alloc, true >::endSafe() const noexcept {
635  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
637  }
638 
639  // returns the iterator to the end of the bijection
640  template < typename T1, typename T2, typename Alloc >
641  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::const_iterator_safe&
642  BijectionImplementation< T1, T2, Alloc, true >::cendSafe() const noexcept {
643  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
645  }
646 
647  // removes all the associations from the bijection
648  template < typename T1, typename T2, typename Alloc >
649  INLINE void BijectionImplementation< T1, T2, Alloc, true >::clear() {
652  // note that _iter_end_ is actually a constant, whatever we add/remove
653  // to/from _firstToSecond_. As a consequence, it need not be updated
654  // after the clear's
655  }
656 
657  // Copy operator
658  template < typename T1, typename T2, typename Alloc >
661  const BijectionImplementation< T1, T2, Alloc, true >& toCopy) {
662  // avoid self assignment
663  if (this != &toCopy) {
664  clear();
666  }
667 
668  // note that _iter_end_ is actually a constant, whatever we add/remove
669  // to/from _firstToSecond_. As a consequence, it need not be updated
670  // after _copy_
671  return *this;
672  }
673 
674  // Generalized copy operator
675  template < typename T1, typename T2, typename Alloc >
676  template < typename OtherAlloc >
679  const BijectionImplementation< T1, T2, OtherAlloc, true >& toCopy) {
680  clear();
682 
683  // note that _iter_end_ is actually a constant, whatever we add/remove
684  // to/from _firstToSecond_. As a consequence, it need not be updated
685  // after _copy_
686  return *this;
687  }
688 
689  // move operator
690  template < typename T1, typename T2, typename Alloc >
693  BijectionImplementation< T1, T2, Alloc, true >&& toCopy) {
694  // avoid self assignment
695  if (this != &toCopy) {
696  clear();
699  }
700 
701  // note that _iter_end_ is actually a constant, whatever we add/remove
702  // to/from _firstToSecond_. As a consequence, it need not be updated
703  // after _copy_
704  return *this;
705  }
706 
707  // returns the value associated to the element passed in argument
708  template < typename T1, typename T2, typename Alloc >
709  INLINE const T1& BijectionImplementation< T1, T2, Alloc, true >::first(T2 second) const {
710  return _secondToFirst_[second];
711  }
712 
713  // returns the value associated to the element passed in argument
714  template < typename T1, typename T2, typename Alloc >
715  INLINE const T2& BijectionImplementation< T1, T2, Alloc, true >::second(T1 first) const {
716  return _firstToSecond_[first];
717  }
718 
719  // Test whether the bijection contains the "first" value
720  template < typename T1, typename T2, typename Alloc >
721  INLINE bool BijectionImplementation< T1, T2, Alloc, true >::existsFirst(T1 first) const {
722  return _firstToSecond_.exists(first);
723  }
724 
725  // Test whether the bijection contains the "second" value
726  template < typename T1, typename T2, typename Alloc >
727  INLINE bool BijectionImplementation< T1, T2, Alloc, true >::existsSecond(T2 second) const {
728  return _secondToFirst_.exists(second);
729  }
730 
731  // inserts a new association in the bijection
732  template < typename T1, typename T2, typename Alloc >
734  // check the uniqueness property
737  "the bijection contains an element with the same couple (" << first << "," << second
738  << ")");
739  }
740 
741  // insert copies of first and second
743 
744  try {
746  } catch (...) {
748  throw;
749  }
750  }
751 
752  // inserts a new association in the bijection
753  template < typename T1, typename T2, typename Alloc >
756  }
757 
758  // emplace a new element in the bijection
759  template < typename T1, typename T2, typename Alloc >
760  template < typename... Args >
761  INLINE void BijectionImplementation< T1, T2, Alloc, true >::emplace(Args&&... args) {
762  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
764  }
765 
766  /* @brief Same method as first, but if the value is not found, a default
767  * value is inserted into the bijection */
768  template < typename T1, typename T2, typename Alloc >
770  T1 val) const {
771  try {
772  return first(second);
773  } catch (NotFound&) {
774  _insert_(val, second);
775  return val;
776  }
777  }
778 
779  /* @brief Same method as second, but if the value is not found, a default
780  * value is inserted into the bijection */
781  template < typename T1, typename T2, typename Alloc >
783  T2 val) const {
784  try {
785  return second(first);
786  } catch (NotFound&) {
787  _insert_(first, val);
788  return val;
789  }
790  }
791 
792  // returns true if the bijection doesn't contain any relation
793  template < typename T1, typename T2, typename Alloc >
794  INLINE bool BijectionImplementation< T1, T2, Alloc, true >::empty() const noexcept {
796  return _firstToSecond_.empty();
797  }
798 
799  // returns the number of associations stored within the bijection
800  template < typename T1, typename T2, typename Alloc >
801  INLINE Size BijectionImplementation< T1, T2, Alloc, true >::size() const noexcept {
803  return _firstToSecond_.size();
804  }
805 
806  // erases an association containing the given first element
807  template < typename T1, typename T2, typename Alloc >
809  try {
812  } catch (NotFound&) {}
813  }
814 
815  // erase an association containing the given second element
816  template < typename T1, typename T2, typename Alloc >
818  try {
821  } catch (NotFound&) {}
822  }
823 
824  // returns the number of hashtables' slots used (@sa hashTable's capacity)
825  template < typename T1, typename T2, typename Alloc >
826  INLINE Size BijectionImplementation< T1, T2, Alloc, true >::capacity() const noexcept {
827  return _firstToSecond_.capacity();
828  }
829 
830  // similar to the hashtable's resize
831  template < typename T1, typename T2, typename Alloc >
835  }
836 
837  // enables the user to change dynamically the resizing policy
838  template < typename T1, typename T2, typename Alloc >
840  const bool new_policy) noexcept {
843  }
844 
845  // returns the current resizing policy
846  template < typename T1, typename T2, typename Alloc >
847  INLINE bool BijectionImplementation< T1, T2, Alloc, true >::resizePolicy() const noexcept {
848  return _firstToSecond_.resizePolicy();
849  }
850 
851  // friendly displays the content of the CliqueGraph
852  template < typename T1, typename T2, typename Alloc >
853  std::string BijectionImplementation< T1, T2, Alloc, true >::toString() const {
855  stream << "{ ";
856  bool first = true;
857 
858  for (iterator iter = begin(); iter != end(); ++iter) {
859  if (!first)
860  stream << ", ";
861  else
862  first = false;
863 
864  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
865  }
866 
867  stream << " }";
868  return stream.str();
869  }
870 
871  // ===========================================================================
872  // === BIJECTION SAFE ITERATORS ===
873  // ===========================================================================
874 
875  /// Default constructor
876  template < typename T1, typename T2 >
879  }
880 
881  /// Constructor
882  template < typename T1, typename T2 >
883  template < typename Alloc, bool Gen >
888  }
889 
890  /// Constructor
891  template < typename T1, typename T2 >
892  template < typename Alloc >
894  const Bijection< T1, T2, Alloc >& bijection) :
897  }
898 
899  /// Copy constructor
900  template < typename T1, typename T2 >
902  const BijectionIteratorSafe< T1, T2 >& toCopy) :
903  _iter_{toCopy._iter_} {
905  }
906 
907  /// move constructor
908  template < typename T1, typename T2 >
910  BijectionIteratorSafe< T1, T2 >&& from) noexcept :
911  _iter_{std::move(from._iter_)} {
913  }
914 
915  /// Destructor
916  template < typename T1, typename T2 >
919  }
920 
921  /// Copy operator
922  template < typename T1, typename T2 >
925  _iter_ = toCopy._iter_;
926  return *this;
927  }
928 
929  /// move operator
930  template < typename T1, typename T2 >
934  return *this;
935  }
936 
937  /// Go to the next association (if exists)
938  template < typename T1, typename T2 >
940  ++_iter_;
941  return *this;
942  }
943 
944  /// moves the iterator by nb elements
945  template < typename T1, typename T2 >
948  _iter_ += nb;
949  return *this;
950  }
951 
952  /// returns a new iterator
953  template < typename T1, typename T2 >
956  return BijectionIteratorSafe< T1, T2 >{*this} += nb;
957  }
958 
959  /// Comparison of iterators
960  template < typename T1, typename T2 >
962  const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
963  return _iter_ != toCompare._iter_;
964  }
965 
966  /// Comparison of iterators
967  template < typename T1, typename T2 >
969  const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
970  return _iter_ == toCompare._iter_;
971  }
972 
973  /// return the first element of the current association
974  template < typename T1, typename T2 >
975  INLINE const T1& BijectionIteratorSafe< T1, T2 >::first() const {
976  return _iter_.key();
977  }
978 
979  /// return the second element of the current association
980  template < typename T1, typename T2 >
981  INLINE const T2& BijectionIteratorSafe< T1, T2 >::second() const {
982  return Getter::op_second(_iter_.val());
983  }
984 
985  /* ===========================================================================
986  */
987  /* === BIJECTION UNSAFE ITERATORS ===
988  */
989  /* ===========================================================================
990  */
991 
992  /// Default constructor
993  template < typename T1, typename T2 >
996  }
997 
998  /// Constructor
999  template < typename T1, typename T2 >
1000  template < typename Alloc, bool Gen >
1005  }
1006 
1007  /// Constructor
1008  template < typename T1, typename T2 >
1009  template < typename Alloc >
1010  INLINE
1014  }
1015 
1016  /// Copy constructor
1017  template < typename T1, typename T2 >
1019  _iter_{toCopy._iter_} {
1021  }
1022 
1023  /// move constructor
1024  template < typename T1, typename T2 >
1026  :
1027  _iter_{std::move(from._iter_)} {
1029  }
1030 
1031  /// Destructor
1032  template < typename T1, typename T2 >
1035  }
1036 
1037  /// Copy operator
1038  template < typename T1, typename T2 >
1041  _iter_ = toCopy._iter_;
1042  return *this;
1043  }
1044 
1045  /// move operator
1046  template < typename T1, typename T2 >
1049  _iter_ = std::move(toCopy._iter_);
1050  return *this;
1051  }
1052 
1053  /// Go to the next association (if exists)
1054  template < typename T1, typename T2 >
1056  ++_iter_;
1057  return *this;
1058  }
1059 
1060  /// moves the iterator by nb elements
1061  template < typename T1, typename T2 >
1063  _iter_ += nb;
1064  return *this;
1065  }
1066 
1067  /// returns a new iterator
1068  template < typename T1, typename T2 >
1070  return BijectionIterator< T1, T2 >{*this} += nb;
1071  }
1072 
1073  /// Comparison of iterators
1074  template < typename T1, typename T2 >
1076  const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1077  return _iter_ != toCompare._iter_;
1078  }
1079 
1080  /// Comparison of iterators
1081  template < typename T1, typename T2 >
1083  const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1084  return _iter_ == toCompare._iter_;
1085  }
1086 
1087  /// return the first element of the current association
1088  template < typename T1, typename T2 >
1089  INLINE const T1& BijectionIterator< T1, T2 >::first() const {
1090  return _iter_.key();
1091  }
1092 
1093  /// return the second element of the current association
1094  template < typename T1, typename T2 >
1095  INLINE const T2& BijectionIterator< T1, T2 >::second() const {
1096  return Getter::op_second(_iter_.val());
1097  }
1098 
1099  // ============================================================================
1100  // BIJECTION
1101  // ============================================================================
1102 
1103  // Default constructor: creates a bijection without any association
1104  template < typename T1, typename T2, typename Alloc >
1107  T2,
1108  Alloc,
1109  std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1110  size,
1111  resize_policy) {
1113  }
1114 
1115  // initializer list constructor
1116  template < typename T1, typename T2, typename Alloc >
1119  T2,
1120  Alloc,
1121  std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(list) {
1123  }
1124 
1125  // Copy constructor
1126  template < typename T1, typename T2, typename Alloc >
1129  T2,
1130  Alloc,
1131  std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1132  toCopy) {
1134  }
1135 
1136  // Generalized copy constructor
1137  template < typename T1, typename T2, typename Alloc >
1138  template < typename OtherAlloc >
1141  T2,
1142  Alloc,
1143  std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1144  toCopy) {
1146  }
1147 
1148  // move constructor
1149  template < typename T1, typename T2, typename Alloc >
1152  T2,
1153  Alloc,
1154  std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1155  std::move(from)) {
1157  }
1158 
1159  // destructor
1160  template < typename T1, typename T2, typename Alloc >
1163  }
1164 
1165  // copy operator
1166  template < typename T1, typename T2, typename Alloc >
1167  INLINE Bijection< T1, T2, Alloc >&
1170  return *this;
1171  }
1172 
1173  // generalized copy operator
1174  template < typename T1, typename T2, typename Alloc >
1175  template < typename OtherAlloc >
1176  INLINE Bijection< T1, T2, Alloc >&
1179  return *this;
1180  }
1181 
1182  // move operator
1183  template < typename T1, typename T2, typename Alloc >
1184  INLINE Bijection< T1, T2, Alloc >&
1187  return *this;
1188  }
1189 
1190  // for friendly displaying the content of bijections
1191  template < typename T1, typename T2, typename Alloc >
1193  stream << b.toString();
1194  return stream;
1195  }
1196 
1197 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643