aGrUM  0.18.1
a C++ library for (probabilistic) graphical models
sequence_tpl.h
Go to the documentation of this file.
1 
31 // to ease IDE parser
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  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 >
134  SequenceIteratorSafe< Key >&& source) noexcept {
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 >
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 >
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 >
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 >
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 >
187  return SequenceIteratorSafe< Key >{*this} += nb;
188  }
189 
190  // returns a new iterator
191  template < typename Key >
194  return SequenceIteratorSafe< Key >{*this} -= nb;
195  }
196 
197  // checks whether two iterators are pointing to the same element
198  template < typename Key >
200  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  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 >
511  INLINE const Key&
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 >
923  INLINE const Key&
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 >
1150  INLINE Sequence< Key, Alloc >&
1152  Implementation::operator=(aSeq);
1153  return *this;
1154  }
1155 
1156  // generalized copy operator
1157  template < typename Key, typename Alloc >
1158  template < typename OtherAlloc >
1159  INLINE Sequence< Key, Alloc >&
1161  Implementation::operator=(aSeq);
1162  return *this;
1163  }
1164 
1165  // move operator
1166  template < typename Key, typename Alloc >
1167  INLINE Sequence< Key, 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:211
SequenceIteratorSafe< Key > & operator=(const SequenceIteratorSafe< Key > &source) noexcept
Copy operator.
Definition: sequence_tpl.h:124
void clear()
Clear the sequence.
Definition: sequence_tpl.h:271
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
void copy__(const SequenceImplementation< Key, OtherAlloc, Gen > &aSeq)
Clears the current sequence and fill it with copies the element of aSeq.
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
void setPos__(Idx pos) noexcept
The iterator points to the posth element (0 = beginning of the sequence).
Definition: sequence_tpl.h:228
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::vector< Key *, typename Alloc::template rebind< Key *>::other > v__
The set of the elements stored into the sequence.
Definition: sequence.h:503
std::string toString() const
Displays the content of the sequence.
Definition: sequence_tpl.h:574
Copyright 2005-2020 Pierre-Henri WUILLEMIN() & Christophe GONZALES() info_at_agrum_dot_org.
Definition: agrum.h:25
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
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:199
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
HashTable< Key, Idx, Alloc > h__
Keep track of the position of the element in v (for fast retrieval).
Definition: sequence.h:500
void erase(const Key &k)
Remove an element from the sequence.
Definition: sequence_tpl.h:453
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 update_end__() noexcept
A method to update the end iterator after changes in the sequence.
Definition: sequence_tpl.h:265
void setAtRend__() noexcept
The iterator points to rend.
Definition: sequence_tpl.h:237
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::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 setAtEnd__() noexcept
The iterator points to the end (which is pos size()-1).
Definition: sequence_tpl.h:243
#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