aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
bijection_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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 >
49  const BijectionIterator< T1, T2 >&
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 >
59  const HashTable< T1, T2*, OtherAlloc >& f2s) {
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 (...) {
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,
86  bool resize_policy) :
87  // warning: below, we create the internal hashTables with a key
88  // uniqueness
89  // policy set to false because we will do the uniqueness tests ourselves
90  // (this
91  // will speed-up the process)
95 
96  // make sure the end() iterator is constructed properly
97  end4Statics();
99  }
100 
101  // initializer list constructor
102  template < typename T1, typename T2, typename Alloc, bool Gen >
104  std::initializer_list< std::pair< T1, T2 > > list) :
105  firstToSecond__(Size(list.size()) / 2, true, false),
106  secondToFirst__(Size(list.size()) / 2, true, false) {
108 
109  for (const auto& elt: list) {
111  }
112 
113  // make sure the end() iterator is constructed properly
114  end4Statics();
115  endSafe4Statics();
116  }
117 
118  // Copy constructor
119  template < typename T1, typename T2, typename Alloc, bool Gen >
121  const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy) :
126  }
127 
128  // Generalized copy constructor
129  template < typename T1, typename T2, typename Alloc, bool Gen >
130  template < typename OtherAlloc >
137  }
138 
139  // move constructor
140  template < typename T1, typename T2, typename Alloc, bool Gen >
142  BijectionImplementation< T1, T2, Alloc, Gen >&& from) noexcept :
146  }
147 
148  // destructor
149  template < typename T1, typename T2, typename Alloc, bool Gen >
150  INLINE
153  }
154 
155  // removes all the associations from the bijection
156  template < typename T1, typename T2, typename Alloc, bool Gen >
160  // note that iter_end__ is actually a constant, whatever we add/remove
161  // to/from firstToSecond__. As a consequence, it need not be updated
162  // after the clear's
163  }
164 
165  // Copy operator
166  template < typename T1, typename T2, typename Alloc, bool Gen >
169  const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy) {
170  // avoid self assignment
171  if (this != &toCopy) {
172  clear();
174  }
175 
176  // note that iter_end__ is actually a constant, whatever we add/remove
177  // to/from firstToSecond__. As a consequence, it need not be updated
178  // after copy__
179  return *this;
180  }
181 
182  // Generalized copy operator
183  template < typename T1, typename T2, typename Alloc, bool Gen >
184  template < typename OtherAlloc >
188  clear();
190 
191  // note that iter_end__ is actually a constant, whatever we add/remove
192  // to/from firstToSecond__. As a consequence, it need not be updated
193  // after copy__
194  return *this;
195  }
196 
197  // move operator
198  template < typename T1, typename T2, typename Alloc, bool Gen >
202  // avoid self assignment
203  if (this != &from) {
204  clear();
207  }
208 
209  // note that iter_end__ is actually a constant, whatever we add/remove
210  // to/from firstToSecond__. As a consequence, it need not be updated
211  // after copy__
212  return *this;
213  }
214 
215  // returns the iterator at the beginning of the bijection
216  template < typename T1, typename T2, typename Alloc, bool Gen >
219  return BijectionIterator< T1, T2 >{*this};
220  }
221 
222  // returns the iterator at the beginning of the bijection
223  template < typename T1, typename T2, typename Alloc, bool Gen >
226  return BijectionIterator< T1, T2 >{*this};
227  }
228 
229  // returns the iterator to the end of the bijection
230  template < typename T1, typename T2, typename Alloc, bool Gen >
231  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::iterator&
232  BijectionImplementation< T1, T2, Alloc, Gen >::end() const noexcept {
233  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
235  }
236 
237  // returns the iterator to the end of the bijection
238  template < typename T1, typename T2, typename Alloc, bool Gen >
239  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::
241  BijectionImplementation< T1, T2, Alloc, Gen >::cend() const noexcept {
242  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
244  }
245 
246  // returns the iterator at the beginning of the bijection
247  template < typename T1, typename T2, typename Alloc, bool Gen >
250  return BijectionIteratorSafe< T1, T2 >{*this};
251  }
252 
253  // returns the iterator at the beginning of the bijection
254  template < typename T1, typename T2, typename Alloc, bool Gen >
255  INLINE
258  return BijectionIteratorSafe< T1, T2 >{*this};
259  }
260 
261  // returns the iterator to the end of the bijection
262  template < typename T1, typename T2, typename Alloc, bool Gen >
263  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::
265  BijectionImplementation< T1, T2, Alloc, Gen >::endSafe() const noexcept {
266  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
268  }
269 
270  // returns the iterator to the end of the bijection
271  template < typename T1, typename T2, typename Alloc, bool Gen >
272  INLINE const typename BijectionImplementation< T1, T2, Alloc, Gen >::
274  BijectionImplementation< T1, T2, Alloc, Gen >::cendSafe() const noexcept {
275  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
277  }
278 
279  // returns the value associated to the element passed in argument
280  template < typename T1, typename T2, typename Alloc, bool Gen >
281  INLINE const T1&
283  return *(secondToFirst__[second]);
284  }
285 
286  // returns the value associated to the element passed in argument
287  template < typename T1, typename T2, typename Alloc, bool Gen >
288  INLINE const T2&
290  return *(firstToSecond__[first]);
291  }
292 
293  // Test whether the bijection contains the "first" value
294  template < typename T1, typename T2, typename Alloc, bool Gen >
296  const T1& first) const {
297  return firstToSecond__.exists(first);
298  }
299 
300  // Test whether the bijection contains the "second" value
301  template < typename T1, typename T2, typename Alloc, bool Gen >
303  const T2& second) const {
304  return secondToFirst__.exists(second);
305  }
306 
307  // inserts a new association in the bijection
308  template < typename T1, typename T2, typename Alloc, bool Gen >
310  value_type*
312  const T2& second) {
313  // check the uniqueness property
316  "the bijection contains an element with the same couple ("
317  << first << "," << second << ")");
318  }
319 
320  // insert copies of first and second
321  typename HashTable12::value_type* val1
322  = &(firstToSecond__.insert(first, nullptr));
323  typename HashTable21::value_type* val2;
324 
325  try {
326  val2 = &(secondToFirst__.insert(second, nullptr));
327  } catch (...) {
329  throw;
330  }
331 
332  val1->second = &(const_cast< T2& >(val2->first));
333  val2->second = &(const_cast< T1& >(val1->first));
334 
335  return val1;
336  }
337 
338  // inserts a new association in the bijection
339  template < typename T1, typename T2, typename Alloc, bool Gen >
341  value_type*
343  T2&& second) {
344  // check the uniqueness property
347  "the bijection contains an element with the same couple ("
348  << first << "," << second << ")");
349  }
350 
351  // insert copies of first and second
352  typename HashTable12::value_type* val1
353  = &(firstToSecond__.insert(std::move(first), nullptr));
354  typename HashTable21::value_type* val2;
355 
356  try {
357  val2 = &(secondToFirst__.insert(std::move(second), nullptr));
358  } catch (...) {
360  throw;
361  }
362 
363  val1->second = &(const_cast< T2& >(val2->first));
364  val2->second = &(const_cast< T1& >(val1->first));
365 
366  return val1;
367  }
368 
369  /* @brief Same method as first, but if the value is not found, a default
370  * value is inserted into the bijection */
371  template < typename T1, typename T2, typename Alloc, bool Gen >
373  const T2& second,
374  const T1& val) const {
375  try {
376  return first(second);
377  } catch (NotFound&) { return insert__(val, second)->first; }
378  }
379 
380  /* @brief Same method as second, but if the value is not found, a default
381  * value is inserted into the bijection */
382  template < typename T1, typename T2, typename Alloc, bool Gen >
383  INLINE const T2&
385  const T1& first,
386  const T2& val) const {
387  try {
388  return second(first);
389  } catch (NotFound&) { return *(insert__(first, val)->second); }
390  }
391 
392  // inserts a new association in the bijection
393  template < typename T1, typename T2, typename Alloc, bool Gen >
394  INLINE void
396  const T2& second) {
398  }
399 
400  // inserts a new association in the bijection
401  template < typename T1, typename T2, typename Alloc, bool Gen >
403  T2&& second) {
405  }
406 
407  // emplace a new element in the bijection
408  template < typename T1, typename T2, typename Alloc, bool Gen >
409  template < typename... Args >
410  INLINE void
412  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
414  }
415 
416  // returns true if the bijection doesn't contain any relation
417  template < typename T1, typename T2, typename Alloc, bool Gen >
418  INLINE bool
419  BijectionImplementation< T1, T2, Alloc, Gen >::empty() const noexcept {
421  return firstToSecond__.empty();
422  }
423 
424  // returns the number of associations stored within the bijection
425  template < typename T1, typename T2, typename Alloc, bool Gen >
426  INLINE Size
427  BijectionImplementation< T1, T2, Alloc, Gen >::size() const noexcept {
429  return firstToSecond__.size();
430  }
431 
432  // erases an association containing the given first element
433  template < typename T1, typename T2, typename Alloc, bool Gen >
434  INLINE void
436  try {
439  } catch (NotFound&) {}
440  }
441 
442  // erase an association containing the given second element
443  template < typename T1, typename T2, typename Alloc, bool Gen >
444  INLINE void
446  try {
449  } catch (NotFound&) {}
450  }
451 
452  // returns the number of hashtables' slots used (@sa hashTable's capacity)
453  template < typename T1, typename T2, typename Alloc, bool Gen >
454  INLINE Size
455  BijectionImplementation< T1, T2, Alloc, Gen >::capacity() const noexcept {
456  return firstToSecond__.capacity();
457  }
458 
459  // similar to the hashtable's resize
460  template < typename T1, typename T2, typename Alloc, bool Gen >
461  INLINE void
465  }
466 
467  // enables the user to change dynamically the resizing policy
468  template < typename T1, typename T2, typename Alloc, bool Gen >
470  const bool new_policy) noexcept {
473  }
474 
475  // returns the current resizing policy
476  template < typename T1, typename T2, typename Alloc, bool Gen >
477  INLINE bool
478  BijectionImplementation< T1, T2, Alloc, Gen >::resizePolicy() const noexcept {
479  return firstToSecond__.resizePolicy();
480  }
481 
482  // friendly displays the content of the CliqueGraph
483  template < typename T1, typename T2, typename Alloc, bool Gen >
486  stream << "{ ";
487  bool first = true;
488 
489  for (iterator iter = begin(); iter != end(); ++iter) {
490  if (!first)
491  stream << ", ";
492  else
493  first = false;
494 
495  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
496  }
497 
498  stream << " }";
499  return stream.str();
500  }
501 
502  // ===========================================================================
503  // === SCALAR BIJECTION IMPLEMENTATION ===
504  // ===========================================================================
505 
506  // returns the end iterator for other classes' statics
507  template < typename T1, typename T2, typename Alloc >
508  const BijectionIteratorSafe< T1, T2 >&
510  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
512  }
513 
514  // returns the end iterator for other classes' statics
515  template < typename T1, typename T2, typename Alloc >
516  const BijectionIterator< T1, T2 >&
518  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
520  }
521 
522  // Default constructor: creates a bijection without association
523  template < typename T1, typename T2, typename Alloc >
525  Size size,
526  bool resize_policy) :
527  // warning: below, we create the internal hashTables with a key
528  // uniqueness
529  // policy set to false because we will do the uniqueness tests ourselves
530  // (this
531  // will speed-up the process)
535 
536  // make sure the end() iterator is constructed properly
537  end4Statics();
538  endSafe4Statics();
539  }
540 
541  // initializer list constructor
542  template < typename T1, typename T2, typename Alloc >
544  std::initializer_list< std::pair< T1, T2 > > list) :
545  firstToSecond__(Size(list.size()) / 2, true, false),
546  secondToFirst__(Size(list.size()) / 2, true, false) {
548 
549  for (const auto& elt: list) {
551  }
552 
553  // make sure the end() iterator is constructed properly
554  end4Statics();
555  endSafe4Statics();
556  }
557 
558  // a function that performs a complete copy of another bijection
559  template < typename T1, typename T2, typename Alloc >
560  template < typename OtherAlloc >
562  const HashTable< T1, T2, OtherAlloc >& f2s) {
563  // parse f2s and perform copies
564  for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
566 
567  try {
569  } catch (...) {
571  throw;
572  }
573  }
574 
575  // note that iter_end__ is actually a constant, whatever we add/remove
576  // to/from firstToSecond__. As a consequence, it need not be updated
577  // after copy__
578  }
579 
580  // Copy constructor
581  template < typename T1, typename T2, typename Alloc >
583  const BijectionImplementation< T1, T2, Alloc, true >& toCopy) :
588  }
589 
590  // Generalized copy constructor
591  template < typename T1, typename T2, typename Alloc >
592  template < typename OtherAlloc >
594  const BijectionImplementation< T1, T2, OtherAlloc, true >& toCopy) :
599  }
600 
601  // move constructor
602  template < typename T1, typename T2, typename Alloc >
604  BijectionImplementation< T1, T2, Alloc, true >&& toCopy) noexcept :
608  }
609 
610  // destructor
611  template < typename T1, typename T2, typename Alloc >
612  INLINE
615  }
616 
617  // returns the iterator at the beginning of the bijection
618  template < typename T1, typename T2, typename Alloc >
619  INLINE typename BijectionImplementation< T1, T2, Alloc, true >::iterator
620  BijectionImplementation< T1, T2, Alloc, true >::begin() const {
621  return BijectionIterator< 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 >::cbegin() const {
628  return BijectionIterator< 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&
634  BijectionImplementation< T1, T2, Alloc, true >::end() const noexcept {
635  return *(reinterpret_cast< const BijectionIterator< 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 >::
643  BijectionImplementation< T1, T2, Alloc, true >::cend() const noexcept {
644  return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(
646  }
647 
648  // returns the iterator at the beginning of the bijection
649  template < typename T1, typename T2, typename Alloc >
651  BijectionImplementation< T1, T2, Alloc, true >::beginSafe() const {
652  return BijectionIteratorSafe< T1, T2 >{*this};
653  }
654 
655  // returns the iterator at the beginning of the bijection
656  template < typename T1, typename T2, typename Alloc >
657  INLINE
659  BijectionImplementation< T1, T2, Alloc, true >::cbeginSafe() const {
660  return BijectionIteratorSafe< T1, T2 >{*this};
661  }
662 
663  // returns the iterator to the end of the bijection
664  template < typename T1, typename T2, typename Alloc >
665  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::
667  BijectionImplementation< T1, T2, Alloc, true >::endSafe() const noexcept {
668  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
670  }
671 
672  // returns the iterator to the end of the bijection
673  template < typename T1, typename T2, typename Alloc >
674  INLINE const typename BijectionImplementation< T1, T2, Alloc, true >::
676  BijectionImplementation< T1, T2, Alloc, true >::cendSafe() const noexcept {
677  return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(
679  }
680 
681  // removes all the associations from the bijection
682  template < typename T1, typename T2, typename Alloc >
683  INLINE void BijectionImplementation< T1, T2, Alloc, true >::clear() {
686  // note that iter_end__ is actually a constant, whatever we add/remove
687  // to/from firstToSecond__. As a consequence, it need not be updated
688  // after the clear's
689  }
690 
691  // Copy operator
692  template < typename T1, typename T2, typename Alloc >
695  const BijectionImplementation< T1, T2, Alloc, true >& toCopy) {
696  // avoid self assignment
697  if (this != &toCopy) {
698  clear();
700  }
701 
702  // note that iter_end__ is actually a constant, whatever we add/remove
703  // to/from firstToSecond__. As a consequence, it need not be updated
704  // after copy__
705  return *this;
706  }
707 
708  // Generalized copy operator
709  template < typename T1, typename T2, typename Alloc >
710  template < typename OtherAlloc >
713  const BijectionImplementation< T1, T2, OtherAlloc, true >& toCopy) {
714  clear();
716 
717  // note that iter_end__ is actually a constant, whatever we add/remove
718  // to/from firstToSecond__. As a consequence, it need not be updated
719  // after copy__
720  return *this;
721  }
722 
723  // move operator
724  template < typename T1, typename T2, typename Alloc >
727  BijectionImplementation< T1, T2, Alloc, true >&& toCopy) {
728  // avoid self assignment
729  if (this != &toCopy) {
730  clear();
733  }
734 
735  // note that iter_end__ is actually a constant, whatever we add/remove
736  // to/from firstToSecond__. As a consequence, it need not be updated
737  // after copy__
738  return *this;
739  }
740 
741  // returns the value associated to the element passed in argument
742  template < typename T1, typename T2, typename Alloc >
743  INLINE const T1&
744  BijectionImplementation< T1, T2, Alloc, true >::first(T2 second) const {
745  return secondToFirst__[second];
746  }
747 
748  // returns the value associated to the element passed in argument
749  template < typename T1, typename T2, typename Alloc >
750  INLINE const T2&
751  BijectionImplementation< T1, T2, Alloc, true >::second(T1 first) const {
752  return firstToSecond__[first];
753  }
754 
755  // Test whether the bijection contains the "first" value
756  template < typename T1, typename T2, typename Alloc >
757  INLINE bool
758  BijectionImplementation< T1, T2, Alloc, true >::existsFirst(T1 first) const {
759  return firstToSecond__.exists(first);
760  }
761 
762  // Test whether the bijection contains the "second" value
763  template < typename T1, typename T2, typename Alloc >
765  T2 second) const {
766  return secondToFirst__.exists(second);
767  }
768 
769  // inserts a new association in the bijection
770  template < typename T1, typename T2, typename Alloc >
772  T2 second) {
773  // check the uniqueness property
776  "the bijection contains an element with the same couple ("
777  << first << "," << second << ")");
778  }
779 
780  // insert copies of first and second
782 
783  try {
785  } catch (...) {
787  throw;
788  }
789  }
790 
791  // inserts a new association in the bijection
792  template < typename T1, typename T2, typename Alloc >
794  T2 second) {
796  }
797 
798  // emplace a new element in the bijection
799  template < typename T1, typename T2, typename Alloc >
800  template < typename... Args >
801  INLINE void
802  BijectionImplementation< T1, T2, Alloc, true >::emplace(Args&&... args) {
803  std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
805  }
806 
807  /* @brief Same method as first, but if the value is not found, a default
808  * value is inserted into the bijection */
809  template < typename T1, typename T2, typename Alloc >
810  INLINE const T1&
812  T2 second,
813  T1 val) const {
814  try {
815  return first(second);
816  } catch (NotFound&) {
817  insert__(val, second);
818  return val;
819  }
820  }
821 
822  /* @brief Same method as second, but if the value is not found, a default
823  * value is inserted into the bijection */
824  template < typename T1, typename T2, typename Alloc >
825  INLINE const T2&
827  T1 first,
828  T2 val) const {
829  try {
830  return second(first);
831  } catch (NotFound&) {
832  insert__(first, val);
833  return val;
834  }
835  }
836 
837  // returns true if the bijection doesn't contain any relation
838  template < typename T1, typename T2, typename Alloc >
839  INLINE bool
840  BijectionImplementation< T1, T2, Alloc, true >::empty() const noexcept {
842  return firstToSecond__.empty();
843  }
844 
845  // returns the number of associations stored within the bijection
846  template < typename T1, typename T2, typename Alloc >
847  INLINE Size
848  BijectionImplementation< T1, T2, Alloc, true >::size() const noexcept {
850  return firstToSecond__.size();
851  }
852 
853  // erases an association containing the given first element
854  template < typename T1, typename T2, typename Alloc >
855  INLINE void
857  try {
860  } catch (NotFound&) {}
861  }
862 
863  // erase an association containing the given second element
864  template < typename T1, typename T2, typename Alloc >
865  INLINE void
867  try {
870  } catch (NotFound&) {}
871  }
872 
873  // returns the number of hashtables' slots used (@sa hashTable's capacity)
874  template < typename T1, typename T2, typename Alloc >
875  INLINE Size
876  BijectionImplementation< T1, T2, Alloc, true >::capacity() const noexcept {
877  return firstToSecond__.capacity();
878  }
879 
880  // similar to the hashtable's resize
881  template < typename T1, typename T2, typename Alloc >
882  INLINE void
886  }
887 
888  // enables the user to change dynamically the resizing policy
889  template < typename T1, typename T2, typename Alloc >
891  const bool new_policy) noexcept {
894  }
895 
896  // returns the current resizing policy
897  template < typename T1, typename T2, typename Alloc >
899  const noexcept {
900  return firstToSecond__.resizePolicy();
901  }
902 
903  // friendly displays the content of the CliqueGraph
904  template < typename T1, typename T2, typename Alloc >
905  std::string BijectionImplementation< T1, T2, Alloc, true >::toString() const {
907  stream << "{ ";
908  bool first = true;
909 
910  for (iterator iter = begin(); iter != end(); ++iter) {
911  if (!first)
912  stream << ", ";
913  else
914  first = false;
915 
916  stream << '(' << iter.first() << " <-> " << iter.second() << ')';
917  }
918 
919  stream << " }";
920  return stream.str();
921  }
922 
923  // ===========================================================================
924  // === BIJECTION SAFE ITERATORS ===
925  // ===========================================================================
926 
927  /// Default constructor
928  template < typename T1, typename T2 >
931  }
932 
933  /// Constructor
934  template < typename T1, typename T2 >
935  template < typename Alloc, bool Gen >
940  }
941 
942  /// Constructor
943  template < typename T1, typename T2 >
944  template < typename Alloc >
946  const Bijection< T1, T2, Alloc >& bijection) :
949  }
950 
951  /// Copy constructor
952  template < typename T1, typename T2 >
954  const BijectionIteratorSafe< T1, T2 >& toCopy) :
955  iter__{toCopy.iter__} {
957  }
958 
959  /// move constructor
960  template < typename T1, typename T2 >
962  BijectionIteratorSafe< T1, T2 >&& from) noexcept :
963  iter__{std::move(from.iter__)} {
965  }
966 
967  /// Destructor
968  template < typename T1, typename T2 >
971  }
972 
973  /// Copy operator
974  template < typename T1, typename T2 >
977  const BijectionIteratorSafe< T1, T2 >& toCopy) {
978  iter__ = toCopy.iter__;
979  return *this;
980  }
981 
982  /// move operator
983  template < typename T1, typename T2 >
986  BijectionIteratorSafe< T1, T2 >&& toCopy) noexcept {
988  return *this;
989  }
990 
991  /// Go to the next association (if exists)
992  template < typename T1, typename T2 >
994  BijectionIteratorSafe< T1, T2 >::operator++() noexcept {
995  ++iter__;
996  return *this;
997  }
998 
999  /// moves the iterator by nb elements
1000  template < typename T1, typename T2 >
1003  iter__ += nb;
1004  return *this;
1005  }
1006 
1007  /// returns a new iterator
1008  template < typename T1, typename T2 >
1011  return BijectionIteratorSafe< T1, T2 >{*this} += nb;
1012  }
1013 
1014  /// Comparison of iterators
1015  template < typename T1, typename T2 >
1017  const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1018  return iter__ != toCompare.iter__;
1019  }
1020 
1021  /// Comparison of iterators
1022  template < typename T1, typename T2 >
1024  const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
1025  return iter__ == toCompare.iter__;
1026  }
1027 
1028  /// return the first element of the current association
1029  template < typename T1, typename T2 >
1030  INLINE const T1& BijectionIteratorSafe< T1, T2 >::first() const {
1031  return iter__.key();
1032  }
1033 
1034  /// return the second element of the current association
1035  template < typename T1, typename T2 >
1036  INLINE const T2& BijectionIteratorSafe< T1, T2 >::second() const {
1037  return Getter::op_second(iter__.val());
1038  }
1039 
1040  /* ===========================================================================
1041  */
1042  /* === BIJECTION UNSAFE ITERATORS ===
1043  */
1044  /* ===========================================================================
1045  */
1046 
1047  /// Default constructor
1048  template < typename T1, typename T2 >
1051  }
1052 
1053  /// Constructor
1054  template < typename T1, typename T2 >
1055  template < typename Alloc, bool Gen >
1060  }
1061 
1062  /// Constructor
1063  template < typename T1, typename T2 >
1064  template < typename Alloc >
1066  const Bijection< T1, T2, Alloc >& bijection) :
1069  }
1070 
1071  /// Copy constructor
1072  template < typename T1, typename T2 >
1074  const BijectionIterator< T1, T2 >& toCopy) :
1075  iter__{toCopy.iter__} {
1077  }
1078 
1079  /// move constructor
1080  template < typename T1, typename T2 >
1082  BijectionIterator< T1, T2 >&& from) noexcept :
1083  iter__{std::move(from.iter__)} {
1085  }
1086 
1087  /// Destructor
1088  template < typename T1, typename T2 >
1091  }
1092 
1093  /// Copy operator
1094  template < typename T1, typename T2 >
1096  const BijectionIterator< T1, T2 >& toCopy) {
1097  iter__ = toCopy.iter__;
1098  return *this;
1099  }
1100 
1101  /// move operator
1102  template < typename T1, typename T2 >
1104  BijectionIterator< T1, T2 >&& toCopy) noexcept {
1105  iter__ = std::move(toCopy.iter__);
1106  return *this;
1107  }
1108 
1109  /// Go to the next association (if exists)
1110  template < typename T1, typename T2 >
1112  BijectionIterator< T1, T2 >::operator++() noexcept {
1113  ++iter__;
1114  return *this;
1115  }
1116 
1117  /// moves the iterator by nb elements
1118  template < typename T1, typename T2 >
1120  BijectionIterator< T1, T2 >::operator+=(Size nb) noexcept {
1121  iter__ += nb;
1122  return *this;
1123  }
1124 
1125  /// returns a new iterator
1126  template < typename T1, typename T2 >
1129  return BijectionIterator< T1, T2 >{*this} += nb;
1130  }
1131 
1132  /// Comparison of iterators
1133  template < typename T1, typename T2 >
1135  const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1136  return iter__ != toCompare.iter__;
1137  }
1138 
1139  /// Comparison of iterators
1140  template < typename T1, typename T2 >
1142  const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1143  return iter__ == toCompare.iter__;
1144  }
1145 
1146  /// return the first element of the current association
1147  template < typename T1, typename T2 >
1148  INLINE const T1& BijectionIterator< T1, T2 >::first() const {
1149  return iter__.key();
1150  }
1151 
1152  /// return the second element of the current association
1153  template < typename T1, typename T2 >
1154  INLINE const T2& BijectionIterator< T1, T2 >::second() const {
1155  return Getter::op_second(iter__.val());
1156  }
1157 
1158  // ============================================================================
1159  // BIJECTION
1160  // ============================================================================
1161 
1162  // Default constructor: creates a bijection without any association
1163  template < typename T1, typename T2, typename Alloc >
1166  T2,
1167  Alloc,
1168  std::is_scalar< T1 >::value
1169  && std::is_scalar< T2 >::value >(size,
1170  resize_policy) {
1172  }
1173 
1174  // initializer list constructor
1175  template < typename T1, typename T2, typename Alloc >
1177  std::initializer_list< std::pair< T1, T2 > > list) :
1179  T2,
1180  Alloc,
1181  std::is_scalar< T1 >::value
1182  && std::is_scalar< T2 >::value >(list) {
1184  }
1185 
1186  // Copy constructor
1187  template < typename T1, typename T2, typename Alloc >
1189  const Bijection< T1, T2, Alloc >& toCopy) :
1191  T2,
1192  Alloc,
1193  std::is_scalar< T1 >::value
1194  && std::is_scalar< T2 >::value >(toCopy) {
1196  }
1197 
1198  // Generalized copy constructor
1199  template < typename T1, typename T2, typename Alloc >
1200  template < typename OtherAlloc >
1202  const Bijection< T1, T2, OtherAlloc >& toCopy) :
1204  T2,
1205  Alloc,
1206  std::is_scalar< T1 >::value
1207  && std::is_scalar< T2 >::value >(toCopy) {
1209  }
1210 
1211  // move constructor
1212  template < typename T1, typename T2, typename Alloc >
1214  Bijection< T1, T2, Alloc >&& from) noexcept :
1216  T2,
1217  Alloc,
1218  std::is_scalar< T1 >::value
1219  && std::is_scalar< T2 >::value >(
1220  std::move(from)) {
1222  }
1223 
1224  // destructor
1225  template < typename T1, typename T2, typename Alloc >
1228  }
1229 
1230  // copy operator
1231  template < typename T1, typename T2, typename Alloc >
1233  const Bijection< T1, T2, Alloc >& toCopy) {
1235  return *this;
1236  }
1237 
1238  // generalized copy operator
1239  template < typename T1, typename T2, typename Alloc >
1240  template < typename OtherAlloc >
1242  const Bijection< T1, T2, OtherAlloc >& toCopy) {
1244  return *this;
1245  }
1246 
1247  // move operator
1248  template < typename T1, typename T2, typename Alloc >
1249  INLINE Bijection< T1, T2, Alloc >&
1252  return *this;
1253  }
1254 
1255  // for friendly displaying the content of bijections
1256  template < typename T1, typename T2, typename Alloc >
1258  const Bijection< T1, T2, Alloc >& b) {
1259  stream << b.toString();
1260  return stream;
1261  }
1262 
1263 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669