aGrUM  0.16.0
sequence_tpl.h
Go to the documentation of this file.
1 
31 // to ease IDE parser
32 #include <agrum/core/sequence.h>
33 
34 namespace gum {
35 
36  // returns the size of the sequence
37  template < typename Key, typename Alloc, bool Gen >
39  return __h.size();
40  }
41 
42  // return true if empty
43  template < typename Key, typename Alloc, bool Gen >
44  INLINE bool SequenceImplementation< Key, Alloc, Gen >::empty() const noexcept {
45  return __h.empty();
46  }
47 
48  // returns the size of the sequence
49  template < typename Key, typename Alloc >
51  return __h.size();
52  }
53 
54  // return true if empty
55  template < typename Key, typename Alloc >
56  INLINE bool SequenceImplementation< Key, Alloc, true >::empty() const noexcept {
57  return __h.empty();
58  }
59 
60  // ===========================================================================
61  // class SequenceIteratorSafe
62  // ===========================================================================
63 
64  // default constructor
65  template < typename Key >
66  template < typename Alloc, bool Gen >
68  const SequenceImplementation< Key, Alloc, Gen >& seq, Idx pos) noexcept :
69  __seq{reinterpret_cast<
70  const SequenceImplementation< Key,
71  std::allocator< Key >,
72  std::is_scalar< Key >::value >* >(&seq)} {
73  GUM_CONSTRUCTOR(SequenceIteratorSafe);
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, Idx pos) noexcept :
86  __seq{reinterpret_cast<
87  const SequenceImplementation< Key,
88  std::allocator< Key >,
89  std::is_scalar< Key >::value >* >(&seq)} {
90  GUM_CONSTRUCTOR(SequenceIteratorSafe);
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 :
102  __iterator{source.__iterator},
103  __seq{source.__seq} {
104  GUM_CONS_CPY(SequenceIteratorSafe);
105  }
106 
107  // move constructor
108  template < typename Key >
110  SequenceIteratorSafe< Key >&& source) noexcept :
111  __iterator{source.__iterator},
112  __seq{source.__seq} {
113  GUM_CONS_MOV(SequenceIteratorSafe);
114  }
115 
116  // destructor
117  template < typename Key >
119  GUM_DESTRUCTOR(SequenceIteratorSafe);
120  }
121 
122  // copy operator
123  template < typename Key >
125  operator=(const SequenceIteratorSafe< Key >& source) noexcept {
126  __iterator = source.__iterator;
127  __seq = source.__seq;
128  return *this;
129  }
130 
131  // move operator
132  template < typename Key >
135  __iterator = source.__iterator;
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  operator++() noexcept {
144  if (__iterator < __seq->size())
145  ++__iterator;
146  else
147  __iterator = __seq->size();
148 
149  return *this;
150  }
151 
152  // point the iterator to the preceding value in the sequence
153  template < typename Key >
155  operator--() noexcept {
156  if (__iterator != std::numeric_limits< Idx >::max()) --__iterator;
157 
158  return *this;
159  }
160 
161  // makes the iterator point to i elements further in the sequence
162  template < typename Key >
164  operator+=(Size nb) noexcept {
165  if (__iterator == std::numeric_limits< Idx >::max()) return *this;
166  __iterator += nb;
167  if (__iterator > __seq->size()) __iterator = __seq->size();
168 
169  return *this;
170  }
171 
172  // makes the iterator point to i elements further in the sequence
173  template < typename Key >
175  operator-=(Size nb) noexcept {
176  if (__iterator == std::numeric_limits< Idx >::max()) return *this;
177  __iterator -= nb;
178  if (__iterator > __seq->size()) __iterator = std::numeric_limits< Idx >::max();
179 
180  return *this;
181  }
182 
183  // returns a new iterator
184  template < typename Key >
186  operator+(Size nb) noexcept {
187  return SequenceIteratorSafe< Key >{*this} += nb;
188  }
189 
190  // returns a new iterator
191  template < typename Key >
193  operator-(Size nb) noexcept {
194  return SequenceIteratorSafe< Key >{*this} -= nb;
195  }
196 
197  // checks whether two iterators are pointing to the same element
198  template < typename Key >
200  operator==(const SequenceIteratorSafe< Key >& source) const noexcept {
201  if (__seq->empty())
202  return true; // all iterators are the same if seq is empty
203 
204  if ((__iterator != source.__iterator) || (__seq != source.__seq)) return false;
205 
206  return true;
207  }
208 
209  // checks whether two iterators are pointing to different elements
210  template < typename Key >
212  operator!=(const SequenceIteratorSafe< Key >& source) const noexcept {
213  return !operator==(source);
214  }
215 
216  // returns the position of the iterator in the sequence
217  template < typename Key >
219  if (__iterator >= __seq->size()) {
220  GUM_ERROR(UndefinedIteratorValue, "iterator is end() or rend()");
221  }
222 
223  return __iterator;
224  }
225 
226  // the iterator points to the posth element (0 = beginning of the sequence).
227  template < typename Key >
228  INLINE void SequenceIteratorSafe< Key >::__setPos(Idx pos) noexcept {
229  if (pos > __seq->size())
230  __iterator = __seq->size();
231  else
232  __iterator = pos;
233  }
234 
235  // the iterator points to the posth element (0 = beginning of the sequence).
236  template < typename Key >
238  __iterator = std::numeric_limits< Idx >::max();
239  }
240 
241  // the iterator points to the posth element (0 = beginning of the sequence).
242  template < typename Key >
244  __iterator = __seq->size();
245  }
246 
247  // returns the value pointed to by the iterator
248  template < typename Key >
249  INLINE const Key& SequenceIteratorSafe< Key >::operator*() const {
250  return Getter::op_star(__seq->__v[pos()]);
251  }
252 
253  // dereferences the value pointed to by the iterator
254  template < typename Key >
255  INLINE const Key* SequenceIteratorSafe< Key >::operator->() const {
256  return Getter::op_arrow(__seq->__v[pos()]);
257  }
258 
259  // ===========================================================================
260  // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
261  // ===========================================================================
262 
263  // updates const iterators
264  template < typename Key, typename Alloc, bool Gen >
266  __end_safe.__setAtEnd();
267  }
268 
269  // clear the sequence
270  template < typename Key, typename Alloc, bool Gen >
272  __h.clear();
273  __v.clear();
274  __update_end();
275  }
276 
277  // clears the current sequence and fill it with copies the element of aSeq
278  template < typename Key, typename Alloc, bool Gen >
279  template < typename OtherAlloc >
282  clear();
283 
284  for (Size i = 0; i < aSeq.size(); ++i) {
285  Key& new_key = const_cast< Key& >(__h.insert(*(aSeq.__v[i]), i).first);
286  __v.push_back(&new_key);
287  }
288 
289  __update_end();
290  }
291 
292  // Default constructor
293  template < typename Key, typename Alloc, bool Gen >
295  Size size_param) :
296  __h(size_param),
297  __end_safe{*this}, __rend_safe{*this} {
298  // for debugging purposes
299  GUM_CONSTRUCTOR(SequenceImplementation);
300  __rend_safe.__setAtRend();
301  __update_end();
302  }
303 
304  // initializer list constructor
305  template < typename Key, typename Alloc, bool Gen >
307  std::initializer_list< Key > list) :
308  __end_safe{*this},
309  __rend_safe{*this} {
310  GUM_CONSTRUCTOR(SequenceImplementation);
311  __rend_safe.__setAtRend();
312  for (const auto& elt : list) {
313  insert(elt); // performs the __update_end ()
314  }
315  }
316 
317  // copy constructor
318  template < typename Key, typename Alloc, bool Gen >
321  __end_safe{*this},
322  __rend_safe{*this} {
323  // for debugging purposes
324  GUM_CONS_CPY(SequenceImplementation);
325  __rend_safe.__setAtRend();
326  __copy(aSeq); // performs the __update_end ()
327  }
328 
329  // generalized copy constructor
330  template < typename Key, typename Alloc, bool Gen >
331  template < typename OtherAlloc >
334  __end_safe{*this},
335  __rend_safe{*this} {
336  // for debugging purposes
337  GUM_CONS_CPY(SequenceImplementation);
338  __rend_safe.__setAtRend();
339  __copy(aSeq); // performs the __update_end ()
340  }
341 
342  // move constructor
343  template < typename Key, typename Alloc, bool Gen >
346  __h(std::move(aSeq.__h)),
347  __v(std::move(aSeq.__v)), __end_safe{*this}, __rend_safe{*this} {
348  // for debugging purposes
349  GUM_CONS_MOV(SequenceImplementation);
350  __rend_safe.__setAtRend();
351  __update_end();
352  }
353 
354  // destructor
355  template < typename Key, typename Alloc, bool Gen >
358  GUM_DESTRUCTOR(SequenceImplementation);
359  }
360 
361  // copy operator
362  template < typename Key, typename Alloc, bool Gen >
366  // avoid self assignment
367  if (&aSeq != this) {
368  __copy(aSeq); // performs the __update_end ()
369  }
370 
371  return *this;
372  }
373 
374  // generalized copy operator
375  template < typename Key, typename Alloc, bool Gen >
376  template < typename OtherAlloc >
380  __copy(aSeq); // performs the __update_end ()
381  return *this;
382  }
383 
384  // move operator
385  template < typename Key, typename Alloc, bool Gen >
389  // avoid self assignment
390  if (&aSeq != this) {
391  __h = std::move(aSeq.__h);
392  __v = std::move(aSeq.__v);
393  __update_end();
394  }
395 
396  return *this;
397  }
398 
399  // check the existence of k in the sequence
400  template < typename Key, typename Alloc, bool Gen >
401  INLINE bool
403  return __h.exists(k);
404  }
405 
406  // insert an element at the end of the sequence
407  template < typename Key, typename Alloc, bool Gen >
409  // k will be added at the end. Insert the new key into the hashtable
410  Key& new_key = const_cast< Key& >(__h.insert(k, __h.size()).first);
411  __v.push_back(&new_key);
412  __update_end();
413  }
414 
415  // insert an element at the end of the sequence
416  template < typename Key, typename Alloc, bool Gen >
418  // k will be added at the end. Insert the new key into the hashtable
419  Key& new_key = const_cast< Key& >(__h.insert(std::move(k), __h.size()).first);
420  __v.push_back(&new_key);
421  __update_end();
422  }
423 
424  // emplace a new element in the sequence
425  template < typename Key, typename Alloc, bool Gen >
426  template < typename... Args >
428  Key key(std::forward< Args >(args)...);
429  Key& new_key =
430  const_cast< Key& >(__h.insert(std::move(key), __h.size()).first);
431  __v.push_back(&new_key);
432  __update_end();
433  }
434 
435  // insert k in the sequence (synonym for insert)
436  template < typename Key, typename Alloc, bool Gen >
439  insert(k);
440  return *this;
441  }
442 
443  // insert k in the sequence (synonym for insert)
444  template < typename Key, typename Alloc, bool Gen >
447  insert(std::move(k));
448  return *this;
449  }
450 
451  // remove an element from the sequence
452  template < typename Key, typename Alloc, bool Gen >
454  // get the position of the element to remove
455  Idx pos;
456 
457  try {
458  pos = __h[k];
459  } catch (NotFound&) { return; }
460 
461  // erase the element
462  __v.erase(__v.begin() + pos);
463  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
464  --__h[*(__v[i])];
465  }
466  __h.erase(k);
467 
468  __update_end();
469  }
470 
471  // remove from the sequence the element pointed to by the iterator
472  template < typename Key, typename Alloc, bool Gen >
473  INLINE void
475  if (iter.pos() >= size()) return;
476 
477  // erase the element
478  Idx pos = iter.pos();
479  Key* key = __v[pos];
480  __v.erase(__v.begin() + pos);
481 
482  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
483  --__h[*(__v[i])];
484  }
485  __h.erase(*key);
486 
487  __update_end();
488  }
489 
490  // remove k in the sequence (synonym for erase)
491  template < typename Key, typename Alloc, bool Gen >
494  erase(k);
495  return *this;
496  }
497 
498  // returns the object at position i ( first elt = index 0 )
499  template < typename Key, typename Alloc, bool Gen >
501  if (i >= __h.size()) {
503  "index " << i << " for a sequence of size" << __h.size());
504  }
505 
506  return *(__v[i]);
507  }
508 
509  // returns the element at position i (synonym for atPos)
510  template < typename Key, typename Alloc, bool Gen >
512  operator[](Idx i) const {
513  return atPos(i);
514  }
515 
516  // returns the position of the object passed in argument (if it exists)
517  template < typename Key, typename Alloc, bool Gen >
519  return __h[key];
520  }
521 
522  // inserts and returns the object at the pos i
523  template < typename Key, typename Alloc, bool Gen >
524  INLINE void
526  const Key& newKey) {
527  if (i >= __h.size()) { GUM_ERROR(NotFound, "index too large"); }
528 
529  Key& new_key = const_cast< Key& >(__h.insert(newKey, i).first);
530  __h.erase(*(__v[i]));
531  __v[i] = &new_key;
532  }
533 
534  // inserts and returns the object at the pos i
535  template < typename Key, typename Alloc, bool Gen >
537  Key&& newKey) {
538  if (i >= __h.size()) { GUM_ERROR(NotFound, "index too large"); }
539 
540  Key& new_key = const_cast< Key& >(__h.insert(std::move(newKey), i).first);
541  __h.erase(*(__v[i]));
542  __v[i] = &new_key;
543  }
544 
545  // replace two elements in the sequence
546  template < typename Key, typename Alloc, bool Gen >
548  if (i == j) return;
549 
550  Key& ki = const_cast< Key& >(atPos(i));
551  Key& kj = const_cast< Key& >(atPos(j));
552 
553  __h[ki] = j;
554  __h[kj] = i;
555 
556  __v[i] = &kj;
557  __v[j] = &ki;
558  }
559 
560  // returns the first element
561  template < typename Key, typename Alloc, bool Gen >
563  return atPos(0);
564  }
565 
566  // returns the last element
567  template < typename Key, typename Alloc, bool Gen >
569  return atPos(size() - 1);
570  }
571 
572  // Print a sequence
573  template < typename Key, typename Alloc, bool Gen >
575  std::stringstream stream;
576  stream << "[";
577 
578  if (!__h.empty()) {
579  stream << 0 << ":" << *__v[0];
580 
581  for (Idx i = 1; i < __h.size(); ++i) {
582  stream << " - " << i << ":" << *__v[i];
583  }
584  }
585 
586  stream << "]";
587 
588  std::string res = stream.str();
589  return res;
590  }
591 
592  // returns true if the content of k equals that of *this
593  template < typename Key, typename Alloc, bool Gen >
594  template < typename OtherAlloc >
597  if (size() != k.size())
598  return false;
599  else {
600  for (Idx i = 0; i < size(); ++i)
601  if (*__v[i] != *(k.__v[i])) return false;
602  }
603 
604  return true;
605  }
606 
607  // returns true if the content of k is different from that of *this
608  template < typename Key, typename Alloc, bool Gen >
609  template < typename OtherAlloc >
612  return !operator==(k);
613  }
614 
615  // a << operator for displaying the content of the Sequence
616  template < typename Key, typename Alloc, bool Gen >
617  INLINE std::ostream&
618  operator<<(std::ostream& stream,
620  stream << seq.toString();
621  return stream;
622  }
623 
624  // returns the safe begin iterator
625  template < typename Key, typename Alloc, bool Gen >
628  return SequenceIteratorSafe< Key >{*this};
629  }
630 
631  // returns the safe end iterator
632  template < typename Key, typename Alloc, bool Gen >
633  INLINE const SequenceIteratorSafe< Key >&
635  return __end_safe;
636  }
637 
638  // return an iterator pointing to the last element
639  template < typename Key, typename Alloc, bool Gen >
642  SequenceIteratorSafe< Key > it{*this};
643  it.__setPos(size() - 1);
644  return it;
645  }
646 
647  // returns an iterator pointing just before the first element
648  template < typename Key, typename Alloc, bool Gen >
649  INLINE const SequenceIteratorSafe< Key >&
651  return __rend_safe;
652  }
653 
654  // returns the unsafe begin iterator
655  template < typename Key, typename Alloc, bool Gen >
656  INLINE SequenceIterator< Key >
658  return SequenceIterator< Key >{*this};
659  }
660 
661  // returns the unsafe end iterator
662  template < typename Key, typename Alloc, bool Gen >
663  INLINE const SequenceIterator< Key >&
665  return __end_safe;
666  }
667 
668  // return an iterator pointing to the last element
669  template < typename Key, typename Alloc, bool Gen >
670  INLINE SequenceIterator< Key >
672  SequenceIterator< Key > it{*this};
673  it.__setPos(size() - 1);
674  return it;
675  }
676 
677  // returns an iterator pointing just before the first element
678  template < typename Key, typename Alloc, bool Gen >
679  INLINE const SequenceIterator< Key >&
681  return __rend_safe;
682  }
683 
684  // modifies the size of the internal structures of the sequence
685  template < typename Key, typename Alloc, bool Gen >
687  if (new_size < __h.size()) return;
688 
689  __h.resize(new_size);
690  __v.reserve(new_size);
691  }
692 
693  // ===========================================================================
694  // === SCALAR GUM SEQUENCE IMPLEMENTATION ===
695  // ===========================================================================
696 
697  // updates the end iterators
698  template < typename Key, typename Alloc >
700  __end_safe.__setAtEnd();
701  }
702 
703  // clear the sequence
704  template < typename Key, typename Alloc >
706  __h.clear();
707  __v.clear();
708  __update_end();
709  }
710 
711  // clears the current sequence and fill it with copies the element of aSeq
712  template < typename Key, typename Alloc >
713  template < typename OtherAlloc >
716  clear();
717 
718  for (Size i = 0; i < aSeq.size(); ++i) {
719  __h.insert(aSeq.__v[i], i);
720  __v.push_back(aSeq.__v[i]);
721  }
722 
723  __update_end();
724  }
725 
726  // Default constructor
727  template < typename Key, typename Alloc >
729  Size size_param) :
730  __h(size_param),
731  __end_safe{*this}, __rend_safe{*this} {
732  // for debugging purposes
733  GUM_CONSTRUCTOR(SequenceImplementation);
734  __rend_safe.__setAtRend();
735  __end_safe.__setAtEnd();
736  }
737 
738  // initializer list constructor
739  template < typename Key, typename Alloc >
740  INLINE SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
741  std::initializer_list< Key > list) :
742  __end_safe{*this},
743  __rend_safe{*this} {
744  GUM_CONSTRUCTOR(SequenceImplementation);
745  __rend_safe.__setAtRend();
746  for (const auto& elt : list) {
747  insert(elt);
748  }
749  }
750 
751  // copy constructor
752  template < typename Key, typename Alloc >
753  SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
755  __h(aSeq.__h),
756  __v(aSeq.__v), __end_safe{*this}, __rend_safe{*this} {
757  // for debugging purposes
758  GUM_CONS_CPY(SequenceImplementation);
759  __rend_safe.__setAtRend();
760  __end_safe.__setAtEnd();
761  }
762 
763  // generalized copy constructor
764  template < typename Key, typename Alloc >
765  template < typename OtherAlloc >
766  SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
768  __h(aSeq.size() / 2),
769  __end_safe{*this}, __rend_safe{*this} {
770  // for debugging purposes
771  GUM_CONS_CPY(SequenceImplementation);
772  __rend_safe.__setAtRend();
773  __copy(aSeq);
774  }
775 
776  // move constructor
777  template < typename Key, typename Alloc >
778  INLINE SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
780  __h(std::move(aSeq.__h)),
781  __v(std::move(aSeq.__v)), __end_safe{*this}, __rend_safe{*this} {
782  // for debugging purposes
783  GUM_CONS_MOV(SequenceImplementation);
784  __rend_safe.__setAtRend();
785  __end_safe.__setAtEnd();
786  }
787 
788  // destructor
789  template < typename Key, typename Alloc >
791  GUM_DESTRUCTOR(SequenceImplementation);
792  }
793 
794  // copy operator
795  template < typename Key, typename Alloc >
799  // avoid self assignment
800  if (&aSeq != this) { __copy(aSeq); }
801 
802  return *this;
803  }
804 
805  // generalized copy operator
806  template < typename Key, typename Alloc >
807  template < typename OtherAlloc >
811  __copy(aSeq);
812  return *this;
813  }
814 
815  // move operator
816  template < typename Key, typename Alloc >
820  // avoid self assignment
821  if (&aSeq != this) {
822  __h = std::move(aSeq.__h);
823  __v = std::move(aSeq.__v);
824  __update_end();
825  }
826 
827  return *this;
828  }
829 
830  // check the existence of k in the sequence
831  template < typename Key, typename Alloc >
832  INLINE bool SequenceImplementation< Key, Alloc, true >::exists(Key k) const {
833  return __h.exists(k);
834  }
835 
836  // insert an element at the end of the sequence
837  template < typename Key, typename Alloc >
839  // k will be added at the end. Insert the new key into the hashtable
840  __h.insert(k, __h.size());
841  __v.push_back(k);
842  __update_end();
843  }
844 
845  // emplace a new element in the sequence
846  template < typename Key, typename Alloc >
847  template < typename... Args >
848  INLINE void SequenceImplementation< Key, Alloc, true >::emplace(Args&&... args) {
849  Key new_key(std::forward< Args >(args)...);
850  __h.insert(new_key, __h.size());
851  __v.push_back(new_key);
852  __update_end();
853  }
854 
855  // insert k in the sequence (synonym for insert)
856  template < typename Key, typename Alloc >
859  insert(k);
860  return *this;
861  }
862 
863  // remove an element from the sequence
864  template < typename Key, typename Alloc >
866  // get the position of the element to remove
867  Idx pos;
868 
869  try {
870  pos = __h[k];
871  } catch (NotFound&) { return; }
872 
873  // erase the element
874  __v.erase(__v.begin() + pos);
875  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
876  --__h[__v[i]];
877  }
878  __h.erase(k);
879 
880  __update_end();
881  }
882 
883  // remove from the sequence the element pointed to by the iterator
884  template < typename Key, typename Alloc >
885  INLINE void
887  if (iter.pos() >= size()) return;
888 
889  // erase the element
890  Idx pos = iter.pos();
891  Key key = __v[pos];
892  __v.erase(__v.begin() + pos);
893 
894  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
895  --__h[__v[i]];
896  }
897  __h.erase(key);
898 
899  __update_end();
900  }
901 
902  // remove k in the sequence (synonym for erase)
903  template < typename Key, typename Alloc >
906  erase(k);
907  return *this;
908  }
909 
910  // returns the object at position i
911  template < typename Key, typename Alloc >
912  INLINE const Key&
914  if (i >= __h.size()) {
915  GUM_ERROR(NotFound, "not enough elements in the sequence");
916  }
917 
918  return __v[i];
919  }
920 
921  // returns the element at position i (synonym for atPos)
922  template < typename Key, typename Alloc >
924  operator[](Idx i) const {
925  return atPos(i);
926  }
927 
928  // returns the position of the object passed in argument (if it exists)
929  template < typename Key, typename Alloc >
931  return __h[key];
932  }
933 
934  // sets the object at position i
935  template < typename Key, typename Alloc >
937  Key newKey) {
938  if (i >= __h.size()) { GUM_ERROR(NotFound, "index too large"); }
939 
940  __h.insert(newKey, i);
941  __h.erase(__v[i]);
942  __v[i] = newKey;
943  }
944 
945  // replace two elements in the sequence
946  template < typename Key, typename Alloc >
948  if (i == j) return;
949 
950  Key ki = atPos(i);
951  Key kj = atPos(j);
952 
953  __h[ki] = j;
954  __h[kj] = i;
955 
956  __v[i] = kj;
957  __v[j] = ki;
958  }
959 
960  // returns the first element
961  template < typename Key, typename Alloc >
962  INLINE const Key& SequenceImplementation< Key, Alloc, true >::front() const {
963  return atPos(0);
964  }
965 
966  // returns the last element
967  template < typename Key, typename Alloc >
968  INLINE const Key& SequenceImplementation< Key, Alloc, true >::back() const {
969  return atPos(size() - 1);
970  }
971 
972  // Print a sequence
973  template < typename Key, typename Alloc >
975  std::stringstream stream;
976  stream << "[";
977 
978  if (!__h.empty()) {
979  stream << 0 << ":" << __v[0];
980 
981  for (Idx i = 1; i < __h.size(); ++i) {
982  stream << " - " << i << ":" << __v[i];
983  }
984  }
985 
986  stream << "]";
987 
988  std::string res = stream.str();
989  return res;
990  }
991 
992  // returns true if the content of k equals that of *this
993  template < typename Key, typename Alloc >
994  template < typename OtherAlloc >
997  if (size() != k.size())
998  return false;
999  else {
1000  for (Idx i = 0; i < size(); ++i)
1001  if (__v[i] != k.__v[i]) return false;
1002  }
1003 
1004  return true;
1005  }
1006 
1007  // returns true if the content of k is different from that of *this
1008  template < typename Key, typename Alloc >
1009  template < typename OtherAlloc >
1012  return !operator==(k);
1013  }
1014 
1015  // a << operator for displaying the content of the Sequence
1016  template < typename Key, typename Alloc >
1017  INLINE std::ostream&
1018  operator<<(std::ostream& stream,
1020  stream << seq.toString();
1021  return stream;
1022  }
1023 
1024  // returns the safe begin iterator
1025  template < typename Key, typename Alloc >
1028  return SequenceIteratorSafe< Key >{*this};
1029  }
1030 
1031  // return the safe end iterator
1032  template < typename Key, typename Alloc >
1033  INLINE const SequenceIteratorSafe< Key >&
1035  return __end_safe;
1036  }
1037 
1038  // return an iterator pointing to the last element
1039  template < typename Key, typename Alloc >
1042  SequenceIteratorSafe< Key > it{*this};
1043  it.__setPos(size() - 1);
1044  return it;
1045  }
1046 
1047  // returns an iterator pointing just before the first element
1048  template < typename Key, typename Alloc >
1049  INLINE const SequenceIteratorSafe< Key >&
1051  return __rend_safe;
1052  }
1053 
1054  // returns the unsafe begin iterator
1055  template < typename Key, typename Alloc >
1056  INLINE SequenceIterator< Key >
1058  return SequenceIterator< Key >{*this};
1059  }
1060 
1061  // return the unsafe end iterator
1062  template < typename Key, typename Alloc >
1063  INLINE const SequenceIterator< Key >&
1065  return __end_safe;
1066  }
1067 
1068  // return an unsafe iterator pointing to the last element
1069  template < typename Key, typename Alloc >
1070  INLINE SequenceIterator< Key >
1072  SequenceIterator< Key > it{*this};
1073  it.__setPos(size() - 1);
1074  return it;
1075  }
1076 
1077  // returns an unsafe iterator pointing just before the first element
1078  template < typename Key, typename Alloc >
1079  INLINE const SequenceIterator< Key >&
1081  return __rend_safe;
1082  }
1083 
1084  // modifies the size of the internal structures of the sequence
1085  template < typename Key, typename Alloc >
1087  if (new_size < __h.size()) return;
1088 
1089  __h.resize(new_size);
1090  __v.reserve(new_size);
1091  }
1092 
1093  // ===========================================================================
1094  // Sequence
1095  // ===========================================================================
1096 
1097  // Default constructor
1098  template < typename Key, typename Alloc >
1100  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(
1101  size_param) {
1102  // for debugging purposes
1103  GUM_CONSTRUCTOR(Sequence);
1104  }
1105 
1106  // initializer list constructor
1107  template < typename Key, typename Alloc >
1108  INLINE Sequence< Key, Alloc >::Sequence(std::initializer_list< Key > list) :
1109  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(list) {
1110  // for debugging purposes
1111  GUM_CONSTRUCTOR(Sequence);
1112  }
1113 
1114  // copy constructor
1115  template < typename Key, typename Alloc >
1117  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(aSeq) {
1118  // for debugging purposes
1119  GUM_CONS_CPY(Sequence);
1120  }
1121 
1122  // generalized copy constructor
1123  template < typename Key, typename Alloc >
1124  template < typename OtherAlloc >
1125  INLINE
1127  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(aSeq) {
1128  // for debugging purposes
1129  GUM_CONS_CPY(Sequence);
1130  }
1131 
1132  // move constructor
1133  template < typename Key, typename Alloc >
1135  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(
1136  std::move(aSeq)) {
1137  // for debugging purposes
1138  GUM_CONS_MOV(Sequence);
1139  }
1140 
1141  // destructor
1142  template < typename Key, typename Alloc >
1144  // for debugging purposes
1145  GUM_DESTRUCTOR(Sequence);
1146  }
1147 
1148  // copy operator
1149  template < typename Key, typename Alloc >
1152  Implementation::operator=(aSeq);
1153  return *this;
1154  }
1155 
1156  // generalized copy operator
1157  template < typename Key, typename Alloc >
1158  template < typename OtherAlloc >
1161  Implementation::operator=(aSeq);
1162  return *this;
1163  }
1164 
1165  // move operator
1166  template < typename Key, typename Alloc >
1169  Implementation::operator=(std::move(aSeq));
1170  return *this;
1171  }
1172 
1173  // returns the set difference : this \ seq
1174  template < typename Key, typename Alloc >
1175  template < typename OtherAlloc >
1177  const Sequence< Key, OtherAlloc >& seq) const {
1178  Set< Key, Alloc > res;
1179 
1180  for (iterator iter = this->begin(); iter != this->end(); ++iter) {
1181  if (!seq.exists(*iter)) res << *iter;
1182  }
1183 
1184  return res;
1185  }
1186 
1187  // a << operator for displaying the content of the Sequence
1188  template < typename Key, typename Alloc >
1189  INLINE std::ostream& operator<<(std::ostream& stream,
1190  const Sequence< Key, Alloc >& seq) {
1191  stream << seq.toString();
1192  return stream;
1193  }
1194 
1195 } /* namespace gum */
Safe iterators for Sequence.
Definition: sequence.h:1206
SequenceIteratorSafe< Key > operator-(Size nb) noexcept
Returns a new iterator.
Definition: sequence_tpl.h:193
bool operator!=(const SequenceIteratorSafe< Key > &source) const noexcept
Checks whether two iterators are pointing to different elements.
Definition: sequence_tpl.h:212
SequenceIteratorSafe< Key > & operator=(const SequenceIteratorSafe< Key > &source) noexcept
Copy operator.
Definition: sequence_tpl.h:125
void clear()
Clear the sequence.
Definition: sequence_tpl.h:271
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
friend class SequenceImplementation
Friends to speed up access.
Definition: sequence.h:94
void resize(Size new_size)
Modifies the size of the internal structures of the sequence.
Definition: sequence_tpl.h:686
Size size() const noexcept
Returns the size of the sequence.
Definition: sequence_tpl.h:38
Idx pos() const
Returns the position of the iterator in the sequence.
Definition: sequence_tpl.h:218
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1022
~SequenceIteratorSafe() noexcept
Class destructor.
Definition: sequence_tpl.h:118
SequenceIteratorSafe< Key > & operator++() noexcept
Point the iterator to the next value in the sequence.
Definition: sequence_tpl.h:143
STL namespace.
SequenceIteratorSafe< Key > & operator--() noexcept
Point the iterator to the preceding value in the sequence.
Definition: sequence_tpl.h:155
bool empty() const noexcept
Return true if empty.
Definition: sequence_tpl.h:44
const Key * operator->() const
Returns the value pointed to by the iterator (works only for non-scalars).
Definition: sequence_tpl.h:255
void swap(HashTable< LpCol, double > *&a, HashTable< LpCol, double > *&b)
Swap the addresses of two pointers to hashTables.
std::string toString() const
Displays the content of the sequence.
Definition: sequence_tpl.h:574
HashTable< Key, Idx, Alloc > __h
Keep track of the position of the element in v (for fast retrieval).
Definition: sequence.h:500
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
void __setAtEnd() noexcept
The iterator points to the end (which is pos size()-1).
Definition: sequence_tpl.h:243
The internal class for storing (ordered) sequences of objects.
Definition: sequence.h:90
std::istream & operator>>(std::istream &in, TiXmlNode &base)
Definition: tinyxml.cpp:1505
void __update_end() noexcept
A method to update the end iterator after changes in the sequence.
Definition: sequence_tpl.h:265
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
bool operator==(const SequenceIteratorSafe< Key > &source) const noexcept
Checks whether two iterators are pointing to the same elements.
Definition: sequence_tpl.h:200
bool exists(const Key &k) const
Check the existence of k in the sequence.
Definition: sequence_tpl.h:402
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:243
SequenceIteratorSafe< Key > & operator-=(Size nb) noexcept
Makes the iterator point to i elements further in the sequence.
Definition: sequence_tpl.h:175
void erase(const Key &k)
Remove an element from the sequence.
Definition: sequence_tpl.h:453
void __setAtRend() noexcept
The iterator points to rend.
Definition: sequence_tpl.h:237
const Key & operator*() const
Returns the value pointed to by the iterator.
Definition: sequence_tpl.h:249
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:251
void __copy(const SequenceImplementation< Key, OtherAlloc, Gen > &aSeq)
Clears the current sequence and fill it with copies the element of aSeq.
Size Idx
Type for indexes.
Definition: types.h:53
INLINE std::ostream & operator<<(std::ostream &stream, const Sequence< Key, Alloc > &seq)
A << operator for displaying the content of the Sequence.
std::vector< Key *, typename Alloc::template rebind< Key *>::other > __v
The set of the elements stored into the sequence.
Definition: sequence.h:503
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
SequenceIteratorSafe(const SequenceImplementation< Key, Alloc, Gen > &seq, Idx pos=0) noexcept
Constructor, always give a valid iterator (even if pos too large).
SequenceIteratorSafe< Key > operator+(Size nb) noexcept
Returns a new iterator.
Definition: sequence_tpl.h:186
SequenceIteratorSafe< Key > & operator+=(Size nb) noexcept
Makes the iterator point to i elements further in the sequence.
Definition: sequence_tpl.h:164
void __setPos(Idx pos) noexcept
The iterator points to the posth element (0 = beginning of the sequence).
Definition: sequence_tpl.h:228
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:408