aGrUM 2.3.2
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-2025 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-2025 *
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#pragma once
41
42
50
51// To simply IDE parsing
53
54namespace gum {
55
56 // ===========================================================================
57 // === NON SCALAR BIJECTION IMPLEMENTATION ===
58 // ===========================================================================
59
60 // a function that performs a complete copy of another bijection
61 template < typename T1, typename T2, bool Gen >
63 // parse f2s and perform copies
64 for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
65 typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(iter.key(), nullptr));
66 typename HashTable21::value_type* val2;
67
68 try {
69 val2 = &(_secondToFirst_.insert(*(iter.val()), nullptr));
70 } catch (...) {
71 _firstToSecond_.erase(iter.key());
72 throw;
73 }
74
75 val1->second = &(const_cast< T2& >(val2->first));
76 val2->second = &(const_cast< T1& >(val1->first));
77 }
78
79 // note that _iter_end_ is actually a constant, whatever we add/remove
80 // to/from _firstToSecond_. As a consequence, it need not be updated
81 // after _copy_
82 }
83
84 // Default constructor: creates a bijection without association
85 template < typename T1, typename T2, bool Gen >
87 bool resize_policy) :
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 >
236 INLINE const T1& BijectionImplementation< T1, T2, Gen >::first(const T2& second) const {
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 >
242 INLINE const T2& BijectionImplementation< T1, T2, Gen >::second(const T1& first) const {
243 return *(_firstToSecond_[first]);
244 }
245
246 // Test whether the bijection contains the "first" value
247 template < typename T1, typename T2, bool Gen >
249 return _firstToSecond_.exists(first);
250 }
251
252 // Test whether the bijection contains the "second" value
253 template < typename T1, typename T2, bool Gen >
255 return _secondToFirst_.exists(second);
257
258 // inserts a new association in the bijection
259 template < typename T1, typename T2, bool Gen >
262 // check the uniqueness property
265 "the bijection contains an element with the same couple (" << first << "," << second
266 << ")");
267 }
268
269 // insert copies of first and second
270 typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(first, nullptr));
271 typename HashTable21::value_type* val2;
272
273 try {
274 val2 = &(_secondToFirst_.insert(second, nullptr));
275 } catch (...) {
276 _firstToSecond_.erase(first);
277 throw;
279
280 val1->second = &(const_cast< T2& >(val2->first));
281 val2->second = &(const_cast< T1& >(val1->first));
282
283 return val1;
284 }
285
286 // inserts a new association in the bijection
287 template < typename T1, typename T2, bool Gen >
290 // check the uniqueness property
293 "the bijection contains an element with the same couple (" << first << "," << second
294 << ")");
295 }
296
297 // insert copies of first and second
298 typename HashTable12::value_type* val1 = &(_firstToSecond_.insert(std::move(first), nullptr));
299 typename HashTable21::value_type* val2;
300
301 try {
302 val2 = &(_secondToFirst_.insert(std::move(second), nullptr));
303 } catch (...) {
304 _firstToSecond_.erase(val1->first);
305 throw;
306 }
307
308 val1->second = &(const_cast< T2& >(val2->first));
309 val2->second = &(const_cast< T1& >(val1->first));
310
311 return val1;
312 }
313
314 /* @brief Same method as first, but if the value is not found, a default
315 * value is inserted into the bijection */
316 template < typename T1, typename T2, bool Gen >
318 const T1& val) const {
319 try {
320 return first(second);
321 } catch (NotFound const&) { return _insert_(val, second)->first; }
322 }
323
324 /* @brief Same method as second, but if the value is not found, a default
325 * value is inserted into the bijection */
326 template < typename T1, typename T2, bool Gen >
328 const T2& val) const {
329 try {
330 return second(first);
331 } catch (NotFound const&) { return *(_insert_(first, val)->second); }
332 }
333
334 // inserts a new association in the bijection
335 template < typename T1, typename T2, bool Gen >
338 }
339
340 // inserts a new association in the bijection
341 template < typename T1, typename T2, bool Gen >
343 _insert_(std::move(first), std::move(second));
344 }
345
346 // emplace a new element in the bijection
347 template < typename T1, typename T2, bool Gen >
348 template < typename... Args >
350 std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
351 _insert_(std::move(new_elt.first), std::move(new_elt.second));
352 }
353
354 // returns true if the bijection doesn't contain any relation
355 template < typename T1, typename T2, bool Gen >
357 GUM_ASSERT(_firstToSecond_.empty() == _secondToFirst_.empty());
358 return _firstToSecond_.empty();
359 }
360
361 // returns the number of associations stored within the bijection
362 template < typename T1, typename T2, bool Gen >
364 GUM_ASSERT(_firstToSecond_.size() == _secondToFirst_.size());
365 return _firstToSecond_.size();
366 }
367
368 // erases an association containing the given first element
369 template < typename T1, typename T2, bool Gen >
371 try {
373 _firstToSecond_.erase(first);
374 } catch (NotFound const&) {}
375 }
376
377 // erase an association containing the given second element
378 template < typename T1, typename T2, bool Gen >
380 try {
382 _secondToFirst_.erase(second);
383 } catch (NotFound const&) {}
384 }
385
386 // returns the number of hashtables' slots used (@sa hashTable's capacity)
387 template < typename T1, typename T2, bool Gen >
389 return _firstToSecond_.capacity();
390 }
391
392 // similar to the hashtable's resize
393 template < typename T1, typename T2, bool Gen >
395 _firstToSecond_.resize(new_size);
396 _secondToFirst_.resize(new_size);
397 }
399 // enables the user to change dynamically the resizing policy
400 template < typename T1, typename T2, bool Gen >
401 INLINE void
403 _firstToSecond_.setResizePolicy(new_policy);
404 _secondToFirst_.setResizePolicy(new_policy);
405 }
407 // returns the current resizing policy
408 template < typename T1, typename T2, bool Gen >
410 return _firstToSecond_.resizePolicy();
411 }
412
413 // friendly displays the content of the CliqueGraph
414 template < typename T1, typename T2, bool Gen >
416 std::stringstream stream;
417 stream << "{ ";
418 bool first = true;
419
420 for (iterator iter = begin(); iter != end(); ++iter) {
421 if (!first) stream << ", ";
422 else first = false;
423
424 stream << '(' << iter.first() << " <-> " << iter.second() << ')';
425 }
427 stream << " }";
428 return stream.str();
429 }
430
431 // ===========================================================================
432 // === SCALAR BIJECTION IMPLEMENTATION ===
433 // ===========================================================================
434
435 // Default constructor: creates a bijection without association
436 template < typename T1, typename T2 >
438 bool resize_policy) :
439 // warning: below, we create the internal hashTables with a key
440 // uniqueness
441 // policy set to false because we will do the uniqueness tests ourselves
442 // (this
443 // will speed-up the process)
444 _firstToSecond_(size, resize_policy, false), _secondToFirst_(size, resize_policy, false) {
445 GUM_CONSTRUCTOR(BijectionImplementation);
447
448 // initializer list constructor
449 template < typename T1, typename T2 >
451 std::initializer_list< std::pair< T1, T2 > > list) :
452 _firstToSecond_(Size(list.size()) / 2, true, false),
453 _secondToFirst_(Size(list.size()) / 2, true, false) {
454 GUM_CONSTRUCTOR(BijectionImplementation);
455
456 for (const auto& elt: list) {
457 insert(elt.first, elt.second);
458 }
459 }
460
461 // a function that performs a complete copy of another bijection
462 template < typename T1, typename T2 >
464 // parse f2s and perform copies
465 for (auto iter = f2s.cbegin(); iter != f2s.cend(); ++iter) {
466 _firstToSecond_.insert(iter.key(), iter.val());
467
468 try {
469 _secondToFirst_.insert(iter.val(), iter.key());
470 } catch (...) {
471 _firstToSecond_.erase(iter.key());
472 throw;
473 }
474 }
476 // note that _iter_end_ is actually a constant, whatever we add/remove
477 // to/from _firstToSecond_. As a consequence, it need not be updated
478 // after _copy_
479 }
480
481 // Copy constructor
482 template < typename T1, typename T2 >
490
491 // move constructor
492 template < typename T1, typename T2 >
494 BijectionImplementation< T1, T2, true >&& toCopy) noexcept :
495 _firstToSecond_(std::move(toCopy._firstToSecond_)),
496 _secondToFirst_(std::move(toCopy._secondToFirst_)) {
497 GUM_CONS_MOV(BijectionImplementation);
498 }
499
500 // destructor
501 template < typename T1, typename T2 >
503 GUM_DESTRUCTOR(BijectionImplementation);
504 }
505
506 // returns the iterator at the beginning of the bijection
507 template < typename T1, typename T2 >
510 return BijectionIterator< T1, T2 >{*this};
512
513 // returns the iterator at the beginning of the bijection
514 template < typename T1, typename T2 >
518 }
519
520 // returns the iterator to the end of the bijection
521 template < typename T1, typename T2 >
524 return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(_Bijection_end_));
525 }
526
527 // returns the iterator to the end of the bijection
528 template < typename T1, typename T2 >
531 return *(reinterpret_cast< const BijectionIterator< T1, T2 >* >(_Bijection_end_));
532 }
533
534 // returns the iterator at the beginning of the bijection
535 template < typename T1, typename T2 >
539 }
540
541 // returns the iterator at the beginning of the bijection
542 template < typename T1, typename T2 >
545 return BijectionIteratorSafe< T1, T2 >{*this};
546 }
548 // returns the iterator to the end of the bijection
549 template < typename T1, typename T2 >
552 return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(_Bijection_end_safe_));
553 }
554
555 // returns the iterator to the end of the bijection
556 template < typename T1, typename T2 >
559 return *(reinterpret_cast< const BijectionIteratorSafe< T1, T2 >* >(_Bijection_end_safe_));
560 }
561
562 // removes all the associations from the bijection
563 template < typename T1, typename T2 >
565 _firstToSecond_.clear();
566 _secondToFirst_.clear();
567 // note that _iter_end_ is actually a constant, whatever we add/remove
568 // to/from _firstToSecond_. As a consequence, it need not be updated
569 // after the clear's
570 }
571
572 // Copy operator
573 template < typename T1, typename T2 >
574 INLINE BijectionImplementation< T1, T2, true >&
576 const BijectionImplementation< T1, T2, true >& toCopy) {
577 // avoid self assignment
578 if (this != &toCopy) {
579 clear();
580 _copy_(toCopy._firstToSecond_);
581 }
582
583 // note that _iter_end_ is actually a constant, whatever we add/remove
584 // to/from _firstToSecond_. As a consequence, it need not be updated
585 // after _copy_
586 return *this;
587 }
588
589 // move operator
590 template < typename T1, typename T2 >
594 // avoid self assignment
595 if (this != &toCopy) {
596 clear();
597 _firstToSecond_ = std::move(toCopy._firstToSecond_);
598 _secondToFirst_ = std::move(toCopy._secondToFirst_);
599 }
600
601 // note that _iter_end_ is actually a constant, whatever we add/remove
602 // to/from _firstToSecond_. As a consequence, it need not be updated
603 // after _copy_
604 return *this;
605 }
606
607 // returns the value associated to the element passed in argument
608 template < typename T1, typename T2 >
609 INLINE const T1& BijectionImplementation< T1, T2, true >::first(T2 second) const {
610 return _secondToFirst_[second];
611 }
612
613 // returns the value associated to the element passed in argument
614 template < typename T1, typename T2 >
615 INLINE const T2& BijectionImplementation< T1, T2, true >::second(T1 first) const {
616 return _firstToSecond_[first];
617 }
618
619 // Test whether the bijection contains the "first" value
620 template < typename T1, typename T2 >
621 INLINE bool BijectionImplementation< T1, T2, true >::existsFirst(T1 first) const {
622 return _firstToSecond_.exists(first);
623 }
624
625 // Test whether the bijection contains the "second" value
626 template < typename T1, typename T2 >
627 INLINE bool BijectionImplementation< T1, T2, true >::existsSecond(T2 second) const {
628 return _secondToFirst_.exists(second);
629 }
630
631 // inserts a new association in the bijection
632 template < typename T1, typename T2 >
633 INLINE void BijectionImplementation< T1, T2, true >::_insert_(T1 first, T2 second) {
634 // check the uniqueness property
635 if (existsFirst(first) || existsSecond(second)) {
636 GUM_ERROR(DuplicateElement,
637 "the bijection contains an element with the same couple (" << first << "," << second
638 << ")");
639 }
640
641 // insert copies of first and second
642 _firstToSecond_.insert(first, second);
643
644 try {
645 _secondToFirst_.insert(second, first);
646 } catch (...) {
647 _firstToSecond_.erase(first);
648 throw;
649 }
650 }
651
652 // inserts a new association in the bijection
653 template < typename T1, typename T2 >
654 INLINE void BijectionImplementation< T1, T2, true >::insert(T1 first, T2 second) {
655 _insert_(first, second);
656 }
657
658 // emplace a new element in the bijection
659 template < typename T1, typename T2 >
660 template < typename... Args >
661 INLINE void BijectionImplementation< T1, T2, true >::emplace(Args&&... args) {
662 std::pair< T1, T2 > new_elt(std::forward< Args >(args)...);
663 _insert_(new_elt.first, new_elt.second);
664 }
665
666 /* @brief Same method as first, but if the value is not found, a default
667 * value is inserted into the bijection */
668 template < typename T1, typename T2 >
670 T1 val) const {
671 try {
672 return first(second);
673 } catch (NotFound const&) {
674 _insert_(val, second);
675 return val;
676 }
677 }
678
679 /* @brief Same method as second, but if the value is not found, a default
680 * value is inserted into the bijection */
681 template < typename T1, typename T2 >
683 T2 val) const {
684 try {
685 return second(first);
686 } catch (NotFound const&) {
687 _insert_(first, val);
688 return val;
689 }
690 }
691
692 // returns true if the bijection doesn't contain any relation
693 template < typename T1, typename T2 >
694 INLINE bool BijectionImplementation< T1, T2, true >::empty() const noexcept {
695 GUM_ASSERT(_firstToSecond_.empty() == _secondToFirst_.empty());
696 return _firstToSecond_.empty();
697 }
698
699 // returns the number of associations stored within the bijection
700 template < typename T1, typename T2 >
702 GUM_ASSERT(_firstToSecond_.size() == _secondToFirst_.size());
703 return _firstToSecond_.size();
704 }
705
706 // erases an association containing the given first element
707 template < typename T1, typename T2 >
709 try {
710 _secondToFirst_.erase(_firstToSecond_[first]);
711 _firstToSecond_.erase(first);
712 } catch (NotFound const&) {}
713 }
714
715 // erase an association containing the given second element
716 template < typename T1, typename T2 >
718 try {
719 _firstToSecond_.erase(_secondToFirst_[second]);
720 _secondToFirst_.erase(second);
721 } catch (NotFound const&) {}
722 }
723
724 // returns the number of hashtables' slots used (@sa hashTable's capacity)
725 template < typename T1, typename T2 >
727 return _firstToSecond_.capacity();
728 }
729
730 // similar to the hashtable's resize
731 template < typename T1, typename T2 >
733 _firstToSecond_.resize(new_size);
734 _secondToFirst_.resize(new_size);
735 }
736
737 // enables the user to change dynamically the resizing policy
738 template < typename T1, typename T2 >
739 INLINE void
740 BijectionImplementation< T1, T2, true >::setResizePolicy(const bool new_policy) noexcept {
741 _firstToSecond_.setResizePolicy(new_policy);
742 _secondToFirst_.setResizePolicy(new_policy);
743 }
744
745 // returns the current resizing policy
746 template < typename T1, typename T2 >
747 INLINE bool BijectionImplementation< T1, T2, true >::resizePolicy() const noexcept {
748 return _firstToSecond_.resizePolicy();
749 }
750
751 // friendly displays the content of the CliqueGraph
752 template < typename T1, typename T2 >
754 std::stringstream stream;
755 stream << "{ ";
756 bool first = true;
757
758 for (iterator iter = begin(); iter != end(); ++iter) {
759 if (!first) stream << ", ";
760 else first = false;
761
762 stream << '(' << iter.first() << " <-> " << iter.second() << ')';
763 }
764
765 stream << " }";
766 return stream.str();
767 }
768
769 // ===========================================================================
770 // === BIJECTION SAFE ITERATORS ===
771 // ===========================================================================
772
774 template < typename T1, typename T2 >
778
780 template < typename T1, typename T2 >
781 template < bool Gen >
784 _iter_{bijection._firstToSecond_.cbeginSafe()} {
785 GUM_CONSTRUCTOR(BijectionIteratorSafe);
786 }
787
789 template < typename T1, typename T2 >
790 INLINE
792 _iter_{bijection._firstToSecond_.cbeginSafe()} {
793 GUM_CONSTRUCTOR(BijectionIteratorSafe);
794 }
795
797 template < typename T1, typename T2 >
802
804 template < typename T1, typename T2 >
806 BijectionIteratorSafe< T1, T2 >&& from) noexcept : _iter_{std::move(from._iter_)} {
807 GUM_CONS_MOV(BijectionIteratorSafe);
808 }
809
811 template < typename T1, typename T2 >
815
817 template < typename T1, typename T2 >
820 _iter_ = toCopy._iter_;
821 return *this;
822 }
823
825 template < typename T1, typename T2 >
827 BijectionIteratorSafe< T1, T2 >&& toCopy) noexcept {
828 _iter_ = std::move(toCopy._iter_);
829 return *this;
830 }
831
833 template < typename T1, typename T2 >
835 ++_iter_;
836 return *this;
837 }
838
840 template < typename T1, typename T2 >
843 _iter_ += nb;
844 return *this;
845 }
846
848 template < typename T1, typename T2 >
853
855 template < typename T1, typename T2 >
857 const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
858 return _iter_ != toCompare._iter_;
859 }
860
862 template < typename T1, typename T2 >
864 const BijectionIteratorSafe< T1, T2 >& toCompare) const noexcept {
865 return _iter_ == toCompare._iter_;
866 }
867
869 template < typename T1, typename T2 >
870 INLINE const T1& BijectionIteratorSafe< T1, T2 >::first() const {
871 return _iter_.key();
872 }
873
875 template < typename T1, typename T2 >
877 return Getter::op_second(_iter_.val());
878 }
879
880 /* ===========================================================================
881 */
882 /* === BIJECTION UNSAFE ITERATORS ===
883 */
884 /* ===========================================================================
885 */
886
888 template < typename T1, typename T2 >
890 GUM_CONSTRUCTOR(BijectionIterator);
891 }
892
894 template < typename T1, typename T2 >
895 template < bool Gen >
898 _iter_{bijection._firstToSecond_.cbegin()} {
899 GUM_CONSTRUCTOR(BijectionIterator);
900 }
901
903 template < typename T1, typename T2 >
905 _iter_{bijection._firstToSecond_.cbegin()} {
906 GUM_CONSTRUCTOR(BijectionIterator);
907 }
908
910 template < typename T1, typename T2 >
915
917 template < typename T1, typename T2 >
919 : _iter_{std::move(from._iter_)} {
920 GUM_CONS_MOV(BijectionIterator);
921 }
922
924 template < typename T1, typename T2 >
926 GUM_DESTRUCTOR(BijectionIterator);
927 }
928
930 template < typename T1, typename T2 >
933 _iter_ = toCopy._iter_;
934 return *this;
935 }
936
938 template < typename T1, typename T2 >
941 _iter_ = std::move(toCopy._iter_);
942 return *this;
943 }
944
946 template < typename T1, typename T2 >
948 ++_iter_;
949 return *this;
950 }
951
953 template < typename T1, typename T2 >
955 _iter_ += nb;
956 return *this;
957 }
958
960 template < typename T1, typename T2 >
964
966 template < typename T1, typename T2 >
968 const BijectionIterator< T1, T2 >& toCompare) const noexcept {
969 return _iter_ != toCompare._iter_;
970 }
971
973 template < typename T1, typename T2 >
975 const BijectionIterator< T1, T2 >& toCompare) const noexcept {
976 return _iter_ == toCompare._iter_;
977 }
978
980 template < typename T1, typename T2 >
981 INLINE const T1& BijectionIterator< T1, T2 >::first() const {
982 return _iter_.key();
983 }
984
986 template < typename T1, typename T2 >
987 INLINE const T2& BijectionIterator< T1, T2 >::second() const {
988 return Getter::op_second(_iter_.val());
989 }
990
991 // ============================================================================
992 // BIJECTION
993 // ============================================================================
994
995 // Default constructor: creates a bijection without any association
996 template < typename T1, typename T2 >
997 INLINE Bijection< T1, T2 >::Bijection(Size size, bool resize_policy) :
998 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
999 size,
1000 resize_policy) {
1001 GUM_CONSTRUCTOR(Bijection);
1002 }
1003
1004 // initializer list constructor
1005 template < typename T1, typename T2 >
1006 INLINE Bijection< T1, T2 >::Bijection(std::initializer_list< std::pair< T1, T2 > > list) :
1007 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1008 list) {
1009 GUM_CONSTRUCTOR(Bijection);
1010 }
1011
1012 // Copy constructor
1013 template < typename T1, typename T2 >
1015 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1016 toCopy) {
1017 GUM_CONS_CPY(Bijection);
1018 }
1019
1020 // move constructor
1021 template < typename T1, typename T2 >
1023 BijectionImplementation< T1, T2, std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >(
1024 std::move(from)) {
1025 GUM_CONS_MOV(Bijection);
1026 }
1027
1028 // destructor
1029 template < typename T1, typename T2 >
1031 GUM_DESTRUCTOR(Bijection);
1032 }
1033
1034 // copy operator
1035 template < typename T1, typename T2 >
1038 return *this;
1039 }
1040
1041 // move operator
1042 template < typename T1, typename T2 >
1044 Implementation::operator=(std::move(bij));
1045 return *this;
1046 }
1047
1048 // for friendly displaying the content of bijections
1049 template < typename T1, typename T2 >
1050 std::ostream& operator<<(std::ostream& stream, const Bijection< T1, T2 >& b) {
1051 stream << b.toString();
1052 return stream;
1053 }
1054
1055} /* 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.
const iterator & end() const noexcept
Returns the unsafe iterator at the end of 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.
BijectionIteratorSafe< T1, T2 > iterator_safe
types for STL compliance
Definition bijection.h:122
void eraseSecond(const T2 &second)
Erases an association containing the given second element.
const iterator_safe & endSafe() const noexcept
Returns the safe iterator at the end of the gum::Bijection.
BijectionIteratorSafe< T1, T2 > const_iterator_safe
types for STL compliance
Definition bijection.h:123
HashTable12 _firstToSecond_
The gum::HashTable associating T2 objects to T1 objects.
Definition bijection.h:582
HashTable12::value_type * _insert_(const T1 &first, const T2 &second)
Inserts a new association into the gum::Bijection.
void _copy_(const HashTable< T1, T2 * > &source)
A function that performs a complete copy of another gum::Bijection.
void eraseFirst(const T1 &first)
Erases an association containing the given first element.
BijectionIterator< T1, T2 > const_iterator
types for STL compliance
Definition bijection.h:121
const const_iterator_safe & cendSafe() const noexcept
Returns the constant safe iterator at the end of the gum::Bijection.
iterator begin() const
Returns the unsafe iterator at the beginning of the gum::Bijection.
bool existsFirst(const T1 &first) const
Returns true if first is the first element in a pair in the gum::Bijection.
Size capacity() const noexcept
Returns the number of hashtables slots used.
HashTable21 _secondToFirst_
The gum::HashTable associating T1 objects to T2 objects.
Definition bijection.h:585
std::string toString() const
Returns a friendly representatin of the gum::Bijection.
BijectionIterator< T1, T2 > iterator
types for STL compliance
Definition bijection.h:120
const_iterator_safe cbeginSafe() const
Returns the constant safe iterator at the begining of the gum::Bijection.
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
bool empty() const noexcept
Returns true if the gum::Bijection doesn't contain any association.
const const_iterator & cend() const noexcept
Returns the constant iterator at the end of the gum::Bijection.
void setResizePolicy(const bool new_policy) noexcept
Change the gum::Bijection resizing policy.
friend class BijectionIterator< T1, T2 >
a friend to speed-up accesses
Definition bijection.h:570
void clear()
Removes all the associations from the gum::Bijection.
const_iterator cbegin() const
Returns the constant unsafe iterator at the beginning of the gum::Bjection.
Size size() const noexcept
Returns the number of associations stored within 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.
const T1 & first(const T2 &second) const
Returns the first value of a pair given its second value.
void resize(Size new_size)
Manually resize the gum::Bijection.
BijectionImplementation< T1, T2, Gen > & operator=(const BijectionImplementation< T1, T2, Gen > &toCopy)
Copy operator.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
bool existsSecond(const T2 &second) const
Returns true if second is the second element in a pair in the gum::Bijection.
friend class BijectionIteratorSafe< T1, T2 >
a friend to speed-up accesses
Definition bijection.h:569
iterator_safe beginSafe() const
Returns the safe iterator at the beginning of the gum::Bijection.
friend class BijectionImplementation
a friend to speed-up accesses
Definition bijection.h:573
bool resizePolicy() const noexcept
Returns true if the resize policy is automatic.
Safe iterators for bijectionIterator.
Definition bijection.h:1194
BijectionIteratorSafe< T1, T2 > & operator=(const BijectionIteratorSafe< T1, T2 > &toCopy)
Copy operator.
BijectionIteratorSafe< T1, T2 > & operator++() noexcept
Go to the next association, if it exists.
const T2 & second() const
Returns the second element of the current association.
BijectionIteratorSafe< T1, T2 > & operator+=(Size nb) noexcept
Moves the iterator by nb elements.
BijectionIteratorSafe(const BijectionImplementation< T1, T2, Gen > &bijection)
Begin constructor.
INLINE BijectionIteratorSafe(const BijectionImplementation< NodeId, double, Gen > &bijection)
BijectionIteratorSafe< T1, T2 > operator+(Size nb) noexcept
Returns a new iterator.
const T1 & first() const
Returns the first element of the current association.
bool operator==(const BijectionIteratorSafe< T1, T2 > &toCompare) const noexcept
Equality operator.
BijectionIteratorSafe() noexcept
Default constructor.
~BijectionIteratorSafe() noexcept
Class destructor.
bool operator!=(const BijectionIteratorSafe< T1, T2 > &toCompare) const noexcept
Inequality operator.
Unsafe iterators for bijection.
Definition bijection.h:1394
BijectionIterator< T1, T2 > & operator+=(Size nb) noexcept
Moves the iterator by nb elements.
const T1 & first() const
Returns the first element of the current association.
bool operator==(const BijectionIterator< T1, T2 > &toCompare) const noexcept
Equality operator.
BijectionIterator() noexcept
Default constructor.
BijectionIterator(const BijectionImplementation< T1, T2, Gen > &bijection)
Begin constructor.
BijectionIterator< T1, T2 > operator+(Size nb) noexcept
Return a new iterator.
const T2 & second() const
Returns the second element of the current association.
bool operator!=(const BijectionIterator< T1, T2 > &toCompare) const noexcept
Inequality operator.
BijectionIterator< T1, T2 > & operator=(const BijectionIterator< T1, T2 > &toCopy)
Copy operator.
HashIter _iter_
The hashTable iterator that actually does all the job.
Definition bijection.h:1568
~BijectionIterator() noexcept
Class destructor.
BijectionIterator< T1, T2 > & operator++() noexcept
Go to the next association, if it exists.
friend class BijectionImplementation
Definition bijection.h:1396
Set of pairs of elements with fast search for both elements.
Definition bijection.h:1594
~Bijection()
Class destructor.
Bijection(Size size=HashTableConst::default_size, bool resize_policy=HashTableConst::default_resize_policy)
Default constructor: creates a gum::Bijection without any association.
Bijection< T1, T2 > & operator=(const Bijection< T1, T2 > &toCopy)
Copy operator.
Exception : a similar element already exists.
The class for generic Hash Tables.
Definition hashTable.h:637
std::pair< const T1, T2 * > value_type
Definition hashTable.h:643
const_iterator cbegin() const
Returns an unsafe const_iterator pointing to the beginning of the hashtable.
const const_iterator & cend() const noexcept
Returns the unsafe const_iterator pointing to the end of the hashtable.
Exception : the element we looked for cannot be found.
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
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
Definition AVLTree.h:913
STL namespace.
static INLINE const T & op_second(const T *x)
Returns a refeence over a pointer.
Definition bijection.h:1153