aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
sequence_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief 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__{reinterpret_cast<
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  const Sequence< Key, Alloc >& seq,
86  Idx pos) noexcept :
87  seq__{reinterpret_cast<
89  std::allocator< Key >,
90  std::is_scalar< Key >::value >* >(&seq)} {
92 
93  if (pos > seq__->size())
94  iterator__ = seq__->size(); // make the iterator point to end
95  else
96  iterator__ = pos;
97  }
98 
99  // copy constructor
100  template < typename Key >
102  const SequenceIteratorSafe< Key >& source) noexcept :
104  seq__{source.seq__} {
106  }
107 
108  // move constructor
109  template < typename Key >
111  SequenceIteratorSafe< Key >&& source) noexcept :
113  seq__{source.seq__} {
115  }
116 
117  // destructor
118  template < typename Key >
121  }
122 
123  // copy operator
124  template < typename Key >
126  const SequenceIteratorSafe< Key >& source) noexcept {
128  seq__ = source.seq__;
129  return *this;
130  }
131 
132  // move operator
133  template < typename Key >
135  SequenceIteratorSafe< Key >&& source) noexcept {
137  seq__ = source.seq__;
138  return *this;
139  }
140 
141  // point the iterator to the next value in the sequence
142  template < typename Key >
144  SequenceIteratorSafe< Key >::operator++() noexcept {
145  if (iterator__ < seq__->size())
146  ++iterator__;
147  else
148  iterator__ = seq__->size();
149 
150  return *this;
151  }
152 
153  // point the iterator to the preceding value in the sequence
154  template < typename Key >
156  SequenceIteratorSafe< Key >::operator--() noexcept {
157  if (iterator__ != std::numeric_limits< Idx >::max()) --iterator__;
158 
159  return *this;
160  }
161 
162  // makes the iterator point to i elements further in the sequence
163  template < typename Key >
166  if (iterator__ == std::numeric_limits< Idx >::max()) return *this;
167  iterator__ += nb;
168  if (iterator__ > seq__->size()) iterator__ = seq__->size();
169 
170  return *this;
171  }
172 
173  // makes the iterator point to i elements further in the sequence
174  template < typename Key >
177  if (iterator__ == std::numeric_limits< Idx >::max()) return *this;
178  iterator__ -= nb;
180 
181  return *this;
182  }
183 
184  // returns a new iterator
185  template < typename Key >
188  return SequenceIteratorSafe< Key >{*this} += nb;
189  }
190 
191  // returns a new iterator
192  template < typename Key >
195  return SequenceIteratorSafe< Key >{*this} -= nb;
196  }
197 
198  // checks whether two iterators are pointing to the same element
199  template < typename Key >
201  const SequenceIteratorSafe< Key >& source) const noexcept {
202  if (seq__->empty())
203  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  }
223 
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())
231  iterator__ = seq__->size();
232  else
233  iterator__ = pos;
234  }
235 
236  // the iterator points to the posth element (0 = beginning of the sequence).
237  template < typename Key >
240  }
241 
242  // the iterator points to the posth element (0 = beginning of the sequence).
243  template < typename Key >
245  iterator__ = seq__->size();
246  }
247 
248  // returns the value pointed to by the iterator
249  template < typename Key >
251  return Getter::op_star(seq__->v__[pos()]);
252  }
253 
254  // dereferences the value pointed to by the iterator
255  template < typename Key >
256  INLINE const Key* SequenceIteratorSafe< Key >::operator->() const {
257  return Getter::op_arrow(seq__->v__[pos()]);
258  }
259 
260  // ===========================================================================
261  // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
262  // ===========================================================================
263 
264  // updates const iterators
265  template < typename Key, typename Alloc, bool Gen >
268  }
269 
270  // clear the sequence
271  template < typename Key, typename Alloc, bool Gen >
273  h__.clear();
274  v__.clear();
275  update_end__();
276  }
277 
278  // clears the current sequence and fill it with copies the element of aSeq
279  template < typename Key, typename Alloc, bool Gen >
280  template < typename OtherAlloc >
283  clear();
284 
285  for (Size i = 0; i < aSeq.size(); ++i) {
286  Key& new_key = const_cast< Key& >(h__.insert(*(aSeq.v__[i]), i).first);
288  }
289 
290  update_end__();
291  }
292 
293  // Default constructor
294  template < typename Key, typename Alloc, bool Gen >
296  Size size_param) :
297  h__(size_param),
298  end_safe__{*this}, rend_safe__{*this} {
299  // for debugging purposes
302  update_end__();
303  }
304 
305  // initializer list constructor
306  template < typename Key, typename Alloc, bool Gen >
309  end_safe__{*this},
310  rend_safe__{*this} {
313  for (const auto& elt: list) {
314  insert(elt); // performs the update_end__ ()
315  }
316  }
317 
318  // copy constructor
319  template < typename Key, typename Alloc, bool Gen >
321  const SequenceImplementation< Key, Alloc, Gen >& aSeq) :
322  end_safe__{*this},
323  rend_safe__{*this} {
324  // for debugging purposes
327  copy__(aSeq); // performs the update_end__ ()
328  }
329 
330  // generalized copy constructor
331  template < typename Key, typename Alloc, bool Gen >
332  template < typename OtherAlloc >
335  end_safe__{*this},
336  rend_safe__{*this} {
337  // for debugging purposes
340  copy__(aSeq); // performs the update_end__ ()
341  }
342 
343  // move constructor
344  template < typename Key, typename Alloc, bool Gen >
347  h__(std::move(aSeq.h__)),
348  v__(std::move(aSeq.v__)), end_safe__{*this}, rend_safe__{*this} {
349  // for debugging purposes
352  update_end__();
353  }
354 
355  // destructor
356  template < typename Key, typename Alloc, bool Gen >
360  }
361 
362  // copy operator
363  template < typename Key, typename Alloc, bool Gen >
366  const SequenceImplementation< Key, Alloc, Gen >& aSeq) {
367  // avoid self assignment
368  if (&aSeq != this) {
369  copy__(aSeq); // performs the update_end__ ()
370  }
371 
372  return *this;
373  }
374 
375  // generalized copy operator
376  template < typename Key, typename Alloc, bool Gen >
377  template < typename OtherAlloc >
381  copy__(aSeq); // performs the update_end__ ()
382  return *this;
383  }
384 
385  // move operator
386  template < typename Key, typename Alloc, bool Gen >
390  // avoid self assignment
391  if (&aSeq != this) {
392  h__ = std::move(aSeq.h__);
393  v__ = std::move(aSeq.v__);
394  update_end__();
395  }
396 
397  return *this;
398  }
399 
400  // check the existence of k in the sequence
401  template < typename Key, typename Alloc, bool Gen >
402  INLINE bool
404  return h__.exists(k);
405  }
406 
407  // insert an element at the end of the sequence
408  template < typename Key, typename Alloc, bool Gen >
410  // k will be added at the end. Insert the new key into the hashtable
411  Key& new_key = const_cast< Key& >(h__.insert(k, h__.size()).first);
413  update_end__();
414  }
415 
416  // insert an element at the end of the sequence
417  template < typename Key, typename Alloc, bool Gen >
419  // k will be added at the end. Insert the new key into the hashtable
420  Key& new_key = const_cast< Key& >(h__.insert(std::move(k), h__.size()).first);
422  update_end__();
423  }
424 
425  // emplace a new element in the sequence
426  template < typename Key, typename Alloc, bool Gen >
427  template < typename... Args >
429  Key key(std::forward< Args >(args)...);
430  Key& new_key
431  = const_cast< Key& >(h__.insert(std::move(key), h__.size()).first);
433  update_end__();
434  }
435 
436  // insert k in the sequence (synonym for insert)
437  template < typename Key, typename Alloc, bool Gen >
440  insert(k);
441  return *this;
442  }
443 
444  // insert k in the sequence (synonym for insert)
445  template < typename Key, typename Alloc, bool Gen >
448  insert(std::move(k));
449  return *this;
450  }
451 
452  // remove an element from the sequence
453  template < typename Key, typename Alloc, bool Gen >
455  // get the position of the element to remove
456  Idx pos;
457 
458  try {
459  pos = h__[k];
460  } catch (NotFound&) { return; }
461 
462  // erase the element
463  v__.erase(v__.begin() + pos);
464  for (Idx i = pos, nb_elts = h__.size() - 1; i < nb_elts; ++i) {
465  --h__[*(v__[i])];
466  }
467  h__.erase(k);
468 
469  update_end__();
470  }
471 
472  // remove from the sequence the element pointed to by the iterator
473  template < typename Key, typename Alloc, bool Gen >
474  INLINE void
476  if (iter.pos() >= size()) return;
477 
478  // erase the element
479  Idx pos = iter.pos();
480  Key* key = v__[pos];
481  v__.erase(v__.begin() + pos);
482 
483  for (Idx i = pos, nb_elts = h__.size() - 1; i < nb_elts; ++i) {
484  --h__[*(v__[i])];
485  }
486  h__.erase(*key);
487 
488  update_end__();
489  }
490 
491  // remove k in the sequence (synonym for erase)
492  template < typename Key, typename Alloc, bool Gen >
495  erase(k);
496  return *this;
497  }
498 
499  // returns the object at position i ( first elt = index 0 )
500  template < typename Key, typename Alloc, bool Gen >
502  if (i >= h__.size()) {
504  "index " << i << " for a sequence of size" << h__.size());
505  }
506 
507  return *(v__[i]);
508  }
509 
510  // returns the element at position i (synonym for atPos)
511  template < typename Key, typename Alloc, bool Gen >
512  INLINE const Key&
514  return atPos(i);
515  }
516 
517  // returns the position of the object passed in argument (if it exists)
518  template < typename Key, typename Alloc, bool Gen >
520  return h__[key];
521  }
522 
523  // inserts and returns the object at the pos i
524  template < typename Key, typename Alloc, bool Gen >
525  INLINE void
527  const Key& newKey) {
528  if (i >= h__.size()) { GUM_ERROR(NotFound, "index too large"); }
529 
530  Key& new_key = const_cast< Key& >(h__.insert(newKey, i).first);
531  h__.erase(*(v__[i]));
532  v__[i] = &new_key;
533  }
534 
535  // inserts and returns the object at the pos i
536  template < typename Key, typename Alloc, bool Gen >
538  Key&& newKey) {
539  if (i >= h__.size()) { GUM_ERROR(NotFound, "index too large"); }
540 
541  Key& new_key = const_cast< Key& >(h__.insert(std::move(newKey), i).first);
542  h__.erase(*(v__[i]));
543  v__[i] = &new_key;
544  }
545 
546  // replace two elements in the sequence
547  template < typename Key, typename Alloc, bool Gen >
549  if (i == j) return;
550 
551  Key& ki = const_cast< Key& >(atPos(i));
552  Key& kj = const_cast< Key& >(atPos(j));
553 
554  h__[ki] = j;
555  h__[kj] = i;
556 
557  v__[i] = &kj;
558  v__[j] = &ki;
559  }
560 
561  // returns the first element
562  template < typename Key, typename Alloc, bool Gen >
564  return atPos(0);
565  }
566 
567  // returns the last element
568  template < typename Key, typename Alloc, bool Gen >
570  return atPos(size() - 1);
571  }
572 
573  // Print a sequence
574  template < typename Key, typename Alloc, bool Gen >
577  stream << "[";
578 
579  if (!h__.empty()) {
580  stream << 0 << ":" << *v__[0];
581 
582  for (Idx i = 1; i < h__.size(); ++i) {
583  stream << " - " << i << ":" << *v__[i];
584  }
585  }
586 
587  stream << "]";
588 
589  std::string res = stream.str();
590  return res;
591  }
592 
593  // returns true if the content of k equals that of *this
594  template < typename Key, typename Alloc, bool Gen >
595  template < typename OtherAlloc >
597  const SequenceImplementation< Key, OtherAlloc, Gen >& k) const {
598  if (size() != k.size())
599  return false;
600  else {
601  for (Idx i = 0; i < size(); ++i)
602  if (*v__[i] != *(k.v__[i])) return false;
603  }
604 
605  return true;
606  }
607 
608  // returns true if the content of k is different from that of *this
609  template < typename Key, typename Alloc, bool Gen >
610  template < typename OtherAlloc >
612  const SequenceImplementation< Key, OtherAlloc, Gen >& k) const {
613  return !operator==(k);
614  }
615 
616  // a << operator for displaying the content of the Sequence
617  template < typename Key, typename Alloc, bool Gen >
618  INLINE std::ostream&
620  const SequenceImplementation< Key, Alloc, Gen >& seq) {
621  stream << seq.toString();
622  return stream;
623  }
624 
625  // returns the safe begin iterator
626  template < typename Key, typename Alloc, bool Gen >
629  return SequenceIteratorSafe< Key >{*this};
630  }
631 
632  // returns the safe end iterator
633  template < typename Key, typename Alloc, bool Gen >
635  SequenceImplementation< Key, Alloc, Gen >::endSafe() const noexcept {
636  return end_safe__;
637  }
638 
639  // return an iterator pointing to the last element
640  template < typename Key, typename Alloc, bool Gen >
643  SequenceIteratorSafe< Key > it{*this};
644  it.setPos__(size() - 1);
645  return it;
646  }
647 
648  // returns an iterator pointing just before the first element
649  template < typename Key, typename Alloc, bool Gen >
651  SequenceImplementation< Key, Alloc, Gen >::rendSafe() const noexcept {
652  return rend_safe__;
653  }
654 
655  // returns the unsafe begin iterator
656  template < typename Key, typename Alloc, bool Gen >
659  return SequenceIterator< Key >{*this};
660  }
661 
662  // returns the unsafe end iterator
663  template < typename Key, typename Alloc, bool Gen >
664  INLINE const SequenceIterator< Key >&
665  SequenceImplementation< Key, Alloc, Gen >::end() const noexcept {
666  return end_safe__;
667  }
668 
669  // return an iterator pointing to the last element
670  template < typename Key, typename Alloc, bool Gen >
673  SequenceIterator< Key > it{*this};
674  it.setPos__(size() - 1);
675  return it;
676  }
677 
678  // returns an iterator pointing just before the first element
679  template < typename Key, typename Alloc, bool Gen >
680  INLINE const SequenceIterator< Key >&
681  SequenceImplementation< Key, Alloc, Gen >::rend() const noexcept {
682  return rend_safe__;
683  }
684 
685  // modifies the size of the internal structures of the sequence
686  template < typename Key, typename Alloc, bool Gen >
688  if (new_size < h__.size()) return;
689 
692  }
693 
694  // ===========================================================================
695  // === SCALAR GUM SEQUENCE IMPLEMENTATION ===
696  // ===========================================================================
697 
698  // updates the end iterators
699  template < typename Key, typename Alloc >
700  INLINE void SequenceImplementation< Key, Alloc, true >::update_end__() noexcept {
702  }
703 
704  // clear the sequence
705  template < typename Key, typename Alloc >
706  INLINE void SequenceImplementation< Key, Alloc, true >::clear() {
707  h__.clear();
708  v__.clear();
709  update_end__();
710  }
711 
712  // clears the current sequence and fill it with copies the element of aSeq
713  template < typename Key, typename Alloc >
714  template < typename OtherAlloc >
716  const SequenceImplementation< Key, OtherAlloc, true >& aSeq) {
717  clear();
718 
719  for (Size i = 0; i < aSeq.size(); ++i) {
720  h__.insert(aSeq.v__[i], i);
721  v__.push_back(aSeq.v__[i]);
722  }
723 
724  update_end__();
725  }
726 
727  // Default constructor
728  template < typename Key, typename Alloc >
730  Size size_param) :
731  h__(size_param),
732  end_safe__{*this}, rend_safe__{*this} {
733  // for debugging purposes
737  }
738 
739  // initializer list constructor
740  template < typename Key, typename Alloc >
743  end_safe__{*this},
744  rend_safe__{*this} {
747  for (const auto& elt: list) {
748  insert(elt);
749  }
750  }
751 
752  // copy constructor
753  template < typename Key, typename Alloc >
755  const SequenceImplementation< Key, Alloc, true >& aSeq) :
756  h__(aSeq.h__),
757  v__(aSeq.v__), end_safe__{*this}, rend_safe__{*this} {
758  // for debugging purposes
762  }
763 
764  // generalized copy constructor
765  template < typename Key, typename Alloc >
766  template < typename OtherAlloc >
768  const SequenceImplementation< Key, OtherAlloc, true >& aSeq) :
769  h__(aSeq.size() / 2),
770  end_safe__{*this}, rend_safe__{*this} {
771  // for debugging purposes
774  copy__(aSeq);
775  }
776 
777  // move constructor
778  template < typename Key, typename Alloc >
780  SequenceImplementation< Key, Alloc, true >&& aSeq) :
781  h__(std::move(aSeq.h__)),
782  v__(std::move(aSeq.v__)), end_safe__{*this}, rend_safe__{*this} {
783  // for debugging purposes
787  }
788 
789  // destructor
790  template < typename Key, typename Alloc >
791  SequenceImplementation< Key, Alloc, true >::~SequenceImplementation() noexcept {
793  }
794 
795  // copy operator
796  template < typename Key, typename Alloc >
799  const SequenceImplementation< Key, Alloc, true >& aSeq) {
800  // avoid self assignment
801  if (&aSeq != this) { copy__(aSeq); }
802 
803  return *this;
804  }
805 
806  // generalized copy operator
807  template < typename Key, typename Alloc >
808  template < typename OtherAlloc >
811  const SequenceImplementation< Key, OtherAlloc, true >& aSeq) {
812  copy__(aSeq);
813  return *this;
814  }
815 
816  // move operator
817  template < typename Key, typename Alloc >
820  SequenceImplementation< Key, Alloc, true >&& aSeq) {
821  // avoid self assignment
822  if (&aSeq != this) {
823  h__ = std::move(aSeq.h__);
824  v__ = std::move(aSeq.v__);
825  update_end__();
826  }
827 
828  return *this;
829  }
830 
831  // check the existence of k in the sequence
832  template < typename Key, typename Alloc >
833  INLINE bool SequenceImplementation< Key, Alloc, true >::exists(Key k) const {
834  return h__.exists(k);
835  }
836 
837  // insert an element at the end of the sequence
838  template < typename Key, typename Alloc >
839  INLINE void SequenceImplementation< Key, Alloc, true >::insert(Key k) {
840  // k will be added at the end. Insert the new key into the hashtable
841  h__.insert(k, h__.size());
842  v__.push_back(k);
843  update_end__();
844  }
845 
846  // emplace a new element in the sequence
847  template < typename Key, typename Alloc >
848  template < typename... Args >
849  INLINE void SequenceImplementation< Key, Alloc, true >::emplace(Args&&... args) {
850  Key new_key(std::forward< Args >(args)...);
851  h__.insert(new_key, h__.size());
853  update_end__();
854  }
855 
856  // insert k in the sequence (synonym for insert)
857  template < typename Key, typename Alloc >
859  SequenceImplementation< Key, Alloc, true >::operator<<(Key k) {
860  insert(k);
861  return *this;
862  }
863 
864  // remove an element from the sequence
865  template < typename Key, typename Alloc >
866  INLINE void SequenceImplementation< Key, Alloc, true >::erase(Key k) {
867  // get the position of the element to remove
868  Idx pos;
869 
870  try {
871  pos = h__[k];
872  } catch (NotFound&) { return; }
873 
874  // erase the element
875  v__.erase(v__.begin() + pos);
876  for (Idx i = pos, nb_elts = h__.size() - 1; i < nb_elts; ++i) {
877  --h__[v__[i]];
878  }
879  h__.erase(k);
880 
881  update_end__();
882  }
883 
884  // remove from the sequence the element pointed to by the iterator
885  template < typename Key, typename Alloc >
886  INLINE void
888  if (iter.pos() >= size()) return;
889 
890  // erase the element
891  Idx pos = iter.pos();
892  Key key = v__[pos];
893  v__.erase(v__.begin() + pos);
894 
895  for (Idx i = pos, nb_elts = h__.size() - 1; i < nb_elts; ++i) {
896  --h__[v__[i]];
897  }
898  h__.erase(key);
899 
900  update_end__();
901  }
902 
903  // remove k in the sequence (synonym for erase)
904  template < typename Key, typename Alloc >
906  SequenceImplementation< Key, Alloc, true >::operator>>(Key k) {
907  erase(k);
908  return *this;
909  }
910 
911  // returns the object at position i
912  template < typename Key, typename Alloc >
913  INLINE const Key&
914  SequenceImplementation< Key, Alloc, true >::atPos(Idx i) const {
915  if (i >= h__.size()) {
916  GUM_ERROR(NotFound, "not enough elements in the sequence");
917  }
918 
919  return v__[i];
920  }
921 
922  // returns the element at position i (synonym for atPos)
923  template < typename Key, typename Alloc >
924  INLINE const Key&
925  SequenceImplementation< Key, Alloc, true >::operator[](Idx i) const {
926  return atPos(i);
927  }
928 
929  // returns the position of the object passed in argument (if it exists)
930  template < typename Key, typename Alloc >
931  INLINE Idx SequenceImplementation< Key, Alloc, true >::pos(Key key) const {
932  return h__[key];
933  }
934 
935  // sets the object at position i
936  template < typename Key, typename Alloc >
938  Key newKey) {
939  if (i >= h__.size()) { GUM_ERROR(NotFound, "index too large"); }
940 
941  h__.insert(newKey, i);
942  h__.erase(v__[i]);
943  v__[i] = newKey;
944  }
945 
946  // replace two elements in the sequence
947  template < typename Key, typename Alloc >
948  INLINE void SequenceImplementation< Key, Alloc, true >::swap(Idx i, Idx j) {
949  if (i == j) return;
950 
951  Key ki = atPos(i);
952  Key kj = atPos(j);
953 
954  h__[ki] = j;
955  h__[kj] = i;
956 
957  v__[i] = kj;
958  v__[j] = ki;
959  }
960 
961  // returns the first element
962  template < typename Key, typename Alloc >
963  INLINE const Key& SequenceImplementation< Key, Alloc, true >::front() const {
964  return atPos(0);
965  }
966 
967  // returns the last element
968  template < typename Key, typename Alloc >
969  INLINE const Key& SequenceImplementation< Key, Alloc, true >::back() const {
970  return atPos(size() - 1);
971  }
972 
973  // Print a sequence
974  template < typename Key, typename Alloc >
975  std::string SequenceImplementation< Key, Alloc, true >::toString() const {
977  stream << "[";
978 
979  if (!h__.empty()) {
980  stream << 0 << ":" << v__[0];
981 
982  for (Idx i = 1; i < h__.size(); ++i) {
983  stream << " - " << i << ":" << v__[i];
984  }
985  }
986 
987  stream << "]";
988 
989  std::string res = stream.str();
990  return res;
991  }
992 
993  // returns true if the content of k equals that of *this
994  template < typename Key, typename Alloc >
995  template < typename OtherAlloc >
997  const SequenceImplementation< Key, OtherAlloc, true >& k) const {
998  if (size() != k.size())
999  return false;
1000  else {
1001  for (Idx i = 0; i < size(); ++i)
1002  if (v__[i] != k.v__[i]) return false;
1003  }
1004 
1005  return true;
1006  }
1007 
1008  // returns true if the content of k is different from that of *this
1009  template < typename Key, typename Alloc >
1010  template < typename OtherAlloc >
1012  const SequenceImplementation< Key, OtherAlloc, true >& k) const {
1013  return !operator==(k);
1014  }
1015 
1016  // a << operator for displaying the content of the Sequence
1017  template < typename Key, typename Alloc >
1018  INLINE std::ostream&
1020  const SequenceImplementation< Key, Alloc, true >& seq) {
1021  stream << seq.toString();
1022  return stream;
1023  }
1024 
1025  // returns the safe begin iterator
1026  template < typename Key, typename Alloc >
1028  SequenceImplementation< Key, Alloc, true >::beginSafe() const {
1029  return SequenceIteratorSafe< Key >{*this};
1030  }
1031 
1032  // return the safe end iterator
1033  template < typename Key, typename Alloc >
1034  INLINE const SequenceIteratorSafe< Key >&
1035  SequenceImplementation< Key, Alloc, true >::endSafe() const noexcept {
1036  return end_safe__;
1037  }
1038 
1039  // return an iterator pointing to the last element
1040  template < typename Key, typename Alloc >
1042  SequenceImplementation< Key, Alloc, true >::rbeginSafe() const {
1043  SequenceIteratorSafe< Key > it{*this};
1044  it.setPos__(size() - 1);
1045  return it;
1046  }
1047 
1048  // returns an iterator pointing just before the first element
1049  template < typename Key, typename Alloc >
1050  INLINE const SequenceIteratorSafe< Key >&
1051  SequenceImplementation< Key, Alloc, true >::rendSafe() const noexcept {
1052  return rend_safe__;
1053  }
1054 
1055  // returns the unsafe begin iterator
1056  template < typename Key, typename Alloc >
1058  SequenceImplementation< Key, Alloc, true >::begin() const {
1059  return SequenceIterator< Key >{*this};
1060  }
1061 
1062  // return the unsafe end iterator
1063  template < typename Key, typename Alloc >
1064  INLINE const SequenceIterator< Key >&
1065  SequenceImplementation< Key, Alloc, true >::end() const noexcept {
1066  return end_safe__;
1067  }
1068 
1069  // return an unsafe iterator pointing to the last element
1070  template < typename Key, typename Alloc >
1072  SequenceImplementation< Key, Alloc, true >::rbegin() const {
1073  SequenceIterator< Key > it{*this};
1074  it.setPos__(size() - 1);
1075  return it;
1076  }
1077 
1078  // returns an unsafe iterator pointing just before the first element
1079  template < typename Key, typename Alloc >
1080  INLINE const SequenceIterator< Key >&
1081  SequenceImplementation< Key, Alloc, true >::rend() const noexcept {
1082  return rend_safe__;
1083  }
1084 
1085  // modifies the size of the internal structures of the sequence
1086  template < typename Key, typename Alloc >
1088  if (new_size < h__.size()) return;
1089 
1090  h__.resize(new_size);
1091  v__.reserve(new_size);
1092  }
1093 
1094  // ===========================================================================
1095  // Sequence
1096  // ===========================================================================
1097 
1098  // Default constructor
1099  template < typename Key, typename Alloc >
1102  size_param) {
1103  // for debugging purposes
1105  }
1106 
1107  // initializer list constructor
1108  template < typename Key, typename Alloc >
1111  // for debugging purposes
1113  }
1114 
1115  // copy constructor
1116  template < typename Key, typename Alloc >
1119  // for debugging purposes
1121  }
1122 
1123  // generalized copy constructor
1124  template < typename Key, typename Alloc >
1125  template < typename OtherAlloc >
1126  INLINE
1129  // for debugging purposes
1131  }
1132 
1133  // move constructor
1134  template < typename Key, typename Alloc >
1137  std::move(aSeq)) {
1138  // for debugging purposes
1140  }
1141 
1142  // destructor
1143  template < typename Key, typename Alloc >
1144  INLINE Sequence< Key, Alloc >::~Sequence() noexcept {
1145  // for debugging purposes
1147  }
1148 
1149  // copy operator
1150  template < typename Key, typename Alloc >
1151  INLINE Sequence< Key, Alloc >&
1154  return *this;
1155  }
1156 
1157  // generalized copy operator
1158  template < typename Key, typename Alloc >
1159  template < typename OtherAlloc >
1160  INLINE Sequence< Key, Alloc >&
1163  return *this;
1164  }
1165 
1166  // move operator
1167  template < typename Key, typename Alloc >
1168  INLINE Sequence< Key, Alloc >&
1171  return *this;
1172  }
1173 
1174  // returns the set difference : this \ seq
1175  template < typename Key, typename Alloc >
1176  template < typename OtherAlloc >
1178  const Sequence< Key, OtherAlloc >& seq) const {
1179  Set< Key, Alloc > res;
1180 
1181  for (iterator iter = this->begin(); iter != this->end(); ++iter) {
1182  if (!seq.exists(*iter)) res << *iter;
1183  }
1184 
1185  return res;
1186  }
1187 
1188  // a << operator for displaying the content of the Sequence
1189  template < typename Key, typename Alloc >
1191  const Sequence< Key, Alloc >& seq) {
1192  stream << seq.toString();
1193  return stream;
1194  }
1195 
1196 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669