aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
sequence_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 ease IDE parser
53
54namespace gum {
55
56 // returns the size of the sequence
57 template < typename Key, bool Gen >
59 return _h_.size();
60 }
61
62 // return true if empty
63 template < typename Key, bool Gen >
64 INLINE bool SequenceImplementation< Key, Gen >::empty() const noexcept {
65 return _h_.empty();
66 }
67
68 // returns the size of the sequence
69 template < typename Key >
70 INLINE Size SequenceImplementation< Key, true >::size() const noexcept {
71 return _h_.size();
72 }
73
74 // return true if empty
75 template < typename Key >
76 INLINE bool SequenceImplementation< Key, true >::empty() const noexcept {
77 return _h_.empty();
78 }
79
80 // ===========================================================================
81 // class SequenceIteratorSafe
82 // ===========================================================================
83
84 // default constructor
85 template < typename Key >
86 template < bool Gen >
89 Idx pos) noexcept :
91 &seq)} {
92 GUM_CONSTRUCTOR(SequenceIteratorSafe);
93
94 if (pos > _seq_->size()) _iterator_ = _seq_->size(); // make the iterator point to end
95 else _iterator_ = pos;
96 }
97
98 // default constructor
99 template < typename Key >
101 Idx pos) noexcept :
103 &seq)} {
104 GUM_CONSTRUCTOR(SequenceIteratorSafe);
105
106 if (pos > _seq_->size()) _iterator_ = _seq_->size(); // make the iterator point to end
107 else _iterator_ = pos;
108 }
109
110 // copy constructor
111 template < typename Key >
113 const SequenceIteratorSafe< Key >& source) noexcept :
114 _iterator_{source._iterator_}, _seq_{source._seq_} {
115 GUM_CONS_CPY(SequenceIteratorSafe);
116 }
117
118 // move constructor
119 template < typename Key >
121 SequenceIteratorSafe< Key >&& source) noexcept :
122 _iterator_{source._iterator_}, _seq_{source._seq_} {
123 GUM_CONS_MOV(SequenceIteratorSafe);
124 }
125
126 // destructor
127 template < typename Key >
129 GUM_DESTRUCTOR(SequenceIteratorSafe);
130 }
131
132 // copy operator
133 template < typename Key >
134 INLINE SequenceIteratorSafe< Key >&
135 SequenceIteratorSafe< Key >::operator=(const SequenceIteratorSafe< Key >& source) noexcept {
136 _iterator_ = source._iterator_;
137 _seq_ = source._seq_;
138 return *this;
139 }
140
141 // move operator
142 template < typename Key >
144 SequenceIteratorSafe< Key >::operator=(SequenceIteratorSafe< Key >&& source) noexcept {
145 _iterator_ = source._iterator_;
146 _seq_ = source._seq_;
147 return *this;
148 }
149
150 // point the iterator to the next value in the sequence
151 template < typename Key >
152 INLINE SequenceIteratorSafe< Key >& SequenceIteratorSafe< Key >::operator++() noexcept {
153 if (_iterator_ < _seq_->size()) ++_iterator_;
154 else _iterator_ = _seq_->size();
155
156 return *this;
157 }
158
159 // point the iterator to the preceding value in the sequence
160 template < typename Key >
161 INLINE SequenceIteratorSafe< Key >& SequenceIteratorSafe< Key >::operator--() noexcept {
162 if (_iterator_ != std::numeric_limits< Idx >::max()) --_iterator_;
163
164 return *this;
165 }
166
167 // makes the iterator point to i elements further in the sequence
168 template < typename Key >
169 INLINE SequenceIteratorSafe< Key >& SequenceIteratorSafe< Key >::operator+=(Size nb) noexcept {
170 if (_iterator_ == std::numeric_limits< Idx >::max()) return *this;
171 _iterator_ += nb;
172 if (_iterator_ > _seq_->size()) _iterator_ = _seq_->size();
173
174 return *this;
176
177 // makes the iterator point to i elements further in the sequence
178 template < typename Key >
179 INLINE SequenceIteratorSafe< Key >& SequenceIteratorSafe< Key >::operator-=(Size nb) noexcept {
180 if (_iterator_ == std::numeric_limits< Idx >::max()) return *this;
181 _iterator_ -= nb;
182 if (_iterator_ > _seq_->size()) _iterator_ = std::numeric_limits< Idx >::max();
183
184 return *this;
185 }
186
187 // returns a new iterator
188 template < typename Key >
189 INLINE SequenceIteratorSafe< Key > SequenceIteratorSafe< Key >::operator+(Size nb) noexcept {
190 return SequenceIteratorSafe< Key >{*this} += nb;
191 }
192
193 // returns a new iterator
194 template < typename Key >
195 INLINE SequenceIteratorSafe< Key > SequenceIteratorSafe< Key >::operator-(Size nb) noexcept {
196 return SequenceIteratorSafe< Key >{*this} -= nb;
197 }
198
199 // checks whether two iterators are pointing to the same element
200 template < typename Key >
202 const SequenceIteratorSafe< Key >& source) const noexcept {
203 if (_seq_->empty()) return true; // all iterators are the same if seq is empty
204
205 if ((_iterator_ != source._iterator_) || (_seq_ != source._seq_)) return false;
206
207 return true;
208 }
209
210 // checks whether two iterators are pointing to different elements
211 template < typename Key >
213 const SequenceIteratorSafe< Key >& source) const noexcept {
214 return !operator==(source);
215 }
216
217 // returns the position of the iterator in the sequence
218 template < typename Key >
220 if (_iterator_ >= _seq_->size()) {
221 GUM_ERROR(UndefinedIteratorValue, "iterator is end() or rend()")
222 }
224 return _iterator_;
225 }
226
227 // the iterator points to the posth element (0 = beginning of the sequence).
228 template < typename Key >
230 if (pos > _seq_->size()) _iterator_ = _seq_->size();
231 else _iterator_ = pos;
232 }
233
234 // the iterator points to the posth element (0 = beginning of the sequence).
235 template < typename Key >
237 _iterator_ = std::numeric_limits< Idx >::max();
238 }
239
240 // the iterator points to the posth element (0 = beginning of the sequence).
241 template < typename Key >
243 _iterator_ = _seq_->size();
245
246 // returns the value pointed to by the iterator
247 template < typename Key >
248 INLINE const Key& SequenceIteratorSafe< Key >::operator*() const {
249 return Getter::op_star(_seq_->_v_[pos()]);
250 }
252 // dereferences the value pointed to by the iterator
253 template < typename Key >
254 INLINE const Key* SequenceIteratorSafe< Key >::operator->() const {
255 return Getter::op_arrow(_seq_->_v_[pos()]);
256 }
257
258 // ===========================================================================
259 // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
260 // ===========================================================================
261
262 // updates const iterators
263 template < typename Key, bool Gen >
265 _end_safe_._setAtEnd_();
266 }
267
268 // clear the sequence
269 template < typename Key, bool Gen >
271 _h_.clear();
272 _v_.clear();
273 _update_end_();
274 }
275
276 // clears the current sequence and fill it with copies the element of aSeq
277 template < typename Key, bool Gen >
278 INLINE void
280 clear();
281
282 for (Size i = 0; i < aSeq.size(); ++i) {
283 Key& new_key = const_cast< Key& >(_h_.insert(*(aSeq._v_[i]), i).first);
284 _v_.push_back(&new_key);
285 }
287 _update_end_();
288 }
289
290 // Default constructor
291 template < typename Key, bool Gen >
293 _h_(size_param), _end_safe_{*this}, _rend_safe_{*this} {
294 GUM_CONSTRUCTOR(SequenceImplementation);
295 _rend_safe_._setAtRend_();
296 _update_end_();
297 }
298
299 // initializer list constructor
300 template < typename Key, bool Gen >
302 std::initializer_list< Key > list) : _end_safe_{*this}, _rend_safe_{*this} {
303 GUM_CONSTRUCTOR(SequenceImplementation);
304 _rend_safe_._setAtRend_();
305 for (const auto& elt: list) {
306 insert(elt); // performs the _update_end_ ()
307 }
308 }
309
310 // copy constructor
311 template < typename Key, bool Gen >
313 const SequenceImplementation< Key, Gen >& aSeq) : _end_safe_{*this}, _rend_safe_{*this} {
314 GUM_CONS_CPY(SequenceImplementation);
315 _rend_safe_._setAtRend_();
316 _copy_(aSeq); // performs the _update_end_ ()
317 }
318
319 // move constructor
320 template < typename Key, bool Gen >
323 _h_(std::move(aSeq._h_)), _v_(std::move(aSeq._v_)), _end_safe_{*this}, _rend_safe_{*this} {
324 GUM_CONS_MOV(SequenceImplementation);
325 _rend_safe_._setAtRend_();
326 _update_end_();
328
329 // destructor
330 template < typename Key, bool Gen >
334
335 // copy operator
336 template < typename Key, bool Gen >
339 // avoid self assignment
340 if (&aSeq != this) {
341 _copy_(aSeq); // performs the _update_end_ ()
342 }
343
344 return *this;
345 }
346
347 // move operator
348 template < typename Key, bool Gen >
351 // avoid self assignment
352 if (&aSeq != this) {
353 _h_ = std::move(aSeq._h_);
354 _v_ = std::move(aSeq._v_);
355 _update_end_();
356 }
357
358 return *this;
360
361 // check the existence of k in the sequence
362 template < typename Key, bool Gen >
363 INLINE bool SequenceImplementation< Key, Gen >::exists(const Key& k) const {
364 return _h_.exists(k);
365 }
366
367 // insert an element at the end of the sequence
368 template < typename Key, bool Gen >
370 // k will be added at the end. Insert the new key into the hashtable
371 Key& new_key = const_cast< Key& >(_h_.insert(k, _h_.size()).first);
372 _v_.push_back(&new_key);
373 _update_end_();
374 }
375
376 // insert an element at the end of the sequence
377 template < typename Key, bool Gen >
379 // k will be added at the end. Insert the new key into the hashtable
380 Key& new_key = const_cast< Key& >(_h_.insert(std::move(k), _h_.size()).first);
381 _v_.push_back(&new_key);
382 _update_end_();
383 }
384
385 // emplace a new element in the sequence
386 template < typename Key, bool Gen >
387 template < typename... Args >
389 Key key(std::forward< Args >(args)...);
390 Key& new_key = const_cast< Key& >(_h_.insert(std::move(key), _h_.size()).first);
391 _v_.push_back(&new_key);
392 _update_end_();
394
395 // insert k in the sequence (synonym for insert)
396 template < typename Key, bool Gen >
399 insert(k);
400 return *this;
401 }
402
403 // insert k in the sequence (synonym for insert)
404 template < typename Key, bool Gen >
407 insert(std::move(k));
408 return *this;
409 }
410
411 // remove an element from the sequence
412 template < typename Key, bool Gen >
414 // get the position of the element to remove
415 Idx pos;
416
417 try {
418 pos = _h_[k];
419 } catch (NotFound const&) { return; }
420
421 // erase the element
422 _v_.erase(_v_.begin() + pos);
423 for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
424 --_h_[*(_v_[i])];
425 }
426 _h_.erase(k);
427
428 _update_end_();
429 }
430
431 // remove from the sequence the element pointed to by the iterator
432 template < typename Key, bool Gen >
434 if (iter.pos() >= size()) return;
435
436 // erase the element
437 Idx pos = iter.pos();
438 Key* key = _v_[pos];
439 _v_.erase(_v_.begin() + pos);
440
441 for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
442 --_h_[*(_v_[i])];
443 }
444 _h_.erase(*key);
445
446 _update_end_();
447 }
449 // remove k in the sequence (synonym for erase)
450 template < typename Key, bool Gen >
453 erase(k);
454 return *this;
456
457 // returns the object at position i ( first elt = index 0 )
458 template < typename Key, bool Gen >
460 if (i >= _h_.size()) {
461 GUM_ERROR(OutOfBounds, "index " << i << " for a sequence of size" << _h_.size())
463
464 return *(_v_[i]);
465 }
466
467 // returns the element at position i (synonym for atPos)
468 template < typename Key, bool Gen >
470 return atPos(i);
471 }
472
473 // returns the position of the object passed in argument (if it exists)
474 template < typename Key, bool Gen >
475 INLINE Idx SequenceImplementation< Key, Gen >::pos(const Key& key) const {
476 return _h_[key];
477 }
478
479 // inserts and returns the object at the pos i
480 template < typename Key, bool Gen >
481 INLINE void SequenceImplementation< Key, Gen >::setAtPos(Idx i, const Key& newKey) {
482 if (i >= _h_.size()) { GUM_ERROR(NotFound, "index too large") }
483
484 Key& new_key = const_cast< Key& >(_h_.insert(newKey, i).first);
485 _h_.erase(*(_v_[i]));
486 _v_[i] = &new_key;
487 }
488
489 // inserts and returns the object at the pos i
490 template < typename Key, bool Gen >
492 if (i >= _h_.size()) { GUM_ERROR(NotFound, "index too large") }
493
494 Key& new_key = const_cast< Key& >(_h_.insert(std::move(newKey), i).first);
495 _h_.erase(*(_v_[i]));
496 _v_[i] = &new_key;
497 }
498
499 // replace two elements in the sequence
500 template < typename Key, bool Gen >
502 if (i == j) return;
503
504 Key& ki = const_cast< Key& >(atPos(i));
505 Key& kj = const_cast< Key& >(atPos(j));
506
507 _h_[ki] = j;
508 _h_[kj] = i;
509
510 _v_[i] = &kj;
511 _v_[j] = &ki;
512 }
513
514 // returns the first element
515 template < typename Key, bool Gen >
517 return atPos(0);
518 }
519
520 // returns the last element
521 template < typename Key, bool Gen >
523 return atPos(size() - 1);
524 }
525
526 // Print a sequence
527 template < typename Key, bool Gen >
529 std::stringstream stream;
530 stream << "[";
531
532 if (!_h_.empty()) {
533 stream << 0 << ":" << *_v_[0];
534
535 for (Idx i = 1; i < _h_.size(); ++i) {
536 stream << " - " << i << ":" << *_v_[i];
537 }
538 }
539
540 stream << "]";
541
542 std::string res = stream.str();
543 return res;
544 }
545
546 // returns true if the content of k equals that of *this
547 template < typename Key, bool Gen >
549 const SequenceImplementation< Key, Gen >& k) const {
550 if (size() != k.size()) return false;
551 else {
552 for (Idx i = 0; i < size(); ++i)
553 if (*_v_[i] != *(k._v_[i])) return false;
554 }
555
556 return true;
557 }
558
559 // returns true if the content of k is different from that of *this
560 template < typename Key, bool Gen >
565
566 // a << operator for displaying the content of the Sequence
567 template < typename Key, bool Gen >
568 INLINE std::ostream& operator<<(std::ostream& stream,
570 stream << seq.toString();
571 return stream;
572 }
573
574 // returns the safe begin iterator
575 template < typename Key, bool Gen >
579
580 // returns the safe end iterator
581 template < typename Key, bool Gen >
582 INLINE const SequenceIteratorSafe< Key >&
584 return _end_safe_;
585 }
586
587 // return an iterator pointing to the last element
588 template < typename Key, bool Gen >
591 it._setPos_(size() - 1);
592 return it;
593 }
594
595 // returns an iterator pointing just before the first element
596 template < typename Key, bool Gen >
597 INLINE const SequenceIteratorSafe< Key >&
599 return _rend_safe_;
600 }
601
602 // returns the unsafe begin iterator
603 template < typename Key, bool Gen >
604 INLINE SequenceIterator< Key > SequenceImplementation< Key, Gen >::begin() const {
605 return SequenceIterator< Key >{*this};
606 }
607
608 // returns the unsafe end iterator
609 template < typename Key, bool Gen >
610 INLINE const SequenceIterator< Key >& SequenceImplementation< Key, Gen >::end() const noexcept {
611 return _end_safe_;
612 }
613
614 // return an iterator pointing to the last element
615 template < typename Key, bool Gen >
616 INLINE SequenceIterator< Key > SequenceImplementation< Key, Gen >::rbegin() const {
617 SequenceIterator< Key > it{*this};
618 it._setPos_(size() - 1);
619 return it;
620 }
621
622 // returns an iterator pointing just before the first element
623 template < typename Key, bool Gen >
624 INLINE const SequenceIterator< Key >& SequenceImplementation< Key, Gen >::rend() const noexcept {
625 return _rend_safe_;
626 }
627
628 // modifies the size of the internal structures of the sequence
629 template < typename Key, bool Gen >
631 if (new_size < _h_.size()) return;
632
633 _h_.resize(new_size);
634 _v_.reserve(new_size);
635 }
636
637 // ===========================================================================
638 // === SCALAR GUM SEQUENCE IMPLEMENTATION ===
639 // ===========================================================================
640
641 // updates the end iterators
642 template < typename Key >
644 _end_safe_._setAtEnd_();
645 }
646
647 // clear the sequence
648 template < typename Key >
650 _h_.clear();
651 _v_.clear();
652 _update_end_();
653 }
654
655 // clears the current sequence and fill it with copies the element of aSeq
656 template < typename Key >
657 INLINE void
659 clear();
660
661 for (Size i = 0; i < aSeq.size(); ++i) {
662 _h_.insert(aSeq._v_[i], i);
663 _v_.push_back(aSeq._v_[i]);
664 }
665
666 _update_end_();
667 }
668
669 // Default constructor
670 template < typename Key >
672 _h_(size_param), _end_safe_{*this}, _rend_safe_{*this} {
673 GUM_CONSTRUCTOR(SequenceImplementation);
674 _rend_safe_._setAtRend_();
675 _end_safe_._setAtEnd_();
676 }
677
678 // initializer list constructor
679 template < typename Key >
681 std::initializer_list< Key > list) : _end_safe_{*this}, _rend_safe_{*this} {
682 GUM_CONSTRUCTOR(SequenceImplementation);
683 _rend_safe_._setAtRend_();
684 for (const auto& elt: list) {
685 insert(elt);
686 }
687 }
688
689 // copy constructor
690 template < typename Key >
693 _h_(aSeq._h_), _v_(aSeq._v_), _end_safe_{*this}, _rend_safe_{*this} {
694 GUM_CONS_CPY(SequenceImplementation);
695 _rend_safe_._setAtRend_();
696 _end_safe_._setAtEnd_();
697 }
698
699 // move constructor
700 template < typename Key >
703 _h_(std::move(aSeq._h_)), _v_(std::move(aSeq._v_)), _end_safe_{*this}, _rend_safe_{*this} {
704 GUM_CONS_MOV(SequenceImplementation);
705 _rend_safe_._setAtRend_();
706 _end_safe_._setAtEnd_();
707 }
708
709 // destructor
710 template < typename Key >
712 GUM_DESTRUCTOR(SequenceImplementation);
713 }
714
715 // copy operator
716 template < typename Key >
719 // avoid self assignment
720 if (&aSeq != this) { _copy_(aSeq); }
721
722 return *this;
723 }
724
725 // move operator
726 template < typename Key >
729 // avoid self assignment
730 if (&aSeq != this) {
731 _h_ = std::move(aSeq._h_);
732 _v_ = std::move(aSeq._v_);
733 _update_end_();
734 }
735
736 return *this;
737 }
738
739 // check the existence of k in the sequence
740 template < typename Key >
741 INLINE bool SequenceImplementation< Key, true >::exists(Key k) const {
742 return _h_.exists(k);
743 }
744
745 // insert an element at the end of the sequence
746 template < typename Key >
748 // k will be added at the end. Insert the new key into the hashtable
749 _h_.insert(k, _h_.size());
750 _v_.push_back(k);
751 _update_end_();
752 }
753
754 // emplace a new element in the sequence
755 template < typename Key >
756 template < typename... Args >
757 INLINE void SequenceImplementation< Key, true >::emplace(Args&&... args) {
758 Key new_key(std::forward< Args >(args)...);
759 _h_.insert(new_key, _h_.size());
760 _v_.push_back(new_key);
761 _update_end_();
762 }
763
764 // insert k in the sequence (synonym for insert)
765 template < typename Key >
768 insert(k);
769 return *this;
770 }
771
772 // remove an element from the sequence
773 template < typename Key >
775 // get the position of the element to remove
776 Idx pos;
777
778 try {
779 pos = _h_[k];
780 } catch (NotFound const&) { return; }
781
782 // erase the element
783 _v_.erase(_v_.begin() + pos);
784 for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
785 --_h_[_v_[i]];
786 }
787 _h_.erase(k);
788
789 _update_end_();
790 }
791
792 // remove from the sequence the element pointed to by the iterator
793 template < typename Key >
794 INLINE void SequenceImplementation< Key, true >::erase(const iterator_safe& iter) {
795 if (iter.pos() >= size()) return;
796
797 // erase the element
798 Idx pos = iter.pos();
799 Key key = _v_[pos];
800 _v_.erase(_v_.begin() + pos);
801
802 for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
803 --_h_[_v_[i]];
804 }
805 _h_.erase(key);
806
807 _update_end_();
808 }
809
810 // remove k in the sequence (synonym for erase)
811 template < typename Key >
814 erase(k);
815 return *this;
816 }
817
818 // returns the object at position i
819 template < typename Key >
820 INLINE const Key& SequenceImplementation< Key, true >::atPos(Idx i) const {
821 if (i >= _h_.size()) { GUM_ERROR(NotFound, "not enough elements in the sequence") }
822
823 return _v_[i];
824 }
825
826 // returns the element at position i (synonym for atPos)
827 template < typename Key >
828 INLINE const Key& SequenceImplementation< Key, true >::operator[](Idx i) const {
829 return atPos(i);
830 }
831
832 // returns the position of the object passed in argument (if it exists)
833 template < typename Key >
834 INLINE Idx SequenceImplementation< Key, true >::pos(Key key) const {
835 return _h_[key];
836 }
837
838 // sets the object at position i
839 template < typename Key >
840 INLINE void SequenceImplementation< Key, true >::setAtPos(Idx i, Key newKey) {
841 if (i >= _h_.size()) { GUM_ERROR(NotFound, "index too large") }
842
843 _h_.insert(newKey, i);
844 _h_.erase(_v_[i]);
845 _v_[i] = newKey;
846 }
847
848 // replace two elements in the sequence
849 template < typename Key >
851 if (i == j) return;
852
853 Key ki = atPos(i);
854 Key kj = atPos(j);
855
856 _h_[ki] = j;
857 _h_[kj] = i;
858
859 _v_[i] = kj;
860 _v_[j] = ki;
861 }
862
863 // returns the first element
864 template < typename Key >
865 INLINE const Key& SequenceImplementation< Key, true >::front() const {
866 return atPos(0);
867 }
868
869 // returns the last element
870 template < typename Key >
871 INLINE const Key& SequenceImplementation< Key, true >::back() const {
872 return atPos(size() - 1);
873 }
874
875 // Print a sequence
876 template < typename Key >
878 std::stringstream stream;
879 stream << "[";
880
881 if (!_h_.empty()) {
882 stream << 0 << ":" << _v_[0];
883
884 for (Idx i = 1; i < _h_.size(); ++i) {
885 stream << " - " << i << ":" << _v_[i];
886 }
887 }
888
889 stream << "]";
890
891 std::string res = stream.str();
892 return res;
893 }
894
895 // returns true if the content of k equals that of *this
896 template < typename Key >
899 if (size() != k.size()) return false;
900 else {
901 for (Idx i = 0; i < size(); ++i)
902 if (_v_[i] != k._v_[i]) return false;
903 }
904
905 return true;
906 }
907
908 // returns true if the content of k is different from that of *this
909 template < typename Key >
912 return !operator==(k);
913 }
914
915 // a << operator for displaying the content of the Sequence
916 template < typename Key >
917 INLINE std::ostream& operator<<(std::ostream& stream,
919 stream << seq.toString();
920 return stream;
921 }
922
923 // returns the safe begin iterator
924 template < typename Key >
925 INLINE SequenceIteratorSafe< Key > SequenceImplementation< Key, true >::beginSafe() const {
926 return SequenceIteratorSafe< Key >{*this};
927 }
928
929 // return the safe end iterator
930 template < typename Key >
931 INLINE const SequenceIteratorSafe< Key >&
933 return _end_safe_;
934 }
935
936 // return an iterator pointing to the last element
937 template < typename Key >
940 it._setPos_(size() - 1);
941 return it;
942 }
943
944 // returns an iterator pointing just before the first element
945 template < typename Key >
946 INLINE const SequenceIteratorSafe< Key >&
948 return _rend_safe_;
949 }
950
951 // returns the unsafe begin iterator
952 template < typename Key >
953 INLINE SequenceIterator< Key > SequenceImplementation< Key, true >::begin() const {
954 return SequenceIterator< Key >{*this};
955 }
956
957 // return the unsafe end iterator
958 template < typename Key >
959 INLINE const SequenceIterator< Key >& SequenceImplementation< Key, true >::end() const noexcept {
960 return _end_safe_;
961 }
962
963 // return an unsafe iterator pointing to the last element
964 template < typename Key >
965 INLINE SequenceIterator< Key > SequenceImplementation< Key, true >::rbegin() const {
966 SequenceIterator< Key > it{*this};
967 it._setPos_(size() - 1);
968 return it;
969 }
970
971 // returns an unsafe iterator pointing just before the first element
972 template < typename Key >
973 INLINE const SequenceIterator< Key >& SequenceImplementation< Key, true >::rend() const noexcept {
974 return _rend_safe_;
975 }
976
977 // modifies the size of the internal structures of the sequence
978 template < typename Key >
980 if (new_size < _h_.size()) return;
981
982 _h_.resize(new_size);
983 _v_.reserve(new_size);
984 }
985
986 // ===========================================================================
987 // Sequence
988 // ===========================================================================
989
990 // Default constructor
991 template < typename Key >
992 INLINE Sequence< Key >::Sequence(Size size_param) :
993 SequenceImplementation< Key, std::is_scalar< Key >::value >(size_param) {
994 GUM_CONSTRUCTOR(Sequence);
995 }
996
997 // initializer list constructor
998 template < typename Key >
999 INLINE Sequence< Key >::Sequence(std::initializer_list< Key > list) :
1000 SequenceImplementation< Key, std::is_scalar< Key >::value >(list) {
1001 // for debugging purposes
1002 GUM_CONSTRUCTOR(Sequence);
1003 }
1004
1005 // copy constructor
1006 template < typename Key >
1008 SequenceImplementation< Key, std::is_scalar< Key >::value >(aSeq) {
1009 // for debugging purposes
1010 GUM_CONS_CPY(Sequence);
1011 }
1012
1013 // move constructor
1014 template < typename Key >
1016 SequenceImplementation< Key, std::is_scalar< Key >::value >(std::move(aSeq)) {
1017 // for debugging purposes
1018 GUM_CONS_MOV(Sequence);
1019 }
1020
1021 // destructor
1022 template < typename Key >
1023 INLINE Sequence< Key >::~Sequence() noexcept {
1024 // for debugging purposes
1025 GUM_DESTRUCTOR(Sequence);
1026 }
1028 // copy operator
1029 template < typename Key >
1032 return *this;
1033 }
1034
1035 // move operator
1036 template < typename Key >
1038 Implementation::operator=(std::move(aSeq));
1039 return *this;
1041
1042 // returns the set difference : this \ seq
1043 template < typename Key >
1045 Set< Key > res;
1046
1047 for (iterator iter = this->begin(); iter != this->end(); ++iter) {
1048 if (!seq.exists(*iter)) res << *iter;
1049 }
1050
1051 return res;
1052 }
1053
1054 // a << operator for displaying the content of the Sequence
1055 template < typename Key >
1056 INLINE std::ostream& operator<<(std::ostream& stream, const Sequence< Key >& seq) {
1057 stream << seq.toString();
1058 return stream;
1059 }
1060
1061} /* namespace gum */
Exception : the element we looked for cannot be found.
Exception : out of bound.
The internal class for storing (ordered) sequences of objects.
Definition sequence.h:109
const iterator & end() const noexcept
Returns the unsafe end iterator.
std::string toString() const
Displays the content of the sequence.
void _copy_(const SequenceImplementation< Key, Gen > &aSeq)
Clears the current sequence and fill it with copies the element of aSeq.
SequenceIteratorSafe< Key > iterator_safe
Types for STL compliance.
Definition sequence.h:128
void swap(Idx i, Idx j)
Swap index.
iterator_safe beginSafe() const
Returns a safe begin iterator.
SequenceImplementation< Key, Gen > & operator=(const SequenceImplementation< Key, Gen > &aSeq)
Copy operator.
SequenceImplementation< Key, Gen > & operator<<(const Key &k)
Insert k at the end of the sequence (synonym for insert).
const Key & front() const
Returns the first element of the element.
std::vector< Key * > _v_
The set of the elements stored into the sequence.
Definition sequence.h:491
void emplace(Args &&... args)
Emplace a new element in the sequence.
void _update_end_() noexcept
A method to update the end iterator after changes in the sequence.
iterator begin() const
Returns an unsafe begin iterator.
iterator rbegin() const
Returns an unsafe rbegin iterator.
SequenceIteratorSafe< Key > _rend_safe_
Stores the rend iterator for fast access.
Definition sequence.h:501
bool operator==(const SequenceImplementation< Key, Gen > &k) const
Returns true if the content of k equals that of *this.
const iterator_safe & endSafe() const noexcept
Returns the safe end iterator.
void erase(const Key &k)
Remove an element from the sequence.
void clear()
Clear the sequence.
Size size() const noexcept
Returns the size of the sequence.
bool exists(const Key &k) const
Check the existence of k in the sequence.
const iterator & rend() const noexcept
Returns the unsafe rend iterator.
const Key & operator[](Idx i) const
Returns the element at position i (synonym for atPos).
bool operator!=(const SequenceImplementation< Key, Gen > &k) const
Returns true if the content of k is different from that of *this.
SequenceImplementation< Key, Gen > & operator>>(const Key &k)
Remove k in the sequence (synonym for erase).
const iterator_safe & rendSafe() const noexcept
Returns the safe rend iterator.
~SequenceImplementation() noexcept
Class destructor.
const Key & back() const
Returns the last element of the sequence.
const Key & atPos(Idx i) const
Returns the object at the pos i.
bool empty() const noexcept
Return true if empty.
SequenceImplementation(Size size_param=HashTableConst::default_size)
Default constructor.
void setAtPos(Idx i, const Key &newKey)
Change the value.
SequenceIteratorSafe< Key > _end_safe_
Stores the end iterator for fast access.
Definition sequence.h:498
void resize(Size new_size)
Modifies the size of the internal structures of the sequence.
iterator_safe rbeginSafe() const
Returns a safe rbegin iterator.
HashTable< Key, Idx > _h_
Keep track of the position of the element in v (for fast retrieval).
Definition sequence.h:488
void insert(const Key &k)
Insert an element at the end of the sequence.
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
Safe iterators for Sequence.
Definition sequence.h:1134
SequenceIteratorSafe< Key > & operator--() noexcept
Point the iterator to the preceding value in the sequence.
SequenceIteratorSafe< Key > & operator=(const SequenceIteratorSafe< Key > &source) noexcept
Copy operator.
void _setAtEnd_() noexcept
The iterator points to the end (which is pos size()-1).
const SequenceImplementation< const gum::DiscreteVariable *, std::is_scalar< const gum::DiscreteVariable * >::value > * _seq_
Definition sequence.h:1342
SequenceIteratorSafe< Key > operator+(Size nb) noexcept
Returns a new iterator.
SequenceIteratorSafe< Key > & operator++() noexcept
Point the iterator to the next value in the sequence.
void _setAtRend_() noexcept
The iterator points to rend.
bool operator!=(const SequenceIteratorSafe< Key > &source) const noexcept
Checks whether two iterators are pointing to different elements.
Idx _iterator_
The index in the sequence's vector where the iterator is pointing.
Definition sequence.h:1339
const Key * operator->() const
Returns the value pointed to by the iterator (works only for non-scalars).
SequenceIteratorSafe(const SequenceImplementation< Key, Gen > &seq, Idx pos=0) noexcept
Constructor, always give a valid iterator (even if pos too large).
SequenceIteratorSafe< Key > & operator-=(Size nb) noexcept
Makes the iterator point to i elements further in the sequence.
SequenceIteratorSafe< Key > operator-(Size nb) noexcept
Returns a new iterator.
bool operator==(const SequenceIteratorSafe< Key > &source) const noexcept
Checks whether two iterators are pointing to the same elements.
~SequenceIteratorSafe() noexcept
Class destructor.
void _setPos_(Idx pos) noexcept
The iterator points to the posth element (0 = beginning of the sequence).
SequenceIteratorSafe< Key > & operator+=(Size nb) noexcept
Makes the iterator point to i elements further in the sequence.
const Key & operator*() const
Returns the value pointed to by the iterator.
The generic class for storing (ordered) sequences of objects.
Definition sequence.h:972
Sequence(Size size_param=HashTableConst::default_size)
Default constructor.
~Sequence() noexcept
Class destructor.
Sequence< Key > & operator=(const Sequence< Key > &aSeq)
Copy operator.
SequenceIterator< Key > iterator
Types for STL compliance.
Definition sequence.h:983
Set< Key > diffSet(const Sequence< Key > &seq) const
Difference between two sequences as a Set<Key> = this \ seq.
Representation of a set.
Definition set.h:131
Exception : generic error on iterator.
#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
Size Idx
Type for indexes.
Definition types.h:79
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
bool operator==(const HashTableIteratorSafe< Key, Val > &from) const noexcept
Checks whether two iterators are pointing toward equal elements.
STL namespace.
Header file of gum::Sequence, a class for storing (ordered) sequences of objects.