aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
sequence_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Template implementation file of gum::Sequence, a class for storing
25  * (ordered) sequences of objects.
26  *
27  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
28  */
29 
30 // to ease IDE parser
31 #include <agrum/tools/core/sequence.h>
32 
33 namespace gum {
34 
35  // returns the size of the sequence
36  template < typename Key, typename Alloc, bool Gen >
37  INLINE Size SequenceImplementation< Key, Alloc, Gen >::size() const noexcept {
38  return _h_.size();
39  }
40 
41  // return true if empty
42  template < typename Key, typename Alloc, bool Gen >
43  INLINE bool SequenceImplementation< Key, Alloc, Gen >::empty() const noexcept {
44  return _h_.empty();
45  }
46 
47  // returns the size of the sequence
48  template < typename Key, typename Alloc >
49  INLINE Size SequenceImplementation< Key, Alloc, true >::size() const noexcept {
50  return _h_.size();
51  }
52 
53  // return true if empty
54  template < typename Key, typename Alloc >
55  INLINE bool SequenceImplementation< Key, Alloc, true >::empty() const noexcept {
56  return _h_.empty();
57  }
58 
59  // ===========================================================================
60  // class SequenceIteratorSafe
61  // ===========================================================================
62 
63  // default constructor
64  template < typename Key >
65  template < typename Alloc, bool Gen >
68  Idx pos) noexcept :
69  _seq_{
70  reinterpret_cast< const SequenceImplementation< Key,
71  std::allocator< Key >,
72  std::is_scalar< Key >::value >* >(&seq)} {
74 
75  if (pos > _seq_->size())
76  _iterator_ = _seq_->size(); // make the iterator point to end
77  else
78  _iterator_ = pos;
79  }
80 
81  // default constructor
82  template < typename Key >
83  template < typename Alloc >
85  Idx pos) noexcept :
86  _seq_{
87  reinterpret_cast< const SequenceImplementation< Key,
88  std::allocator< Key >,
89  std::is_scalar< Key >::value >* >(&seq)} {
91 
92  if (pos > _seq_->size())
93  _iterator_ = _seq_->size(); // make the iterator point to end
94  else
95  _iterator_ = pos;
96  }
97 
98  // copy constructor
99  template < typename Key >
101  const SequenceIteratorSafe< Key >& source) noexcept :
103  _seq_{source._seq_} {
105  }
106 
107  // move constructor
108  template < typename Key >
110  SequenceIteratorSafe< Key >&& source) noexcept :
112  _seq_{source._seq_} {
114  }
115 
116  // destructor
117  template < typename Key >
120  }
121 
122  // copy operator
123  template < typename Key >
127  _seq_ = source._seq_;
128  return *this;
129  }
130 
131  // move operator
132  template < typename Key >
136  _seq_ = source._seq_;
137  return *this;
138  }
139 
140  // point the iterator to the next value in the sequence
141  template < typename Key >
143  if (_iterator_ < _seq_->size())
144  ++_iterator_;
145  else
146  _iterator_ = _seq_->size();
147 
148  return *this;
149  }
150 
151  // point the iterator to the preceding value in the sequence
152  template < typename Key >
154  if (_iterator_ != std::numeric_limits< Idx >::max()) --_iterator_;
155 
156  return *this;
157  }
158 
159  // makes the iterator point to i elements further in the sequence
160  template < typename Key >
162  if (_iterator_ == std::numeric_limits< Idx >::max()) return *this;
163  _iterator_ += nb;
164  if (_iterator_ > _seq_->size()) _iterator_ = _seq_->size();
165 
166  return *this;
167  }
168 
169  // makes the iterator point to i elements further in the sequence
170  template < typename Key >
172  if (_iterator_ == std::numeric_limits< Idx >::max()) return *this;
173  _iterator_ -= nb;
175 
176  return *this;
177  }
178 
179  // returns a new iterator
180  template < typename Key >
182  return SequenceIteratorSafe< Key >{*this} += nb;
183  }
184 
185  // returns a new iterator
186  template < typename Key >
188  return SequenceIteratorSafe< Key >{*this} -= nb;
189  }
190 
191  // checks whether two iterators are pointing to the same element
192  template < typename Key >
194  const SequenceIteratorSafe< Key >& source) const noexcept {
195  if (_seq_->empty()) return true; // all iterators are the same if seq is empty
196 
197  if ((_iterator_ != source._iterator_) || (_seq_ != source._seq_)) return false;
198 
199  return true;
200  }
201 
202  // checks whether two iterators are pointing to different elements
203  template < typename Key >
205  const SequenceIteratorSafe< Key >& source) const noexcept {
206  return !operator==(source);
207  }
208 
209  // returns the position of the iterator in the sequence
210  template < typename Key >
212  if (_iterator_ >= _seq_->size()) {
213  GUM_ERROR(UndefinedIteratorValue, "iterator is end() or rend()")
214  }
215 
216  return _iterator_;
217  }
218 
219  // the iterator points to the posth element (0 = beginning of the sequence).
220  template < typename Key >
222  if (pos > _seq_->size())
223  _iterator_ = _seq_->size();
224  else
225  _iterator_ = pos;
226  }
227 
228  // the iterator points to the posth element (0 = beginning of the sequence).
229  template < typename Key >
232  }
233 
234  // the iterator points to the posth element (0 = beginning of the sequence).
235  template < typename Key >
237  _iterator_ = _seq_->size();
238  }
239 
240  // returns the value pointed to by the iterator
241  template < typename Key >
243  return Getter::op_star(_seq_->_v_[pos()]);
244  }
245 
246  // dereferences the value pointed to by the iterator
247  template < typename Key >
248  INLINE const Key* SequenceIteratorSafe< Key >::operator->() const {
249  return Getter::op_arrow(_seq_->_v_[pos()]);
250  }
251 
252  // ===========================================================================
253  // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
254  // ===========================================================================
255 
256  // updates const iterators
257  template < typename Key, typename Alloc, bool Gen >
260  }
261 
262  // clear the sequence
263  template < typename Key, typename Alloc, bool Gen >
265  _h_.clear();
266  _v_.clear();
267  _update_end_();
268  }
269 
270  // clears the current sequence and fill it with copies the element of aSeq
271  template < typename Key, typename Alloc, bool Gen >
272  template < typename OtherAlloc >
275  clear();
276 
277  for (Size i = 0; i < aSeq.size(); ++i) {
278  Key& new_key = const_cast< Key& >(_h_.insert(*(aSeq._v_[i]), i).first);
280  }
281 
282  _update_end_();
283  }
284 
285  // Default constructor
286  template < typename Key, typename Alloc, bool Gen >
288  _h_(size_param), _end_safe_{*this}, _rend_safe_{*this} {
291  _update_end_();
292  }
293 
294  // initializer list constructor
295  template < typename Key, typename Alloc, bool Gen >
298  _end_safe_{*this},
299  _rend_safe_{*this} {
302  for (const auto& elt: list) {
303  insert(elt); // performs the _update_end_ ()
304  }
305  }
306 
307  // copy constructor
308  template < typename Key, typename Alloc, bool Gen >
310  const SequenceImplementation< Key, Alloc, Gen >& aSeq) :
311  _end_safe_{*this},
312  _rend_safe_{*this} {
315  _copy_(aSeq); // performs the _update_end_ ()
316  }
317 
318  // generalized copy constructor
319  template < typename Key, typename Alloc, bool Gen >
320  template < typename OtherAlloc >
323  _end_safe_{*this},
324  _rend_safe_{*this} {
327  _copy_(aSeq); // performs the _update_end_ ()
328  }
329 
330  // move constructor
331  template < typename Key, typename Alloc, bool Gen >
334  _h_(std::move(aSeq._h_)),
335  _v_(std::move(aSeq._v_)), _end_safe_{*this}, _rend_safe_{*this} {
338  _update_end_();
339  }
340 
341  // destructor
342  template < typename Key, typename Alloc, bool Gen >
345  }
346 
347  // copy operator
348  template < typename Key, typename Alloc, bool Gen >
351  const SequenceImplementation< Key, Alloc, Gen >& aSeq) {
352  // avoid self assignment
353  if (&aSeq != this) {
354  _copy_(aSeq); // performs the _update_end_ ()
355  }
356 
357  return *this;
358  }
359 
360  // generalized copy operator
361  template < typename Key, typename Alloc, bool Gen >
362  template < typename OtherAlloc >
366  _copy_(aSeq); // performs the _update_end_ ()
367  return *this;
368  }
369 
370  // move operator
371  template < typename Key, typename Alloc, bool Gen >
375  // avoid self assignment
376  if (&aSeq != this) {
377  _h_ = std::move(aSeq._h_);
378  _v_ = std::move(aSeq._v_);
379  _update_end_();
380  }
381 
382  return *this;
383  }
384 
385  // check the existence of k in the sequence
386  template < typename Key, typename Alloc, bool Gen >
387  INLINE bool SequenceImplementation< Key, Alloc, Gen >::exists(const Key& k) const {
388  return _h_.exists(k);
389  }
390 
391  // insert an element at the end of the sequence
392  template < typename Key, typename Alloc, bool Gen >
394  // k will be added at the end. Insert the new key into the hashtable
395  Key& new_key = const_cast< Key& >(_h_.insert(k, _h_.size()).first);
397  _update_end_();
398  }
399 
400  // insert an element at the end of the sequence
401  template < typename Key, typename Alloc, bool Gen >
403  // k will be added at the end. Insert the new key into the hashtable
404  Key& new_key = const_cast< Key& >(_h_.insert(std::move(k), _h_.size()).first);
406  _update_end_();
407  }
408 
409  // emplace a new element in the sequence
410  template < typename Key, typename Alloc, bool Gen >
411  template < typename... Args >
413  Key key(std::forward< Args >(args)...);
414  Key& new_key = const_cast< Key& >(_h_.insert(std::move(key), _h_.size()).first);
416  _update_end_();
417  }
418 
419  // insert k in the sequence (synonym for insert)
420  template < typename Key, typename Alloc, bool Gen >
423  insert(k);
424  return *this;
425  }
426 
427  // insert k in the sequence (synonym for insert)
428  template < typename Key, typename Alloc, bool Gen >
431  insert(std::move(k));
432  return *this;
433  }
434 
435  // remove an element from the sequence
436  template < typename Key, typename Alloc, bool Gen >
438  // get the position of the element to remove
439  Idx pos;
440 
441  try {
442  pos = _h_[k];
443  } catch (NotFound&) { return; }
444 
445  // erase the element
446  _v_.erase(_v_.begin() + pos);
447  for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
448  --_h_[*(_v_[i])];
449  }
450  _h_.erase(k);
451 
452  _update_end_();
453  }
454 
455  // remove from the sequence the element pointed to by the iterator
456  template < typename Key, typename Alloc, bool Gen >
458  if (iter.pos() >= size()) return;
459 
460  // erase the element
461  Idx pos = iter.pos();
462  Key* key = _v_[pos];
463  _v_.erase(_v_.begin() + pos);
464 
465  for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
466  --_h_[*(_v_[i])];
467  }
468  _h_.erase(*key);
469 
470  _update_end_();
471  }
472 
473  // remove k in the sequence (synonym for erase)
474  template < typename Key, typename Alloc, bool Gen >
477  erase(k);
478  return *this;
479  }
480 
481  // returns the object at position i ( first elt = index 0 )
482  template < typename Key, typename Alloc, bool Gen >
484  if (i >= _h_.size()) {
485  GUM_ERROR(OutOfBounds, "index " << i << " for a sequence of size" << _h_.size())
486  }
487 
488  return *(_v_[i]);
489  }
490 
491  // returns the element at position i (synonym for atPos)
492  template < typename Key, typename Alloc, bool Gen >
494  return atPos(i);
495  }
496 
497  // returns the position of the object passed in argument (if it exists)
498  template < typename Key, typename Alloc, bool Gen >
500  return _h_[key];
501  }
502 
503  // inserts and returns the object at the pos i
504  template < typename Key, typename Alloc, bool Gen >
506  if (i >= _h_.size()) { GUM_ERROR(NotFound, "index too large") }
507 
508  Key& new_key = const_cast< Key& >(_h_.insert(newKey, i).first);
509  _h_.erase(*(_v_[i]));
510  _v_[i] = &new_key;
511  }
512 
513  // inserts and returns the object at the pos i
514  template < typename Key, typename Alloc, bool Gen >
516  if (i >= _h_.size()) { GUM_ERROR(NotFound, "index too large") }
517 
518  Key& new_key = const_cast< Key& >(_h_.insert(std::move(newKey), i).first);
519  _h_.erase(*(_v_[i]));
520  _v_[i] = &new_key;
521  }
522 
523  // replace two elements in the sequence
524  template < typename Key, typename Alloc, bool Gen >
526  if (i == j) return;
527 
528  Key& ki = const_cast< Key& >(atPos(i));
529  Key& kj = const_cast< Key& >(atPos(j));
530 
531  _h_[ki] = j;
532  _h_[kj] = i;
533 
534  _v_[i] = &kj;
535  _v_[j] = &ki;
536  }
537 
538  // returns the first element
539  template < typename Key, typename Alloc, bool Gen >
541  return atPos(0);
542  }
543 
544  // returns the last element
545  template < typename Key, typename Alloc, bool Gen >
547  return atPos(size() - 1);
548  }
549 
550  // Print a sequence
551  template < typename Key, typename Alloc, bool Gen >
554  stream << "[";
555 
556  if (!_h_.empty()) {
557  stream << 0 << ":" << *_v_[0];
558 
559  for (Idx i = 1; i < _h_.size(); ++i) {
560  stream << " - " << i << ":" << *_v_[i];
561  }
562  }
563 
564  stream << "]";
565 
566  std::string res = stream.str();
567  return res;
568  }
569 
570  // returns true if the content of k equals that of *this
571  template < typename Key, typename Alloc, bool Gen >
572  template < typename OtherAlloc >
574  const SequenceImplementation< Key, OtherAlloc, Gen >& k) const {
575  if (size() != k.size())
576  return false;
577  else {
578  for (Idx i = 0; i < size(); ++i)
579  if (*_v_[i] != *(k._v_[i])) return false;
580  }
581 
582  return true;
583  }
584 
585  // returns true if the content of k is different from that of *this
586  template < typename Key, typename Alloc, bool Gen >
587  template < typename OtherAlloc >
589  const SequenceImplementation< Key, OtherAlloc, Gen >& k) const {
590  return !operator==(k);
591  }
592 
593  // a << operator for displaying the content of the Sequence
594  template < typename Key, typename Alloc, bool Gen >
596  const SequenceImplementation< Key, Alloc, Gen >& seq) {
597  stream << seq.toString();
598  return stream;
599  }
600 
601  // returns the safe begin iterator
602  template < typename Key, typename Alloc, bool Gen >
604  return SequenceIteratorSafe< Key >{*this};
605  }
606 
607  // returns the safe end iterator
608  template < typename Key, typename Alloc, bool Gen >
610  SequenceImplementation< Key, Alloc, Gen >::endSafe() const noexcept {
611  return _end_safe_;
612  }
613 
614  // return an iterator pointing to the last element
615  template < typename Key, typename Alloc, bool Gen >
617  SequenceIteratorSafe< 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, typename Alloc, bool Gen >
625  SequenceImplementation< Key, Alloc, Gen >::rendSafe() const noexcept {
626  return _rend_safe_;
627  }
628 
629  // returns the unsafe begin iterator
630  template < typename Key, typename Alloc, bool Gen >
632  return SequenceIterator< Key >{*this};
633  }
634 
635  // returns the unsafe end iterator
636  template < typename Key, typename Alloc, bool Gen >
637  INLINE const SequenceIterator< Key >&
638  SequenceImplementation< Key, Alloc, Gen >::end() const noexcept {
639  return _end_safe_;
640  }
641 
642  // return an iterator pointing to the last element
643  template < typename Key, typename Alloc, bool Gen >
645  SequenceIterator< Key > it{*this};
646  it._setPos_(size() - 1);
647  return it;
648  }
649 
650  // returns an iterator pointing just before the first element
651  template < typename Key, typename Alloc, bool Gen >
652  INLINE const SequenceIterator< Key >&
653  SequenceImplementation< Key, Alloc, Gen >::rend() const noexcept {
654  return _rend_safe_;
655  }
656 
657  // modifies the size of the internal structures of the sequence
658  template < typename Key, typename Alloc, bool Gen >
660  if (new_size < _h_.size()) return;
661 
664  }
665 
666  // ===========================================================================
667  // === SCALAR GUM SEQUENCE IMPLEMENTATION ===
668  // ===========================================================================
669 
670  // updates the end iterators
671  template < typename Key, typename Alloc >
672  INLINE void SequenceImplementation< Key, Alloc, true >::_update_end_() noexcept {
674  }
675 
676  // clear the sequence
677  template < typename Key, typename Alloc >
678  INLINE void SequenceImplementation< Key, Alloc, true >::clear() {
679  _h_.clear();
680  _v_.clear();
681  _update_end_();
682  }
683 
684  // clears the current sequence and fill it with copies the element of aSeq
685  template < typename Key, typename Alloc >
686  template < typename OtherAlloc >
688  const SequenceImplementation< Key, OtherAlloc, true >& aSeq) {
689  clear();
690 
691  for (Size i = 0; i < aSeq.size(); ++i) {
692  _h_.insert(aSeq._v_[i], i);
693  _v_.push_back(aSeq._v_[i]);
694  }
695 
696  _update_end_();
697  }
698 
699  // Default constructor
700  template < typename Key, typename Alloc >
702  _h_(size_param), _end_safe_{*this}, _rend_safe_{*this} {
706  }
707 
708  // initializer list constructor
709  template < typename Key, typename Alloc >
712  _end_safe_{*this},
713  _rend_safe_{*this} {
716  for (const auto& elt: list) {
717  insert(elt);
718  }
719  }
720 
721  // copy constructor
722  template < typename Key, typename Alloc >
724  const SequenceImplementation< Key, Alloc, true >& aSeq) :
725  _h_(aSeq._h_),
726  _v_(aSeq._v_), _end_safe_{*this}, _rend_safe_{*this} {
730  }
731 
732  // generalized copy constructor
733  template < typename Key, typename Alloc >
734  template < typename OtherAlloc >
736  const SequenceImplementation< Key, OtherAlloc, true >& aSeq) :
737  _h_(aSeq.size() / 2),
738  _end_safe_{*this}, _rend_safe_{*this} {
741  _copy_(aSeq);
742  }
743 
744  // move constructor
745  template < typename Key, typename Alloc >
747  SequenceImplementation< Key, Alloc, true >&& aSeq) :
748  _h_(std::move(aSeq._h_)),
749  _v_(std::move(aSeq._v_)), _end_safe_{*this}, _rend_safe_{*this} {
753  }
754 
755  // destructor
756  template < typename Key, typename Alloc >
757  SequenceImplementation< Key, Alloc, true >::~SequenceImplementation() noexcept {
759  }
760 
761  // copy operator
762  template < typename Key, typename Alloc >
765  const SequenceImplementation< Key, Alloc, true >& aSeq) {
766  // avoid self assignment
767  if (&aSeq != this) { _copy_(aSeq); }
768 
769  return *this;
770  }
771 
772  // generalized copy operator
773  template < typename Key, typename Alloc >
774  template < typename OtherAlloc >
777  const SequenceImplementation< Key, OtherAlloc, true >& aSeq) {
778  _copy_(aSeq);
779  return *this;
780  }
781 
782  // move operator
783  template < typename Key, typename Alloc >
786  SequenceImplementation< Key, Alloc, true >&& aSeq) {
787  // avoid self assignment
788  if (&aSeq != this) {
789  _h_ = std::move(aSeq._h_);
790  _v_ = std::move(aSeq._v_);
791  _update_end_();
792  }
793 
794  return *this;
795  }
796 
797  // check the existence of k in the sequence
798  template < typename Key, typename Alloc >
799  INLINE bool SequenceImplementation< Key, Alloc, true >::exists(Key k) const {
800  return _h_.exists(k);
801  }
802 
803  // insert an element at the end of the sequence
804  template < typename Key, typename Alloc >
805  INLINE void SequenceImplementation< Key, Alloc, true >::insert(Key k) {
806  // k will be added at the end. Insert the new key into the hashtable
807  _h_.insert(k, _h_.size());
808  _v_.push_back(k);
809  _update_end_();
810  }
811 
812  // emplace a new element in the sequence
813  template < typename Key, typename Alloc >
814  template < typename... Args >
815  INLINE void SequenceImplementation< Key, Alloc, true >::emplace(Args&&... args) {
816  Key new_key(std::forward< Args >(args)...);
817  _h_.insert(new_key, _h_.size());
819  _update_end_();
820  }
821 
822  // insert k in the sequence (synonym for insert)
823  template < typename Key, typename Alloc >
825  SequenceImplementation< Key, Alloc, true >::operator<<(Key k) {
826  insert(k);
827  return *this;
828  }
829 
830  // remove an element from the sequence
831  template < typename Key, typename Alloc >
832  INLINE void SequenceImplementation< Key, Alloc, true >::erase(Key k) {
833  // get the position of the element to remove
834  Idx pos;
835 
836  try {
837  pos = _h_[k];
838  } catch (NotFound&) { return; }
839 
840  // erase the element
841  _v_.erase(_v_.begin() + pos);
842  for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
843  --_h_[_v_[i]];
844  }
845  _h_.erase(k);
846 
847  _update_end_();
848  }
849 
850  // remove from the sequence the element pointed to by the iterator
851  template < typename Key, typename Alloc >
852  INLINE void SequenceImplementation< Key, Alloc, true >::erase(const iterator_safe& iter) {
853  if (iter.pos() >= size()) return;
854 
855  // erase the element
856  Idx pos = iter.pos();
857  Key key = _v_[pos];
858  _v_.erase(_v_.begin() + pos);
859 
860  for (Idx i = pos, nb_elts = _h_.size() - 1; i < nb_elts; ++i) {
861  --_h_[_v_[i]];
862  }
863  _h_.erase(key);
864 
865  _update_end_();
866  }
867 
868  // remove k in the sequence (synonym for erase)
869  template < typename Key, typename Alloc >
871  SequenceImplementation< Key, Alloc, true >::operator>>(Key k) {
872  erase(k);
873  return *this;
874  }
875 
876  // returns the object at position i
877  template < typename Key, typename Alloc >
878  INLINE const Key& SequenceImplementation< Key, Alloc, true >::atPos(Idx i) const {
879  if (i >= _h_.size()) { GUM_ERROR(NotFound, "not enough elements in the sequence") }
880 
881  return _v_[i];
882  }
883 
884  // returns the element at position i (synonym for atPos)
885  template < typename Key, typename Alloc >
886  INLINE const Key& SequenceImplementation< Key, Alloc, true >::operator[](Idx i) const {
887  return atPos(i);
888  }
889 
890  // returns the position of the object passed in argument (if it exists)
891  template < typename Key, typename Alloc >
892  INLINE Idx SequenceImplementation< Key, Alloc, true >::pos(Key key) const {
893  return _h_[key];
894  }
895 
896  // sets the object at position i
897  template < typename Key, typename Alloc >
899  if (i >= _h_.size()) { GUM_ERROR(NotFound, "index too large") }
900 
901  _h_.insert(newKey, i);
902  _h_.erase(_v_[i]);
903  _v_[i] = newKey;
904  }
905 
906  // replace two elements in the sequence
907  template < typename Key, typename Alloc >
908  INLINE void SequenceImplementation< Key, Alloc, true >::swap(Idx i, Idx j) {
909  if (i == j) return;
910 
911  Key ki = atPos(i);
912  Key kj = atPos(j);
913 
914  _h_[ki] = j;
915  _h_[kj] = i;
916 
917  _v_[i] = kj;
918  _v_[j] = ki;
919  }
920 
921  // returns the first element
922  template < typename Key, typename Alloc >
923  INLINE const Key& SequenceImplementation< Key, Alloc, true >::front() const {
924  return atPos(0);
925  }
926 
927  // returns the last element
928  template < typename Key, typename Alloc >
929  INLINE const Key& SequenceImplementation< Key, Alloc, true >::back() const {
930  return atPos(size() - 1);
931  }
932 
933  // Print a sequence
934  template < typename Key, typename Alloc >
935  std::string SequenceImplementation< Key, Alloc, true >::toString() const {
937  stream << "[";
938 
939  if (!_h_.empty()) {
940  stream << 0 << ":" << _v_[0];
941 
942  for (Idx i = 1; i < _h_.size(); ++i) {
943  stream << " - " << i << ":" << _v_[i];
944  }
945  }
946 
947  stream << "]";
948 
949  std::string res = stream.str();
950  return res;
951  }
952 
953  // returns true if the content of k equals that of *this
954  template < typename Key, typename Alloc >
955  template < typename OtherAlloc >
957  const SequenceImplementation< Key, OtherAlloc, true >& k) const {
958  if (size() != k.size())
959  return false;
960  else {
961  for (Idx i = 0; i < size(); ++i)
962  if (_v_[i] != k._v_[i]) return false;
963  }
964 
965  return true;
966  }
967 
968  // returns true if the content of k is different from that of *this
969  template < typename Key, typename Alloc >
970  template < typename OtherAlloc >
972  const SequenceImplementation< Key, OtherAlloc, true >& k) const {
973  return !operator==(k);
974  }
975 
976  // a << operator for displaying the content of the Sequence
977  template < typename Key, typename Alloc >
979  const SequenceImplementation< Key, Alloc, true >& seq) {
980  stream << seq.toString();
981  return stream;
982  }
983 
984  // returns the safe begin iterator
985  template < typename Key, typename Alloc >
987  return SequenceIteratorSafe< Key >{*this};
988  }
989 
990  // return the safe end iterator
991  template < typename Key, typename Alloc >
993  SequenceImplementation< Key, Alloc, true >::endSafe() const noexcept {
994  return _end_safe_;
995  }
996 
997  // return an iterator pointing to the last element
998  template < typename Key, typename Alloc >
1000  SequenceImplementation< Key, Alloc, true >::rbeginSafe() const {
1001  SequenceIteratorSafe< Key > it{*this};
1002  it._setPos_(size() - 1);
1003  return it;
1004  }
1005 
1006  // returns an iterator pointing just before the first element
1007  template < typename Key, typename Alloc >
1008  INLINE const SequenceIteratorSafe< Key >&
1009  SequenceImplementation< Key, Alloc, true >::rendSafe() const noexcept {
1010  return _rend_safe_;
1011  }
1012 
1013  // returns the unsafe begin iterator
1014  template < typename Key, typename Alloc >
1016  return SequenceIterator< Key >{*this};
1017  }
1018 
1019  // return the unsafe end iterator
1020  template < typename Key, typename Alloc >
1021  INLINE const SequenceIterator< Key >&
1022  SequenceImplementation< Key, Alloc, true >::end() const noexcept {
1023  return _end_safe_;
1024  }
1025 
1026  // return an unsafe iterator pointing to the last element
1027  template < typename Key, typename Alloc >
1029  SequenceIterator< Key > it{*this};
1030  it._setPos_(size() - 1);
1031  return it;
1032  }
1033 
1034  // returns an unsafe iterator pointing just before the first element
1035  template < typename Key, typename Alloc >
1036  INLINE const SequenceIterator< Key >&
1037  SequenceImplementation< Key, Alloc, true >::rend() const noexcept {
1038  return _rend_safe_;
1039  }
1040 
1041  // modifies the size of the internal structures of the sequence
1042  template < typename Key, typename Alloc >
1044  if (new_size < _h_.size()) return;
1045 
1046  _h_.resize(new_size);
1047  _v_.reserve(new_size);
1048  }
1049 
1050  // ===========================================================================
1051  // Sequence
1052  // ===========================================================================
1053 
1054  // Default constructor
1055  template < typename Key, typename Alloc >
1059  }
1060 
1061  // initializer list constructor
1062  template < typename Key, typename Alloc >
1065  // for debugging purposes
1067  }
1068 
1069  // copy constructor
1070  template < typename Key, typename Alloc >
1073  // for debugging purposes
1075  }
1076 
1077  // generalized copy constructor
1078  template < typename Key, typename Alloc >
1079  template < typename OtherAlloc >
1082  // for debugging purposes
1084  }
1085 
1086  // move constructor
1087  template < typename Key, typename Alloc >
1090  // for debugging purposes
1092  }
1093 
1094  // destructor
1095  template < typename Key, typename Alloc >
1096  INLINE Sequence< Key, Alloc >::~Sequence() noexcept {
1097  // for debugging purposes
1099  }
1100 
1101  // copy operator
1102  template < typename Key, typename Alloc >
1103  INLINE Sequence< Key, Alloc >&
1106  return *this;
1107  }
1108 
1109  // generalized copy operator
1110  template < typename Key, typename Alloc >
1111  template < typename OtherAlloc >
1112  INLINE Sequence< Key, Alloc >&
1115  return *this;
1116  }
1117 
1118  // move operator
1119  template < typename Key, typename Alloc >
1122  return *this;
1123  }
1124 
1125  // returns the set difference : this \ seq
1126  template < typename Key, typename Alloc >
1127  template < typename OtherAlloc >
1128  Set< Key, Alloc > Sequence< Key, Alloc >::diffSet(const Sequence< Key, OtherAlloc >& seq) const {
1129  Set< Key, Alloc > res;
1130 
1131  for (iterator iter = this->begin(); iter != this->end(); ++iter) {
1132  if (!seq.exists(*iter)) res << *iter;
1133  }
1134 
1135  return res;
1136  }
1137 
1138  // a << operator for displaying the content of the Sequence
1139  template < typename Key, typename Alloc >
1141  stream << seq.toString();
1142  return stream;
1143  }
1144 
1145 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643