aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
bijection_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
51
52// To simply IDE parsing
54
55namespace gum {
56
57 // ===========================================================================
58 // === NON SCALAR BIJECTION IMPLEMENTATION ===
59 // ===========================================================================
60
61 // a function that performs a complete copy of another bijection
62 template < typename T1, typename T2, bool Gen >
64 // parse f2s and perform copies
65 for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
66 typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(iter.key(), nullptr));
67 typename HashTable21::value_type* val2;
68
69 try {
70 val2 = &(_secondToFirst_.insert(*(iter.val()), nullptr));
71 } catch (...) {
72 _firstToSecond_.erase(iter.key());
73 throw;
74 }
75
76 val1->second = &(const_cast< T2& >(val2->first));
77 val2->second = &(const_cast< T1& >(val1->first));
78 }
79
80 // note that _iter_end_ is actually a constant, whatever we add/remove
81 // to/from _firstToSecond_. As a consequence, it need not be updated
82 // after _copy_
83 }
84
85 // Default constructor: creates a bijection without association
86 template < typename T1, typename T2, bool Gen >
88 // warning: below, we create the internal hashTables with a key
89 // uniqueness
90 // policy set to false because we will do the uniqueness tests ourselves
91 // (this
92 // will speed-up the process)
93 _firstToSecond_(size, resize_policy, false), _secondToFirst_(size, resize_policy, false) {
94 GUM_CONSTRUCTOR(BijectionImplementation);
95 }
96
97 // initializer list constructor
98 template < typename T1, typename T2, 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
110 // Copy constructor
111 template < typename T1, typename T2, bool Gen >
119
120 // move constructor
121 template < typename T1, typename T2, bool Gen >
124 _firstToSecond_(std::move(from._firstToSecond_)),
125 _secondToFirst_(std::move(from._secondToFirst_)) {
126 GUM_CONS_MOV(BijectionImplementation);
127 }
128
129 // destructor
130 template < typename T1, typename T2, bool Gen >
134
135 // removes all the associations from the bijection
136 template < typename T1, typename T2, bool Gen >
138 _firstToSecond_.clear();
139 _secondToFirst_.clear();
140 // note that _iter_end_ is actually a constant, whatever we add/remove
141 // to/from _firstToSecond_. As a consequence, it need not be updated
142 // after the clear's
143 }
144
145 // Copy operator
146 template < typename T1, typename T2, bool Gen >
149 // avoid self assignment
150 if (this != &toCopy) {
151 clear();
152 _copy_(toCopy._firstToSecond_);
153 }
154
155 // note that _iter_end_ is actually a constant, whatever we add/remove
156 // to/from _firstToSecond_. As a consequence, it need not be updated
157 // after _copy_
158 return *this;
159 }
160
161 // move operator
162 template < typename T1, typename T2, bool Gen >
165 // avoid self assignment
166 if (this != &from) {
167 clear();
168 _firstToSecond_ = std::move(from._firstToSecond_);
169 _secondToFirst_ = std::move(from._secondToFirst_);
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 // returns the iterator at the beginning of the bijection
179 template < typename T1, typename T2, bool Gen >
184
185 // returns the iterator at the beginning of the bijection
186 template < typename T1, typename T2, bool Gen >
191
192 // returns the iterator to the end of the bijection
193 template < typename T1, typename T2, bool Gen >
196 return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(_Bijection_end_));
197 }
198
199 // returns the iterator to the end of the bijection
200 template < typename T1, typename T2, bool Gen >
203 return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(_Bijection_end_));
204 }
205
206 // returns the iterator at the beginning of the bijection
207 template < typename T1, typename T2, bool Gen >
212
213 // returns the iterator at the beginning of the bijection
214 template < typename T1, typename T2, bool Gen >
219
220 // returns the iterator to the end of the bijection
221 template < typename T1, typename T2, bool Gen >
224 return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(_Bijection_end_safe_));
225 }
226
227 // returns the iterator to the end of the bijection
228 template < typename T1, typename T2, bool Gen >
231 return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(_Bijection_end_safe_));
232 }
233
234 // returns the value associated to the element passed in argument
235 template < typename T1, typename T2, bool Gen >
237 return *(_secondToFirst_[second]);
238 }
239
240 // returns the value associated to the element passed in argument
241 template < typename T1, typename T2, bool Gen >
243 return *(_firstToSecond_[first]);
244 }
245
246 template < typename T1, typename T2, bool Gen >
247 template < typename K >
248 requires(std::same_as< T1, std::string > && std::convertible_to< K, std::string_view >
249 && !std::same_as< std::decay_t< K >, std::string >)
251 return *(_firstToSecond_[first]);
252 }
253
254 // Test whether the bijection contains the "first" value
255 template < typename T1, typename T2, bool Gen >
257 return _firstToSecond_.exists(first);
258 }
259
260 template < typename T1, typename T2, bool Gen >
261 template < typename K >
262 requires(std::same_as< T1, std::string > && std::convertible_to< K, std::string_view >
263 && !std::same_as< std::decay_t< K >, std::string >)
265 return _firstToSecond_.exists(first);
266 }
267
268 // Test whether the bijection contains the "second" value
269 template < typename T1, typename T2, bool Gen >
273
274 // returns an optional reference to the first value or empty if not found
275 template < typename T1, typename T2, bool Gen >
278 auto ptr = _secondToFirst_.tryGet(second);
279 if (!ptr) return {};
280 return optional_ref< const T1 >(**ptr);
281 }
282
283 // returns an optional reference to the second value or empty if not found
284 template < typename T1, typename T2, bool Gen >
285 optional_ref< const T2 >
287 auto ptr = _firstToSecond_.tryGet(first);
288 if (!ptr) return {};
289 return optional_ref< const T2 >(**ptr);
290 }
291
292 template < typename T1, typename T2, bool Gen >
293 template < typename K >
294 requires(std::same_as< T1, std::string > && std::convertible_to< K, std::string_view >
295 && !std::same_as< std::decay_t< K >, std::string >)
297 auto ptr = _firstToSecond_.tryGet(first);
298 if (!ptr) return {};
299 return optional_ref< const T2 >(**ptr);
300 }
302 // inserts a new association in the bijection
303 template < typename T1, typename T2, bool Gen >
306 // check the uniqueness property
309 "the bijection contains an element with the same couple (" << first << "," << second
310 << ")");
311 }
312
313 // insert copies of first and second
314 typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(first, nullptr));
315 typename HashTable21::value_type* val2;
316
317 try {
318 val2 = &(_secondToFirst_.insert(second, nullptr));
319 } catch (...) {
320 _firstToSecond_.erase(first);
321 throw;
322 }
323
324 val1->second = &(const_cast< T2& >(val2->first));
325 val2->second = &(const_cast< T1& >(val1->first));
326
327 return val1;
328 }
329
330 // inserts a new association in the bijection
331 template < typename T1, typename T2, bool Gen >
334 // check the uniqueness property
337 "the bijection contains an element with the same couple (" << first << "," << second
338 << ")");
339 }
340
341 // insert copies of first and second
342 typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(std::move(first), nullptr));
343 typename HashTable21::value_type* val2;
344
345 try {
346 val2 = &(_secondToFirst_.insert(std::move(second), nullptr));
347 } catch (...) {
348 _firstToSecond_.erase(val1->first);
349 throw;
350 }
351
352 val1->second = &(const_cast< T2& >(val2->first));
353 val2->second = &(const_cast< T1& >(val1->first));
354
355 return val1;
356 }
357
358 /* @brief Same method as first, but if the value is not found, a default
359 * value is inserted into the bijection */
360 template < typename T1, typename T2, bool Gen >
362 const T1& val) const {
363 if (auto ptr = tryFirst(second)) return *ptr;
364 return _insert_(val, second)->first;
365 }
366
367 /* @brief Same method as second, but if the value is not found, a default
368 * value is inserted into the bijection */
369 template < typename T1, typename T2, bool Gen >
371 const T2& val) const {
372 if (auto ptr = trySecond(first)) return *ptr;
373 return *(_insert_(first, val)->second);
374 }
375
376 // inserts a new association in the bijection
377 template < typename T1, typename T2, bool Gen >
381
382 // inserts a new association in the bijection
383 template < typename T1, typename T2, bool Gen >
385 _insert_(std::move(first), std::move(second));
386 }
388 // emplace a new element in the bijection
389 template < typename T1, typename T2, bool Gen >
390 template < typename... Args >
392 std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
393 _insert_(std::move(new_elt.first), std::move(new_elt.second));
394 }
395
396 // returns true if the bijection doesn't contain any relation
397 template < typename T1, typename T2, bool Gen >
399 GUM_ASSERT(_firstToSecond_.empty() == _secondToFirst_.empty());
400 return _firstToSecond_.empty();
401 }
402
403 // returns the number of associations stored within the bijection
404 template < typename T1, typename T2, bool Gen >
406 GUM_ASSERT(_firstToSecond_.size() == _secondToFirst_.size());
407 return _firstToSecond_.size();
408 }
409
410 // erases an association containing the given first element
411 template < typename T1, typename T2, bool Gen >
413 if (auto ptr = _firstToSecond_.tryGet(first)) {
414 _secondToFirst_.erase(**ptr);
415 _firstToSecond_.erase(first);
416 }
417 }
418
419 // erase an association containing the given second element
420 template < typename T1, typename T2, bool Gen >
422 if (auto ptr = _secondToFirst_.tryGet(second)) {
423 _firstToSecond_.erase(**ptr);
424 _secondToFirst_.erase(second);
425 }
426 }
427
428 // returns the number of hashtables' slots used (@sa hashTable's capacity)
429 template < typename T1, typename T2, bool Gen >
433
434 // similar to the hashtable's resize
435 template < typename T1, typename T2, bool Gen >
437 _firstToSecond_.resize(new_size);
438 _secondToFirst_.resize(new_size);
439 }
440
441 // enables the user to change dynamically the resizing policy
442 template < typename T1, typename T2, bool Gen >
443 void BijectionImplementation< T1, T2, Gen >::setResizePolicy(const bool new_policy) noexcept {
444 _firstToSecond_.setResizePolicy(new_policy);
445 _secondToFirst_.setResizePolicy(new_policy);
446 }
448 // returns the current resizing policy
449 template < typename T1, typename T2, bool Gen >
451 return _firstToSecond_.resizePolicy();
452 }
453
454 // friendly displays the content of the CliqueGraph
455 template < typename T1, typename T2, bool Gen >
457 std::stringstream stream;
458 stream << "{ ";
459 bool first = true;
460
461 for (iterator iter = begin(); iter != end(); ++iter) {
462 if (!first) stream << ", ";
463 else first = false;
464
465 stream << '(' << iter.first() << " <-> " << iter.second() << ')';
466 }
467
468 stream << " }";
469 return stream.str();
470 }
471
472 // ===========================================================================
473 // === SCALAR BIJECTION IMPLEMENTATION ===
474 // ===========================================================================
475
476 // Default constructor: creates a bijection without association
477 template < typename T1, typename T2 >
479 // warning: below, we create the internal hashTables with a key
480 // uniqueness
481 // policy set to false because we will do the uniqueness tests ourselves
482 // (this
483 // will speed-up the process)
484 _firstToSecond_(size, resize_policy, false), _secondToFirst_(size, resize_policy, false) {
485 GUM_CONSTRUCTOR(BijectionImplementation);
486 }
487
488 // initializer list constructor
489 template < typename T1, typename T2 >
491 std::initializer_list< std::pair< T1, T2 > > list) :
492 _firstToSecond_(Size(list.size()) / 2, true, false),
493 _secondToFirst_(Size(list.size()) / 2, true, false) {
494 GUM_CONSTRUCTOR(BijectionImplementation);
495
496 for (const auto& elt: list) {
497 insert(elt.first, elt.second);
498 }
499 }
500
501 // a function that performs a complete copy of another bijection
502 template < typename T1, typename T2 >
504 // parse f2s and perform copies
505 for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
506 _firstToSecond_.insert(iter.key(), iter.val());
507
508 try {
509 _secondToFirst_.insert(iter.val(), iter.key());
510 } catch (...) {
511 _firstToSecond_.erase(iter.key());
512 throw;
513 }
514 }
515
516 // note that _iter_end_ is actually a constant, whatever we add/remove
517 // to/from _firstToSecond_. As a consequence, it need not be updated
518 // after _copy_
519 }
520
521 // Copy constructor
522 template < typename T1, typename T2 >
526 _secondToFirst_(toCopy._secondToFirst_.capacity(), true, false) {
527 GUM_CONS_CPY(BijectionImplementation);
528 _copy_(toCopy._firstToSecond_);
529 }
530
531 // move constructor
532 template < typename T1, typename T2 >
534 BijectionImplementation< T1, T2, true >&& toCopy) noexcept :
535 _firstToSecond_(std::move(toCopy._firstToSecond_)),
536 _secondToFirst_(std::move(toCopy._secondToFirst_)) {
537 GUM_CONS_MOV(BijectionImplementation);
538 }
539
540 // destructor
541 template < typename T1, typename T2 >
543 GUM_DESTRUCTOR(BijectionImplementation);
544 }
546 // returns the iterator at the beginning of the bijection
547 template < typename T1, typename T2 >
550 return BijectionIterator< T1, T2 >{*this};
552
553 // returns the iterator at the beginning of the bijection
554 template < typename T1, typename T2 >
557 return BijectionIterator< T1, T2 >{*this};
558 }
559
560 // returns the iterator to the end of the bijection
561 template < typename T1, typename T2 >
564 return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(_Bijection_end_));
565 }
566
567 // returns the iterator to the end of the bijection
568 template < typename T1, typename T2 >
571 return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(_Bijection_end_));
573
574 // returns the iterator at the beginning of the bijection
575 template < typename T1, typename T2 >
579 }
580
581 // returns the iterator at the beginning of the bijection
582 template < typename T1, typename T2 >
586 }
587
588 // returns the iterator to the end of the bijection
589 template < typename T1, typename T2 >
592 return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(_Bijection_end_safe_));
593 }
594
595 // returns the iterator to the end of the bijection
596 template < typename T1, typename T2 >
599 return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(_Bijection_end_safe_));
600 }
601
602 // removes all the associations from the bijection
603 template < typename T1, typename T2 >
605 _firstToSecond_.clear();
606 _secondToFirst_.clear();
607 // note that _iter_end_ is actually a constant, whatever we add/remove
608 // to/from _firstToSecond_. As a consequence, it need not be updated
609 // after the clear's
610 }
611
612 // Copy operator
613 template < typename T1, typename T2 >
616 // avoid self assignment
617 if (this != &toCopy) {
618 clear();
619 _copy_(toCopy._firstToSecond_);
620 }
621
622 // note that _iter_end_ is actually a constant, whatever we add/remove
623 // to/from _firstToSecond_. As a consequence, it need not be updated
624 // after _copy_
625 return *this;
626 }
627
628 // move operator
629 template < typename T1, typename T2 >
632 // avoid self assignment
633 if (this != &toCopy) {
634 clear();
635 _firstToSecond_ = std::move(toCopy._firstToSecond_);
636 _secondToFirst_ = std::move(toCopy._secondToFirst_);
638
639 // note that _iter_end_ is actually a constant, whatever we add/remove
640 // to/from _firstToSecond_. As a consequence, it need not be updated
641 // after _copy_
642 return *this;
643 }
644
645 // returns the value associated to the element passed in argument
646 template < typename T1, typename T2 >
647 const T1& BijectionImplementation< T1, T2, true >::first(T2 second) const {
648 return _secondToFirst_[second];
649 }
650
651 // returns the value associated to the element passed in argument
652 template < typename T1, typename T2 >
653 const T2& BijectionImplementation< T1, T2, true >::second(T1 first) const {
654 return _firstToSecond_[first];
655 }
656
657 // Test whether the bijection contains the "first" value
658 template < typename T1, typename T2 >
660 return _firstToSecond_.exists(first);
661 }
662
663 // Test whether the bijection contains the "second" value
664 template < typename T1, typename T2 >
666 return _secondToFirst_.exists(second);
667 }
668
669 // returns an optional reference to the first value or empty if not found
670 template < typename T1, typename T2 >
672 return _secondToFirst_.tryGet(second);
673 }
674
675 // returns an optional reference to the second value or empty if not found
676 template < typename T1, typename T2 >
678 return _firstToSecond_.tryGet(first);
679 }
680
681 // inserts a new association in the bijection
682 template < typename T1, typename T2 >
683 void BijectionImplementation< T1, T2, true >::_insert_(T1 first, T2 second) {
684 // check the uniqueness property
685 if (existsFirst(first) || existsSecond(second)) {
686 GUM_ERROR(DuplicateElement,
687 "the bijection contains an element with the same couple (" << first << "," << second
688 << ")");
689 }
690
691 // insert copies of first and second
692 _firstToSecond_.insert(first, second);
693
694 try {
695 _secondToFirst_.insert(second, first);
696 } catch (...) {
697 _firstToSecond_.erase(first);
698 throw;
699 }
700 }
701
702 // inserts a new association in the bijection
703 template < typename T1, typename T2 >
704 void BijectionImplementation< T1, T2, true >::insert(T1 first, T2 second) {
705 _insert_(first, second);
706 }
707
708 // emplace a new element in the bijection
709 template < typename T1, typename T2 >
710 template < typename... Args >
712 std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
713 _insert_(new_elt.first, new_elt.second);
714 }
715
716 /* @brief Same method as first, but if the value is not found, a default
717 * value is inserted into the bijection */
718 template < typename T1, typename T2 >
719 const T1& BijectionImplementation< T1, T2, true >::firstWithDefault(T2 second, T1 val) const {
720 if (auto ptr = tryFirst(second)) return *ptr;
721 _insert_(val, second);
722 return val;
723 }
724
725 /* @brief Same method as second, but if the value is not found, a default
726 * value is inserted into the bijection */
727 template < typename T1, typename T2 >
728 const T2& BijectionImplementation< T1, T2, true >::secondWithDefault(T1 first, T2 val) const {
729 if (auto ptr = trySecond(first)) return *ptr;
730 _insert_(first, val);
731 return val;
732 }
733
734 // returns true if the bijection doesn't contain any relation
735 template < typename T1, typename T2 >
737 GUM_ASSERT(_firstToSecond_.empty() == _secondToFirst_.empty());
738 return _firstToSecond_.empty();
739 }
740
741 // returns the number of associations stored within the bijection
742 template < typename T1, typename T2 >
744 GUM_ASSERT(_firstToSecond_.size() == _secondToFirst_.size());
745 return _firstToSecond_.size();
746 }
747
748 // erases an association containing the given first element
749 template < typename T1, typename T2 >
751 if (auto ptr = _firstToSecond_.tryGet(first)) {
752 _secondToFirst_.erase(*ptr);
753 _firstToSecond_.erase(first);
754 }
755 }
756
757 // erase an association containing the given second element
758 template < typename T1, typename T2 >
760 if (auto ptr = _secondToFirst_.tryGet(second)) {
761 _firstToSecond_.erase(*ptr);
762 _secondToFirst_.erase(second);
763 }
764 }
765
766 // returns the number of hashtables' slots used (@sa hashTable's capacity)
767 template < typename T1, typename T2 >
769 return _firstToSecond_.capacity();
770 }
771
772 // similar to the hashtable's resize
773 template < typename T1, typename T2 >
775 _firstToSecond_.resize(new_size);
776 _secondToFirst_.resize(new_size);
777 }
778
779 // enables the user to change dynamically the resizing policy
780 template < typename T1, typename T2 >
781 void BijectionImplementation< T1, T2, true >::setResizePolicy(const bool new_policy) noexcept {
782 _firstToSecond_.setResizePolicy(new_policy);
783 _secondToFirst_.setResizePolicy(new_policy);
784 }
785
786 // returns the current resizing policy
787 template < typename T1, typename T2 >
789 return _firstToSecond_.resizePolicy();
790 }
791
792 // friendly displays the content of the CliqueGraph
793 template < typename T1, typename T2 >
795 std::stringstream stream;
796 stream << "{ ";
797 bool first = true;
798
799 for (iterator iter = begin(); iter != end(); ++iter) {
800 if (!first) stream << ", ";
801 else first = false;
802
803 stream << '(' << iter.first() << " <-> " << iter.second() << ')';
804 }
805
806 stream << " }";
807 return stream.str();
808 }
809
810 // ===========================================================================
811 // === BIJECTION SAFE ITERATORS ===
812 // ===========================================================================
813
815 template < typename T1, typename T2 >
819
821 template < typename T1, typename T2 >
822 template < bool Gen >
825 _iter_{bijection._firstToSecond_.cbeginSafe()} {
826 GUM_CONSTRUCTOR(BijectionIteratorSafe);
827 }
828
830 template < typename T1, typename T2 >
832 _iter_{bijection._firstToSecond_.cbeginSafe()} {
833 GUM_CONSTRUCTOR(BijectionIteratorSafe);
834 }
835
837 template < typename T1, typename T2 >
842
844 template < typename T1, typename T2 >
846 BijectionIteratorSafe< T1, T2 >&& from) noexcept : _iter_{std::move(from._iter_)} {
847 GUM_CONS_MOV(BijectionIteratorSafe);
848 }
849
851 template < typename T1, typename T2 >
855
857 template < typename T1, typename T2 >
860 = default;
861
863 template < typename T1, typename T2 >
865 BijectionIteratorSafe< T1, T2 >&& toCopy) noexcept {
866 _iter_ = std::move(toCopy._iter_);
867 return *this;
868 }
869
871 template < typename T1, typename T2 >
876
878 template < typename T1, typename T2 >
883
885 template < typename T1, typename T2 >
889
891 template < typename T1, typename T2 >
893 const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
894 return _iter_ != toCompare._iter_;
895 }
896
898 template < typename T1, typename T2 >
900 const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
901 return _iter_ == toCompare._iter_;
902 }
903
905 template < typename T1, typename T2 >
907 return _iter_.key();
908 }
909
911 template < typename T1, typename T2 >
913 return Getter::op_second(_iter_.val());
914 }
915
916 /* ===========================================================================
917 */
918 /* === BIJECTION UNSAFE ITERATORS ===
919 */
920 /* ===========================================================================
921 */
922
924 template < typename T1, typename T2 >
928
930 template < typename T1, typename T2 >
931 template < bool Gen >
934 _iter_{bijection._firstToSecond_.cbegin()} {
935 GUM_CONSTRUCTOR(BijectionIterator);
936 }
937
939 template < typename T1, typename T2 >
941 _iter_{bijection._firstToSecond_.cbegin()} {
942 GUM_CONSTRUCTOR(BijectionIterator);
943 }
944
946 template < typename T1, typename T2 >
951
953 template < typename T1, typename T2 >
955 _iter_{std::move(from._iter_)} {
956 GUM_CONS_MOV(BijectionIterator);
957 }
958
960 template < typename T1, typename T2 >
964
966 template < typename T1, typename T2 >
969
971 template < typename T1, typename T2 >
974 _iter_ = std::move(toCopy._iter_);
975 return *this;
976 }
977
979 template < typename T1, typename T2 >
984
986 template < typename T1, typename T2 >
988 _iter_ += nb;
989 return *this;
990 }
991
993 template < typename T1, typename T2 >
997
999 template < typename T1, typename T2 >
1001 const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1002 return _iter_ != toCompare._iter_;
1003 }
1004
1006 template < typename T1, typename T2 >
1008 const BijectionIterator< T1, T2 >& toCompare) const noexcept {
1009 return _iter_ == toCompare._iter_;
1010 }
1011
1013 template < typename T1, typename T2 >
1015 return _iter_.key();
1016 }
1017
1019 template < typename T1, typename T2 >
1021 return Getter::op_second(_iter_.val());
1022 }
1023
1024 // ============================================================================
1025 // BIJECTION
1026 // ============================================================================
1027
1028 // Default constructor: creates a bijection without any association
1029 template < typename T1, typename T2 >
1031 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1032 size,
1033 resize_policy) {
1034 GUM_CONSTRUCTOR(Bijection);
1035 }
1036
1037 // initializer list constructor
1038 template < typename T1, typename T2 >
1039 Bijection< T1, T2 >::Bijection(std::initializer_list< std::pair< T1, T2 > > list) :
1040 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1041 list) {
1042 GUM_CONSTRUCTOR(Bijection);
1043 }
1044
1045 // Copy constructor
1046 template < typename T1, typename T2 >
1048 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1049 toCopy) {
1050 GUM_CONS_CPY(Bijection);
1051 }
1052
1053 // move constructor
1054 template < typename T1, typename T2 >
1056 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1057 std::move(from)) {
1058 GUM_CONS_MOV(Bijection);
1059 }
1060
1061 // destructor
1062 template < typename T1, typename T2 >
1064 GUM_DESTRUCTOR(Bijection);
1065 }
1066
1067 // copy operator
1068 template < typename T1, typename T2 >
1073
1074 // move operator
1075 template < typename T1, typename T2 >
1080
1081 // for friendly displaying the content of bijections
1082 template < typename T1, typename T2 >
1083 std::ostream& operator<<(std::ostream& stream, const Bijection< T1, T2 >& b) {
1084 stream << b.toString();
1085 return stream;
1086 }
1087
1088 template < bool gen >
1089 template < typename T >
1091 return *x;
1092 }
1093
1094 template < typename T >
1096 return x;
1097 }
1098
1099} /* namespace gum */
Set of pairs of elements with fast search for both elements.
A non scalar implementation of a Bijection.
Definition bijection.h:104
void emplace(Args &&... args)
Emplace a new element in the gum::Bijection.
BijectionIteratorSafe< T1, T2 > iterator_safe
types for STL compliance
Definition bijection.h:122
void setResizePolicy(const bool new_policy) noexcept
Change the gum::Bijection resizing policy.
optional_ref< const T2 > trySecond(const T1 &first) const
Returns an optional reference to the second value associated with the given first value,...
bool resizePolicy() const noexcept
Returns true if the resize policy is automatic.
BijectionIteratorSafe< T1, T2 > const_iterator_safe
types for STL compliance
Definition bijection.h:123
const iterator & end() const noexcept
Returns the unsafe iterator at the end of the gum::Bijection.
HashTable12 _firstToSecond_
The gum::HashTable associating T2 objects to T1 objects.
Definition bijection.h:616
const iterator_safe & endSafe() const noexcept
Returns the safe iterator at the end of the gum::Bijection.
BijectionIterator< T1, T2 > const_iterator
types for STL compliance
Definition bijection.h:121
const_iterator cbegin() const
Returns the constant unsafe iterator at the beginning of the gum::Bjection.
HashTable21 _secondToFirst_
The gum::HashTable associating T1 objects to T2 objects.
Definition bijection.h:619
std::string toString() const
Returns a friendly representatin of the gum::Bijection.
BijectionIterator< T1, T2 > iterator
types for STL compliance
Definition bijection.h:120
BijectionImplementation< T1, T2, Gen > & operator=(const BijectionImplementation< T1, T2, Gen > &toCopy)
Copy operator.
const_iterator_safe cbeginSafe() const
Returns the constant safe iterator at the begining of the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
optional_ref< const T1 > tryFirst(const T2 &second) const
Returns a pointer to the first value associated with the given second value, or nullptr if not found.
bool empty() const noexcept
Returns true if the gum::Bijection doesn't contain any association.
friend class BijectionIterator< T1, T2 >
a friend to speed-up accesses
Definition bijection.h:604
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
void resize(Size new_size)
Manually resize the gum::Bijection.
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.
HashTable12::value_type * _insert_(const T1 &first, const T2 &second)
Inserts a new association into the gum::Bijection.
Size capacity() const noexcept
Returns the number of hashtables slots used.
bool existsSecond(const T2 &second) const
Returns true if second is the second element in a pair in the gum::Bijection.
const T1 & first(const T2 &second) const
Returns the first value of a pair given its second value.
void _copy_(const HashTable< T1, T2 * > &source)
A function that performs a complete copy of another gum::Bijection.
void clear()
Removes all the associations from the gum::Bijection.
Size size() const noexcept
Returns the number of associations stored within the gum::Bijection.
void eraseFirst(const T1 &first)
Erases an association containing the given first element.
iterator_safe beginSafe() const
Returns the safe iterator at the beginning of the gum::Bijection.
void eraseSecond(const T2 &second)
Erases an association containing the given second element.
const const_iterator & cend() const noexcept
Returns the constant iterator at the end of the gum::Bijection.
friend class BijectionIteratorSafe< T1, T2 >
a friend to speed-up accesses
Definition bijection.h:603
iterator begin() const
Returns the unsafe iterator at the beginning of the gum::Bijection.
friend class BijectionImplementation
a friend to speed-up accesses
Definition bijection.h:607
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
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.
const const_iterator_safe & cendSafe() const noexcept
Returns the constant safe iterator at the end of the gum::Bijection.
Safe iterators for bijectionIterator.
Definition bijection.h:1240
~BijectionIteratorSafe() noexcept
Class destructor.
HashIter _iter_
The hashTable iterator that actually does all the job.
Definition bijection.h:1423
BijectionIteratorSafe< T1, T2 > & operator=(const BijectionIteratorSafe< T1, T2 > &toCopy)
Copy operator.
BijectionIteratorSafe< T1, T2 > operator+(Size nb) noexcept
Returns a new iterator.
bool operator==(const BijectionIteratorSafe< T1, T2 > &toCompare) const noexcept
Equality operator.
BijectionIteratorSafe< T1, T2 > & operator+=(Size nb) noexcept
Moves the iterator by nb elements.
const T2 & second() const
Returns the second element of the current association.
bool operator!=(const BijectionIteratorSafe< T1, T2 > &toCompare) const noexcept
Inequality operator.
BijectionIteratorSafe() noexcept
Default constructor.
BijectionIteratorSafe(const BijectionImplementation< T1, T2, Gen > &bijection)
Begin constructor.
const T1 & first() const
Returns the first element of the current association.
BijectionIteratorSafe< T1, T2 > & operator++() noexcept
Go to the next association, if it exists.
friend class BijectionImplementation
Definition bijection.h:1242
Unsafe iterators for bijection.
Definition bijection.h:1440
BijectionIterator< T1, T2 > & operator+=(Size nb) noexcept
Moves the iterator by nb elements.
BijectionIterator(const BijectionImplementation< T1, T2, Gen > &bijection)
Begin constructor.
const T1 & first() const
Returns the first element of the current association.
BijectionIterator< T1, T2 > & operator++() noexcept
Go to the next association, if it exists.
bool operator==(const BijectionIterator< T1, T2 > &toCompare) const noexcept
Equality operator.
BijectionIterator< T1, T2 > & operator=(const BijectionIterator< T1, T2 > &toCopy)
Copy operator.
~BijectionIterator() noexcept
Class destructor.
bool operator!=(const BijectionIterator< T1, T2 > &toCompare) const noexcept
Inequality operator.
BijectionIterator< T1, T2 > operator+(Size nb) noexcept
Return a new iterator.
HashIter _iter_
The hashTable iterator that actually does all the job.
Definition bijection.h:1614
const T2 & second() const
Returns the second element of the current association.
friend class BijectionImplementation
Definition bijection.h:1442
BijectionIterator() noexcept
Default constructor.
Set of pairs of elements with fast search for both elements.
Definition bijection.h:1640
Bijection< T1, T2 > & operator=(const Bijection< T1, T2 > &toCopy)
Copy operator.
Bijection(Size size=HashTableConst::default_size, bool resize_policy=HashTableConst::default_resize_policy)
Default constructor: creates a gum::Bijection without any association.
~Bijection()
Class destructor.
Exception : a similar element already exists.
The class for generic Hash Tables.
Definition hashTable.h:640
const const_iterator & cend() const noexcept
Returns the unsafe const_iterator pointing to the end of the hashtable.
std::pair< const T1, T2 * > value_type
Definition hashTable.h:646
const_iterator cbegin() const
Returns an unsafe const_iterator pointing to the beginning of the hashtable.
A lightweight wrapper around a pointer providing an optional-like API for references (not supported b...
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
std::ostream & operator<<(std::ostream &stream, const AVLTree< Val, Cmp > &tree)
display the content of a tree
STL namespace.
static const T & op_second(const T *x)
Returns a refeence over a pointer.