aGrUM  0.14.2
sequence_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
28 // to ease IDE parser
29 #include <agrum/core/sequence.h>
30 
31 namespace gum {
32 
33  // returns the size of the sequence
34  template < typename Key, typename Alloc, bool Gen >
36  return __h.size();
37  }
38 
39  // return true if empty
40  template < typename Key, typename Alloc, bool Gen >
41  INLINE bool SequenceImplementation< Key, Alloc, Gen >::empty() const noexcept {
42  return __h.empty();
43  }
44 
45  // returns the size of the sequence
46  template < typename Key, typename Alloc >
48  return __h.size();
49  }
50 
51  // return true if empty
52  template < typename Key, typename Alloc >
53  INLINE bool SequenceImplementation< Key, Alloc, true >::empty() const noexcept {
54  return __h.empty();
55  }
56 
57  // ===========================================================================
58  // class SequenceIteratorSafe
59  // ===========================================================================
60 
61  // default constructor
62  template < typename Key >
63  template < typename Alloc, bool Gen >
65  const SequenceImplementation< Key, Alloc, Gen >& seq, Idx pos) noexcept :
66  __seq{reinterpret_cast<
67  const SequenceImplementation< Key,
68  std::allocator< Key >,
69  std::is_scalar< Key >::value >* >(&seq)} {
70  GUM_CONSTRUCTOR(SequenceIteratorSafe);
71 
72  if (pos > __seq->size())
73  __iterator = __seq->size(); // make the iterator point to end
74  else
75  __iterator = pos;
76  }
77 
78  // default constructor
79  template < typename Key >
80  template < typename Alloc >
82  const Sequence< Key, Alloc >& seq, Idx pos) noexcept :
83  __seq{reinterpret_cast<
84  const SequenceImplementation< Key,
85  std::allocator< Key >,
86  std::is_scalar< Key >::value >* >(&seq)} {
87  GUM_CONSTRUCTOR(SequenceIteratorSafe);
88 
89  if (pos > __seq->size())
90  __iterator = __seq->size(); // make the iterator point to end
91  else
92  __iterator = pos;
93  }
94 
95  // copy constructor
96  template < typename Key >
98  const SequenceIteratorSafe< Key >& source) noexcept :
99  __iterator{source.__iterator},
100  __seq{source.__seq} {
101  GUM_CONS_CPY(SequenceIteratorSafe);
102  }
103 
104  // move constructor
105  template < typename Key >
107  SequenceIteratorSafe< Key >&& source) noexcept :
108  __iterator{source.__iterator},
109  __seq{source.__seq} {
110  GUM_CONS_MOV(SequenceIteratorSafe);
111  }
112 
113  // destructor
114  template < typename Key >
116  GUM_DESTRUCTOR(SequenceIteratorSafe);
117  }
118 
119  // copy operator
120  template < typename Key >
122  operator=(const SequenceIteratorSafe< Key >& source) noexcept {
123  __iterator = source.__iterator;
124  __seq = source.__seq;
125  return *this;
126  }
127 
128  // move operator
129  template < typename Key >
132  __iterator = source.__iterator;
133  __seq = source.__seq;
134  return *this;
135  }
136 
137  // point the iterator to the next value in the sequence
138  template < typename Key >
140  operator++() noexcept {
141  if (__iterator < __seq->size())
142  ++__iterator;
143  else
144  __iterator = __seq->size();
145 
146  return *this;
147  }
148 
149  // point the iterator to the preceding value in the sequence
150  template < typename Key >
152  operator--() noexcept {
153  if (__iterator != std::numeric_limits< Idx >::max()) --__iterator;
154 
155  return *this;
156  }
157 
158  // makes the iterator point to i elements further in the sequence
159  template < typename Key >
161  operator+=(Size nb) noexcept {
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  operator-=(Size nb) noexcept {
173  if (__iterator == std::numeric_limits< Idx >::max()) return *this;
174  __iterator -= nb;
175  if (__iterator > __seq->size()) __iterator = std::numeric_limits< Idx >::max();
176 
177  return *this;
178  }
179 
180  // returns a new iterator
181  template < typename Key >
183  operator+(Size nb) noexcept {
184  return SequenceIteratorSafe< Key >{*this} += nb;
185  }
186 
187  // returns a new iterator
188  template < typename Key >
190  operator-(Size nb) noexcept {
191  return SequenceIteratorSafe< Key >{*this} -= nb;
192  }
193 
194  // checks whether two iterators are pointing to the same element
195  template < typename Key >
197  operator==(const SequenceIteratorSafe< Key >& source) const noexcept {
198  if (__seq->empty())
199  return true; // all iterators are the same if seq is empty
200 
201  if ((__iterator != source.__iterator) || (__seq != source.__seq)) return false;
202 
203  return true;
204  }
205 
206  // checks whether two iterators are pointing to different elements
207  template < typename Key >
209  operator!=(const SequenceIteratorSafe< Key >& source) const noexcept {
210  return !operator==(source);
211  }
212 
213  // returns the position of the iterator in the sequence
214  template < typename Key >
216  if (__iterator >= __seq->size()) {
217  GUM_ERROR(UndefinedIteratorValue, "iterator is end() or rend()");
218  }
219 
220  return __iterator;
221  }
222 
223  // the iterator points to the posth element (0 = beginning of the sequence).
224  template < typename Key >
225  INLINE void SequenceIteratorSafe< Key >::__setPos(Idx pos) noexcept {
226  if (pos > __seq->size())
227  __iterator = __seq->size();
228  else
229  __iterator = pos;
230  }
231 
232  // the iterator points to the posth element (0 = beginning of the sequence).
233  template < typename Key >
235  __iterator = std::numeric_limits< Idx >::max();
236  }
237 
238  // the iterator points to the posth element (0 = beginning of the sequence).
239  template < typename Key >
241  __iterator = __seq->size();
242  }
243 
244  // returns the value pointed to by the iterator
245  template < typename Key >
246  INLINE const Key& SequenceIteratorSafe< Key >::operator*() const {
247  return Getter::op_star(__seq->__v[pos()]);
248  }
249 
250  // dereferences the value pointed to by the iterator
251  template < typename Key >
252  INLINE const Key* SequenceIteratorSafe< Key >::operator->() const {
253  return Getter::op_arrow(__seq->__v[pos()]);
254  }
255 
256  // ===========================================================================
257  // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
258  // ===========================================================================
259 
260  // updates const iterators
261  template < typename Key, typename Alloc, bool Gen >
263  __end_safe.__setAtEnd();
264  }
265 
266  // clear the sequence
267  template < typename Key, typename Alloc, bool Gen >
269  __h.clear();
270  __v.clear();
271  __update_end();
272  }
273 
274  // clears the current sequence and fill it with copies the element of aSeq
275  template < typename Key, typename Alloc, bool Gen >
276  template < typename OtherAlloc >
279  clear();
280 
281  for (Size i = 0; i < aSeq.size(); ++i) {
282  Key& new_key = const_cast< Key& >(__h.insert(*(aSeq.__v[i]), i).first);
283  __v.push_back(&new_key);
284  }
285 
286  __update_end();
287  }
288 
289  // Default constructor
290  template < typename Key, typename Alloc, bool Gen >
292  Size size_param) :
293  __h(size_param),
294  __end_safe{*this}, __rend_safe{*this} {
295  // for debugging purposes
296  GUM_CONSTRUCTOR(SequenceImplementation);
297  __rend_safe.__setAtRend();
298  __update_end();
299  }
300 
301  // initializer list constructor
302  template < typename Key, typename Alloc, bool Gen >
304  std::initializer_list< Key > list) :
305  __end_safe{*this},
306  __rend_safe{*this} {
307  GUM_CONSTRUCTOR(SequenceImplementation);
308  __rend_safe.__setAtRend();
309  for (const auto& elt : list) {
310  insert(elt); // performs the __update_end ()
311  }
312  }
313 
314  // copy constructor
315  template < typename Key, typename Alloc, bool Gen >
318  __end_safe{*this},
319  __rend_safe{*this} {
320  // for debugging purposes
321  GUM_CONS_CPY(SequenceImplementation);
322  __rend_safe.__setAtRend();
323  __copy(aSeq); // performs the __update_end ()
324  }
325 
326  // generalized copy constructor
327  template < typename Key, typename Alloc, bool Gen >
328  template < typename OtherAlloc >
331  __end_safe{*this},
332  __rend_safe{*this} {
333  // for debugging purposes
334  GUM_CONS_CPY(SequenceImplementation);
335  __rend_safe.__setAtRend();
336  __copy(aSeq); // performs the __update_end ()
337  }
338 
339  // move constructor
340  template < typename Key, typename Alloc, bool Gen >
343  __h(std::move(aSeq.__h)),
344  __v(std::move(aSeq.__v)), __end_safe{*this}, __rend_safe{*this} {
345  // for debugging purposes
346  GUM_CONS_MOV(SequenceImplementation);
347  __rend_safe.__setAtRend();
348  __update_end();
349  }
350 
351  // destructor
352  template < typename Key, typename Alloc, bool Gen >
355  GUM_DESTRUCTOR(SequenceImplementation);
356  }
357 
358  // copy operator
359  template < typename Key, typename Alloc, bool Gen >
363  // avoid self assignment
364  if (&aSeq != this) {
365  __copy(aSeq); // performs the __update_end ()
366  }
367 
368  return *this;
369  }
370 
371  // generalized copy operator
372  template < typename Key, typename Alloc, bool Gen >
373  template < typename OtherAlloc >
377  __copy(aSeq); // performs the __update_end ()
378  return *this;
379  }
380 
381  // move operator
382  template < typename Key, typename Alloc, bool Gen >
386  // avoid self assignment
387  if (&aSeq != this) {
388  __h = std::move(aSeq.__h);
389  __v = std::move(aSeq.__v);
390  __update_end();
391  }
392 
393  return *this;
394  }
395 
396  // check the existence of k in the sequence
397  template < typename Key, typename Alloc, bool Gen >
398  INLINE bool
400  return __h.exists(k);
401  }
402 
403  // insert an element at the end of the sequence
404  template < typename Key, typename Alloc, bool Gen >
406  // k will be added at the end. Insert the new key into the hashtable
407  Key& new_key = const_cast< Key& >(__h.insert(k, __h.size()).first);
408  __v.push_back(&new_key);
409  __update_end();
410  }
411 
412  // insert an element at the end of the sequence
413  template < typename Key, typename Alloc, bool Gen >
415  // k will be added at the end. Insert the new key into the hashtable
416  Key& new_key = const_cast< Key& >(__h.insert(std::move(k), __h.size()).first);
417  __v.push_back(&new_key);
418  __update_end();
419  }
420 
421  // emplace a new element in the sequence
422  template < typename Key, typename Alloc, bool Gen >
423  template < typename... Args >
425  Key key(std::forward< Args >(args)...);
426  Key& new_key =
427  const_cast< Key& >(__h.insert(std::move(key), __h.size()).first);
428  __v.push_back(&new_key);
429  __update_end();
430  }
431 
432  // insert k in the sequence (synonym for insert)
433  template < typename Key, typename Alloc, bool Gen >
436  insert(k);
437  return *this;
438  }
439 
440  // insert k in the sequence (synonym for insert)
441  template < typename Key, typename Alloc, bool Gen >
444  insert(std::move(k));
445  return *this;
446  }
447 
448  // remove an element from the sequence
449  template < typename Key, typename Alloc, bool Gen >
451  // get the position of the element to remove
452  Idx pos;
453 
454  try {
455  pos = __h[k];
456  } catch (NotFound&) { return; }
457 
458  // erase the element
459  __v.erase(__v.begin() + pos);
460  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
461  --__h[*(__v[i])];
462  }
463  __h.erase(k);
464 
465  __update_end();
466  }
467 
468  // remove from the sequence the element pointed to by the iterator
469  template < typename Key, typename Alloc, bool Gen >
470  INLINE void
472  if (iter.pos() >= size()) return;
473 
474  // erase the element
475  Idx pos = iter.pos();
476  Key* key = __v[pos];
477  __v.erase(__v.begin() + pos);
478 
479  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
480  --__h[*(__v[i])];
481  }
482  __h.erase(*key);
483 
484  __update_end();
485  }
486 
487  // remove k in the sequence (synonym for erase)
488  template < typename Key, typename Alloc, bool Gen >
491  erase(k);
492  return *this;
493  }
494 
495  // returns the object at position i ( first elt = index 0 )
496  template < typename Key, typename Alloc, bool Gen >
498  if (i >= __h.size()) {
500  "index " << i << " for a sequence of size" << __h.size());
501  }
502 
503  return *(__v[i]);
504  }
505 
506  // returns the element at position i (synonym for atPos)
507  template < typename Key, typename Alloc, bool Gen >
509  operator[](Idx i) const {
510  return atPos(i);
511  }
512 
513  // returns the position of the object passed in argument (if it exists)
514  template < typename Key, typename Alloc, bool Gen >
516  return __h[key];
517  }
518 
519  // inserts and returns the object at the pos i
520  template < typename Key, typename Alloc, bool Gen >
521  INLINE void
523  const Key& newKey) {
524  if (i >= __h.size()) { GUM_ERROR(NotFound, "index too large"); }
525 
526  Key& new_key = const_cast< Key& >(__h.insert(newKey, i).first);
527  __h.erase(*(__v[i]));
528  __v[i] = &new_key;
529  }
530 
531  // inserts and returns the object at the pos i
532  template < typename Key, typename Alloc, bool Gen >
534  Key&& newKey) {
535  if (i >= __h.size()) { GUM_ERROR(NotFound, "index too large"); }
536 
537  Key& new_key = const_cast< Key& >(__h.insert(std::move(newKey), i).first);
538  __h.erase(*(__v[i]));
539  __v[i] = &new_key;
540  }
541 
542  // replace two elements in the sequence
543  template < typename Key, typename Alloc, bool Gen >
545  if (i == j) return;
546 
547  Key& ki = const_cast< Key& >(atPos(i));
548  Key& kj = const_cast< Key& >(atPos(j));
549 
550  __h[ki] = j;
551  __h[kj] = i;
552 
553  __v[i] = &kj;
554  __v[j] = &ki;
555  }
556 
557  // returns the first element
558  template < typename Key, typename Alloc, bool Gen >
560  return atPos(0);
561  }
562 
563  // returns the last element
564  template < typename Key, typename Alloc, bool Gen >
566  return atPos(size() - 1);
567  }
568 
569  // Print a sequence
570  template < typename Key, typename Alloc, bool Gen >
572  std::stringstream stream;
573  stream << "[";
574 
575  if (!__h.empty()) {
576  stream << 0 << ":" << *__v[0];
577 
578  for (Idx i = 1; i < __h.size(); ++i) {
579  stream << " - " << i << ":" << *__v[i];
580  }
581  }
582 
583  stream << "]";
584 
585  std::string res = stream.str();
586  return res;
587  }
588 
589  // returns true if the content of k equals that of *this
590  template < typename Key, typename Alloc, bool Gen >
591  template < typename OtherAlloc >
594  if (size() != k.size())
595  return false;
596  else {
597  for (Idx i = 0; i < size(); ++i)
598  if (*__v[i] != *(k.__v[i])) return false;
599  }
600 
601  return true;
602  }
603 
604  // returns true if the content of k is different from that of *this
605  template < typename Key, typename Alloc, bool Gen >
606  template < typename OtherAlloc >
609  return !operator==(k);
610  }
611 
612  // a << operator for displaying the content of the Sequence
613  template < typename Key, typename Alloc, bool Gen >
614  INLINE std::ostream&
615  operator<<(std::ostream& stream,
617  stream << seq.toString();
618  return stream;
619  }
620 
621  // returns the safe begin iterator
622  template < typename Key, typename Alloc, bool Gen >
625  return SequenceIteratorSafe< Key >{*this};
626  }
627 
628  // returns the safe end iterator
629  template < typename Key, typename Alloc, bool Gen >
630  INLINE const SequenceIteratorSafe< Key >&
632  return __end_safe;
633  }
634 
635  // return an iterator pointing to the last element
636  template < typename Key, typename Alloc, bool Gen >
639  SequenceIteratorSafe< Key > it{*this};
640  it.__setPos(size() - 1);
641  return it;
642  }
643 
644  // returns an iterator pointing just before the first element
645  template < typename Key, typename Alloc, bool Gen >
646  INLINE const SequenceIteratorSafe< Key >&
648  return __rend_safe;
649  }
650 
651  // returns the unsafe begin iterator
652  template < typename Key, typename Alloc, bool Gen >
653  INLINE SequenceIterator< Key >
655  return SequenceIterator< Key >{*this};
656  }
657 
658  // returns the unsafe end iterator
659  template < typename Key, typename Alloc, bool Gen >
660  INLINE const SequenceIterator< Key >&
662  return __end_safe;
663  }
664 
665  // return an iterator pointing to the last element
666  template < typename Key, typename Alloc, bool Gen >
667  INLINE SequenceIterator< Key >
669  SequenceIterator< Key > it{*this};
670  it.__setPos(size() - 1);
671  return it;
672  }
673 
674  // returns an iterator pointing just before the first element
675  template < typename Key, typename Alloc, bool Gen >
676  INLINE const SequenceIterator< Key >&
678  return __rend_safe;
679  }
680 
681  // modifies the size of the internal structures of the sequence
682  template < typename Key, typename Alloc, bool Gen >
684  if (new_size < __h.size()) return;
685 
686  __h.resize(new_size);
687  __v.reserve(new_size);
688  }
689 
690  // ===========================================================================
691  // === SCALAR GUM SEQUENCE IMPLEMENTATION ===
692  // ===========================================================================
693 
694  // updates the end iterators
695  template < typename Key, typename Alloc >
697  __end_safe.__setAtEnd();
698  }
699 
700  // clear the sequence
701  template < typename Key, typename Alloc >
703  __h.clear();
704  __v.clear();
705  __update_end();
706  }
707 
708  // clears the current sequence and fill it with copies the element of aSeq
709  template < typename Key, typename Alloc >
710  template < typename OtherAlloc >
713  clear();
714 
715  for (Size i = 0; i < aSeq.size(); ++i) {
716  __h.insert(aSeq.__v[i], i);
717  __v.push_back(aSeq.__v[i]);
718  }
719 
720  __update_end();
721  }
722 
723  // Default constructor
724  template < typename Key, typename Alloc >
726  Size size_param) :
727  __h(size_param),
728  __end_safe{*this}, __rend_safe{*this} {
729  // for debugging purposes
730  GUM_CONSTRUCTOR(SequenceImplementation);
731  __rend_safe.__setAtRend();
732  __end_safe.__setAtEnd();
733  }
734 
735  // initializer list constructor
736  template < typename Key, typename Alloc >
737  INLINE SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
738  std::initializer_list< Key > list) :
739  __end_safe{*this},
740  __rend_safe{*this} {
741  GUM_CONSTRUCTOR(SequenceImplementation);
742  __rend_safe.__setAtRend();
743  for (const auto& elt : list) {
744  insert(elt);
745  }
746  }
747 
748  // copy constructor
749  template < typename Key, typename Alloc >
750  SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
752  __h(aSeq.__h),
753  __v(aSeq.__v), __end_safe{*this}, __rend_safe{*this} {
754  // for debugging purposes
755  GUM_CONS_CPY(SequenceImplementation);
756  __rend_safe.__setAtRend();
757  __end_safe.__setAtEnd();
758  }
759 
760  // generalized copy constructor
761  template < typename Key, typename Alloc >
762  template < typename OtherAlloc >
763  SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
765  __h(aSeq.size() / 2),
766  __end_safe{*this}, __rend_safe{*this} {
767  // for debugging purposes
768  GUM_CONS_CPY(SequenceImplementation);
769  __rend_safe.__setAtRend();
770  __copy(aSeq);
771  }
772 
773  // move constructor
774  template < typename Key, typename Alloc >
775  INLINE SequenceImplementation< Key, Alloc, true >::SequenceImplementation(
777  __h(std::move(aSeq.__h)),
778  __v(std::move(aSeq.__v)), __end_safe{*this}, __rend_safe{*this} {
779  // for debugging purposes
780  GUM_CONS_MOV(SequenceImplementation);
781  __rend_safe.__setAtRend();
782  __end_safe.__setAtEnd();
783  }
784 
785  // destructor
786  template < typename Key, typename Alloc >
788  GUM_DESTRUCTOR(SequenceImplementation);
789  }
790 
791  // copy operator
792  template < typename Key, typename Alloc >
796  // avoid self assignment
797  if (&aSeq != this) { __copy(aSeq); }
798 
799  return *this;
800  }
801 
802  // generalized copy operator
803  template < typename Key, typename Alloc >
804  template < typename OtherAlloc >
808  __copy(aSeq);
809  return *this;
810  }
811 
812  // move operator
813  template < typename Key, typename Alloc >
817  // avoid self assignment
818  if (&aSeq != this) {
819  __h = std::move(aSeq.__h);
820  __v = std::move(aSeq.__v);
821  __update_end();
822  }
823 
824  return *this;
825  }
826 
827  // check the existence of k in the sequence
828  template < typename Key, typename Alloc >
829  INLINE bool SequenceImplementation< Key, Alloc, true >::exists(Key k) const {
830  return __h.exists(k);
831  }
832 
833  // insert an element at the end of the sequence
834  template < typename Key, typename Alloc >
836  // k will be added at the end. Insert the new key into the hashtable
837  __h.insert(k, __h.size());
838  __v.push_back(k);
839  __update_end();
840  }
841 
842  // emplace a new element in the sequence
843  template < typename Key, typename Alloc >
844  template < typename... Args >
845  INLINE void SequenceImplementation< Key, Alloc, true >::emplace(Args&&... args) {
846  Key new_key(std::forward< Args >(args)...);
847  __h.insert(new_key, __h.size());
848  __v.push_back(new_key);
849  __update_end();
850  }
851 
852  // insert k in the sequence (synonym for insert)
853  template < typename Key, typename Alloc >
856  insert(k);
857  return *this;
858  }
859 
860  // remove an element from the sequence
861  template < typename Key, typename Alloc >
863  // get the position of the element to remove
864  Idx pos;
865 
866  try {
867  pos = __h[k];
868  } catch (NotFound&) { return; }
869 
870  // erase the element
871  __v.erase(__v.begin() + pos);
872  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
873  --__h[__v[i]];
874  }
875  __h.erase(k);
876 
877  __update_end();
878  }
879 
880  // remove from the sequence the element pointed to by the iterator
881  template < typename Key, typename Alloc >
882  INLINE void
884  if (iter.pos() >= size()) return;
885 
886  // erase the element
887  Idx pos = iter.pos();
888  Key key = __v[pos];
889  __v.erase(__v.begin() + pos);
890 
891  for (Idx i = pos, nb_elts = __h.size() - 1; i < nb_elts; ++i) {
892  --__h[__v[i]];
893  }
894  __h.erase(key);
895 
896  __update_end();
897  }
898 
899  // remove k in the sequence (synonym for erase)
900  template < typename Key, typename Alloc >
903  erase(k);
904  return *this;
905  }
906 
907  // returns the object at position i
908  template < typename Key, typename Alloc >
909  INLINE const Key&
911  if (i >= __h.size()) {
912  GUM_ERROR(NotFound, "not enough elements in the sequence");
913  }
914 
915  return __v[i];
916  }
917 
918  // returns the element at position i (synonym for atPos)
919  template < typename Key, typename Alloc >
921  operator[](Idx i) const {
922  return atPos(i);
923  }
924 
925  // returns the position of the object passed in argument (if it exists)
926  template < typename Key, typename Alloc >
928  return __h[key];
929  }
930 
931  // sets the object at position i
932  template < typename Key, typename Alloc >
934  Key newKey) {
935  if (i >= __h.size()) { GUM_ERROR(NotFound, "index too large"); }
936 
937  __h.insert(newKey, i);
938  __h.erase(__v[i]);
939  __v[i] = newKey;
940  }
941 
942  // replace two elements in the sequence
943  template < typename Key, typename Alloc >
945  if (i == j) return;
946 
947  Key ki = atPos(i);
948  Key kj = atPos(j);
949 
950  __h[ki] = j;
951  __h[kj] = i;
952 
953  __v[i] = kj;
954  __v[j] = ki;
955  }
956 
957  // returns the first element
958  template < typename Key, typename Alloc >
959  INLINE const Key& SequenceImplementation< Key, Alloc, true >::front() const {
960  return atPos(0);
961  }
962 
963  // returns the last element
964  template < typename Key, typename Alloc >
965  INLINE const Key& SequenceImplementation< Key, Alloc, true >::back() const {
966  return atPos(size() - 1);
967  }
968 
969  // Print a sequence
970  template < typename Key, typename Alloc >
972  std::stringstream stream;
973  stream << "[";
974 
975  if (!__h.empty()) {
976  stream << 0 << ":" << __v[0];
977 
978  for (Idx i = 1; i < __h.size(); ++i) {
979  stream << " - " << i << ":" << __v[i];
980  }
981  }
982 
983  stream << "]";
984 
985  std::string res = stream.str();
986  return res;
987  }
988 
989  // returns true if the content of k equals that of *this
990  template < typename Key, typename Alloc >
991  template < typename OtherAlloc >
994  if (size() != k.size())
995  return false;
996  else {
997  for (Idx i = 0; i < size(); ++i)
998  if (__v[i] != k.__v[i]) return false;
999  }
1000 
1001  return true;
1002  }
1003 
1004  // returns true if the content of k is different from that of *this
1005  template < typename Key, typename Alloc >
1006  template < typename OtherAlloc >
1009  return !operator==(k);
1010  }
1011 
1012  // a << operator for displaying the content of the Sequence
1013  template < typename Key, typename Alloc >
1014  INLINE std::ostream&
1015  operator<<(std::ostream& stream,
1017  stream << seq.toString();
1018  return stream;
1019  }
1020 
1021  // returns the safe begin iterator
1022  template < typename Key, typename Alloc >
1025  return SequenceIteratorSafe< Key >{*this};
1026  }
1027 
1028  // return the safe end iterator
1029  template < typename Key, typename Alloc >
1030  INLINE const SequenceIteratorSafe< Key >&
1032  return __end_safe;
1033  }
1034 
1035  // return an iterator pointing to the last element
1036  template < typename Key, typename Alloc >
1039  SequenceIteratorSafe< Key > it{*this};
1040  it.__setPos(size() - 1);
1041  return it;
1042  }
1043 
1044  // returns an iterator pointing just before the first element
1045  template < typename Key, typename Alloc >
1046  INLINE const SequenceIteratorSafe< Key >&
1048  return __rend_safe;
1049  }
1050 
1051  // returns the unsafe begin iterator
1052  template < typename Key, typename Alloc >
1053  INLINE SequenceIterator< Key >
1055  return SequenceIterator< Key >{*this};
1056  }
1057 
1058  // return the unsafe end iterator
1059  template < typename Key, typename Alloc >
1060  INLINE const SequenceIterator< Key >&
1062  return __end_safe;
1063  }
1064 
1065  // return an unsafe iterator pointing to the last element
1066  template < typename Key, typename Alloc >
1067  INLINE SequenceIterator< Key >
1069  SequenceIterator< Key > it{*this};
1070  it.__setPos(size() - 1);
1071  return it;
1072  }
1073 
1074  // returns an unsafe iterator pointing just before the first element
1075  template < typename Key, typename Alloc >
1076  INLINE const SequenceIterator< Key >&
1078  return __rend_safe;
1079  }
1080 
1081  // modifies the size of the internal structures of the sequence
1082  template < typename Key, typename Alloc >
1084  if (new_size < __h.size()) return;
1085 
1086  __h.resize(new_size);
1087  __v.reserve(new_size);
1088  }
1089 
1090  // ===========================================================================
1091  // Sequence
1092  // ===========================================================================
1093 
1094  // Default constructor
1095  template < typename Key, typename Alloc >
1097  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(
1098  size_param) {
1099  // for debugging purposes
1100  GUM_CONSTRUCTOR(Sequence);
1101  }
1102 
1103  // initializer list constructor
1104  template < typename Key, typename Alloc >
1105  INLINE Sequence< Key, Alloc >::Sequence(std::initializer_list< Key > list) :
1106  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(list) {
1107  // for debugging purposes
1108  GUM_CONSTRUCTOR(Sequence);
1109  }
1110 
1111  // copy constructor
1112  template < typename Key, typename Alloc >
1114  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(aSeq) {
1115  // for debugging purposes
1116  GUM_CONS_CPY(Sequence);
1117  }
1118 
1119  // generalized copy constructor
1120  template < typename Key, typename Alloc >
1121  template < typename OtherAlloc >
1122  INLINE
1124  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(aSeq) {
1125  // for debugging purposes
1126  GUM_CONS_CPY(Sequence);
1127  }
1128 
1129  // move constructor
1130  template < typename Key, typename Alloc >
1132  SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value >(
1133  std::move(aSeq)) {
1134  // for debugging purposes
1135  GUM_CONS_MOV(Sequence);
1136  }
1137 
1138  // destructor
1139  template < typename Key, typename Alloc >
1141  // for debugging purposes
1142  GUM_DESTRUCTOR(Sequence);
1143  }
1144 
1145  // copy operator
1146  template < typename Key, typename Alloc >
1149  Implementation::operator=(aSeq);
1150  return *this;
1151  }
1152 
1153  // generalized copy operator
1154  template < typename Key, typename Alloc >
1155  template < typename OtherAlloc >
1158  Implementation::operator=(aSeq);
1159  return *this;
1160  }
1161 
1162  // move operator
1163  template < typename Key, typename Alloc >
1166  Implementation::operator=(std::move(aSeq));
1167  return *this;
1168  }
1169 
1170  // returns the set difference : this \ seq
1171  template < typename Key, typename Alloc >
1172  template < typename OtherAlloc >
1174  const Sequence< Key, OtherAlloc >& seq) const {
1175  Set< Key, Alloc > res;
1176 
1177  for (iterator iter = this->begin(); iter != this->end(); ++iter) {
1178  if (!seq.exists(*iter)) res << *iter;
1179  }
1180 
1181  return res;
1182  }
1183 
1184  // a << operator for displaying the content of the Sequence
1185  template < typename Key, typename Alloc >
1186  INLINE std::ostream& operator<<(std::ostream& stream,
1187  const Sequence< Key, Alloc >& seq) {
1188  stream << seq.toString();
1189  return stream;
1190  }
1191 
1192 } /* namespace gum */
Safe iterators for Sequence.
Definition: sequence.h:1203
SequenceIteratorSafe< Key > operator-(Size nb) noexcept
Returns a new iterator.
Definition: sequence_tpl.h:190
bool operator!=(const SequenceIteratorSafe< Key > &source) const noexcept
Checks whether two iterators are pointing to different elements.
Definition: sequence_tpl.h:209
SequenceIteratorSafe< Key > & operator=(const SequenceIteratorSafe< Key > &source) noexcept
Copy operator.
Definition: sequence_tpl.h:122
void clear()
Clear the sequence.
Definition: sequence_tpl.h:268
Header file of gum::Sequence, a class for storing (ordered) sequences of objects. ...
friend class SequenceImplementation
Friends to speed up access.
Definition: sequence.h:91
void resize(Size new_size)
Modifies the size of the internal structures of the sequence.
Definition: sequence_tpl.h:683
Size size() const noexcept
Returns the size of the sequence.
Definition: sequence_tpl.h:35
Idx pos() const
Returns the position of the iterator in the sequence.
Definition: sequence_tpl.h:215
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
~SequenceIteratorSafe() noexcept
Class destructor.
Definition: sequence_tpl.h:115
SequenceIteratorSafe< Key > & operator++() noexcept
Point the iterator to the next value in the sequence.
Definition: sequence_tpl.h:140
STL namespace.
SequenceIteratorSafe< Key > & operator--() noexcept
Point the iterator to the preceding value in the sequence.
Definition: sequence_tpl.h:152
bool empty() const noexcept
Return true if empty.
Definition: sequence_tpl.h:41
const Key * operator->() const
Returns the value pointed to by the iterator (works only for non-scalars).
Definition: sequence_tpl.h:252
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:571
HashTable< Key, Idx, Alloc > __h
Keep track of the position of the element in v (for fast retrieval).
Definition: sequence.h:497
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void __setAtEnd() noexcept
The iterator points to the end (which is pos size()-1).
Definition: sequence_tpl.h:240
The internal class for storing (ordered) sequences of objects.
Definition: sequence.h:87
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:262
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:162
bool operator==(const SequenceIteratorSafe< Key > &source) const noexcept
Checks whether two iterators are pointing to the same elements.
Definition: sequence_tpl.h:197
bool exists(const Key &k) const
Check the existence of k in the sequence.
Definition: sequence_tpl.h:399
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:172
void erase(const Key &k)
Remove an element from the sequence.
Definition: sequence_tpl.h:450
void __setAtRend() noexcept
The iterator points to rend.
Definition: sequence_tpl.h:234
const Key & operator*() const
Returns the value pointed to by the iterator.
Definition: sequence_tpl.h:246
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:50
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:500
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
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:183
SequenceIteratorSafe< Key > & operator+=(Size nb) noexcept
Makes the iterator point to i elements further in the sequence.
Definition: sequence_tpl.h:161
void __setPos(Idx pos) noexcept
The iterator points to the posth element (0 = beginning of the sequence).
Definition: sequence_tpl.h:225
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:405