aGrUM  0.16.0
sequence.h
Go to the documentation of this file.
1 
30 #ifndef GUM_SEQUENCE_H
31 #define GUM_SEQUENCE_H
32 
33 #include <initializer_list>
34 #include <limits>
35 #include <type_traits>
36 #include <vector>
37 
38 #include <agrum/agrum.h>
39 #include <agrum/core/hashTable.h>
40 #include <agrum/core/set.h>
41 
42 namespace gum {
43 
44 #ifndef DOXYGEN_SHOULD_SKIP_THIS
45  template < typename Key, typename Alloc, bool >
46  class SequenceImplementation;
47  template < typename Key, typename Alloc >
48  class Sequence;
49  template < typename Key >
50  class SequenceIteratorSafe;
51  template < typename Key >
52  using SequenceIterator = SequenceIteratorSafe< Key >;
53  template < typename Key >
54  using SequenceConstIterator = SequenceIteratorSafe< Key >;
55 #endif
56 
57  // ===========================================================================
58  // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
59  // ===========================================================================
89  template < typename Key, typename Alloc, bool Gen >
93  template < typename K, typename A, bool >
94  friend class SequenceImplementation;
95  friend class SequenceIteratorSafe< Key >;
96  friend class Sequence< Key, Alloc >;
98 
99  public:
102  using value_type = Key;
103  using reference = Key&;
104  using const_reference = const Key&;
105  using pointer = Key*;
106  using const_pointer = const Key*;
107  using size_type = std::size_t;
108  using difference_type = std::ptrdiff_t;
109  using allocator_type = Alloc;
110  using iterator = SequenceIterator< Key >;
111  using const_iterator = SequenceIterator< Key >;
115 
116  private:
117  // ============================================================================
119  // ============================================================================
121 
126 
131  SequenceImplementation(std::initializer_list< Key > list);
132 
141 
150  template < typename OtherAlloc >
153 
159 
161 
162  public:
163  // ============================================================================
165  // ============================================================================
167 
171  ~SequenceImplementation() noexcept;
172 
174  // ============================================================================
176  // ============================================================================
178 
183  iterator_safe beginSafe() const;
184 
189  iterator_safe rbeginSafe() const;
190 
195  const iterator_safe& endSafe() const noexcept;
196 
201  const iterator_safe& rendSafe() const noexcept;
202 
207  iterator begin() const;
208 
213  iterator rbegin() const;
214 
219  const iterator& end() const noexcept;
220 
225  const iterator& rend() const noexcept;
226 
228 
229  private:
230  // ============================================================================
232  // ============================================================================
234 
240  SequenceImplementation< Key, Alloc, Gen >&
241  operator=(const SequenceImplementation< Key, Alloc, Gen >& aSeq);
242 
249  template < typename OtherAlloc >
250  SequenceImplementation< Key, Alloc, Gen >&
251  operator=(const SequenceImplementation< Key, OtherAlloc, Gen >& aSeq);
252 
258  SequenceImplementation< Key, Alloc, Gen >&
259  operator=(SequenceImplementation< Key, Alloc, Gen >&& aSeq);
260 
262 
263  public:
264  // ============================================================================
266  // ============================================================================
268 
275  SequenceImplementation< Key, Alloc, Gen >& operator<<(const Key& k);
276 
283  SequenceImplementation< Key, Alloc, Gen >& operator<<(Key&& k);
284 
294  SequenceImplementation< Key, Alloc, Gen >& operator>>(const Key& k);
295 
302  const Key& operator[](Idx i) const;
303 
314  template < typename OtherAlloc >
315  bool operator==(const SequenceImplementation< Key, OtherAlloc, Gen >& k) const;
316 
327  template < typename OtherAlloc >
328  bool operator!=(const SequenceImplementation< Key, OtherAlloc, Gen >& k) const;
329 
331  // ============================================================================
333  // ============================================================================
335 
339  void clear();
340 
345  Size size() const noexcept;
346 
351  bool empty() const noexcept;
352 
361  bool exists(const Key& k) const;
362 
371  void insert(const Key& k);
372 
381  void insert(Key&& k);
382 
393  template < typename... Args >
394  void emplace(Args&&... args);
395 
405  void erase(const Key& k);
406 
416  void erase(const iterator_safe& k);
417 
424  const Key& atPos(Idx i) const;
425 
433  Idx pos(const Key& key) const;
434 
443  void setAtPos(Idx i, const Key& newKey);
444 
453  void setAtPos(Idx i, Key&& newKey);
454 
460  void swap(Idx i, Idx j);
461 
467  const Key& front() const;
468 
474  const Key& back() const;
475 
480  std::string toString() const;
481 
494  void resize(Size new_size);
495 
497 
498  private:
500  HashTable< Key, Idx, Alloc > __h;
501 
503  std::vector< Key*, typename Alloc::template rebind< Key* >::other > __v;
504 
505  // Note that, using Key* in __v, we actually store the Key only once in the
506  // sequence (that is, within __h). This enables storing big objects within
507  // sequences without having memory overhead.
508 
511 
514 
519  void __update_end() noexcept;
520 
527  template < typename OtherAlloc >
528  void __copy(const SequenceImplementation< Key, OtherAlloc, Gen >& aSeq);
529 
535  void __insert(HashTableBucket< Key, Idx >&& bucket);
536  };
537 
538 #ifndef DOXYGEN_SHOULD_SKIP_THIS
539 
540  // ===========================================================================
541  // === GUM_SEQUENCE_IMPLEMENTATION OPTIMIZED FOR SCALARS ===
542  // ===========================================================================
560  template < typename Key, typename Alloc >
561  class SequenceImplementation< Key, Alloc, true > {
564  template < typename K, typename A, bool >
565  friend class SequenceImplementation;
566  friend class SequenceIteratorSafe< Key >;
567  friend class Sequence< Key, Alloc >;
569 
570  public:
573  using value_type = Key;
574  using size_type = std::size_t;
575  using difference_type = std::ptrdiff_t;
576  using allocator_type = Alloc;
577  using iterator = SequenceIterator< Key >;
578  using const_iterator = SequenceIterator< Key >;
582 
583  private:
584  // ============================================================================
586  // ============================================================================
588 
593 
598  SequenceImplementation(std::initializer_list< Key > list);
599 
608 
617  template < typename OtherAlloc >
620 
626 
628  public:
629  // ============================================================================
631  // ============================================================================
633 
637  ~SequenceImplementation() noexcept;
638 
640  // ============================================================================
642  // ============================================================================
644 
649  iterator_safe beginSafe() const;
650 
655  iterator_safe rbeginSafe() const;
656 
661  const iterator_safe& endSafe() const noexcept;
662 
667  const iterator_safe& rendSafe() const noexcept;
668 
673  iterator begin() const;
674 
679  iterator rbegin() const;
680 
685  const iterator& end() const noexcept;
686 
691  const iterator& rend() const noexcept;
692 
694 
695  private:
696  // ============================================================================
698  // ============================================================================
700 
708 
715  template < typename OtherAlloc >
718 
726 
728 
729  public:
730  // ============================================================================
732  // ============================================================================
734 
742 
753 
760  const Key& operator[](Idx i) const;
761 
772  template < typename OtherAlloc >
773  bool
775 
786  template < typename OtherAlloc >
787  bool
789 
791  // ============================================================================
793  // ============================================================================
795 
799  void clear();
800 
805  Size size() const noexcept;
806 
811  bool empty() const noexcept;
812 
821  bool exists(Key k) const;
822 
831  void insert(Key k);
832 
843  template < typename... Args >
844  void emplace(Args&&... args);
845 
855  void erase(Key k);
856 
866  void erase(const iterator_safe& k);
867 
874  const Key& atPos(Idx i) const;
875 
883  Idx pos(Key key) const;
884 
893  void setAtPos(Idx i, Key newKey);
894 
900  void swap(Idx i, Idx j);
901 
907  const Key& front() const;
908 
914  const Key& back() const;
915 
920  std::string toString() const;
921 
934  void resize(Size new_size);
935 
937 
938  private:
941 
943  std::vector< Key, Alloc > __v;
944 
947 
950 
955  void __update_end() noexcept;
956 
963  template < typename OtherAlloc >
965 
971  void __insert(Key k);
972  };
973 
974 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
975 
976  // ===========================================================================
977  // === GUM_SEQUENCE ===
978  // ===========================================================================
1021  template < typename Key, typename Alloc = std::allocator< Key > >
1022  class Sequence
1023  : public SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value > {
1024  public:
1027  using value_type = Key;
1028  using reference = Key&;
1029  using const_reference = const Key&;
1030  using pointer = Key*;
1031  using const_pointer = const Key*;
1032  using size_type = std::size_t;
1033  using difference_type = std::ptrdiff_t;
1034  using allocator_type = Alloc;
1035  using iterator = SequenceIterator< Key >;
1036  using const_iterator = SequenceIterator< Key >;
1040 
1042  using Implementation =
1044 
1045  // ============================================================================
1047  // ============================================================================
1049 
1055 
1060  Sequence(std::initializer_list< Key > list);
1061 
1069  Sequence(const Sequence< Key, Alloc >& aSeq);
1070 
1079  template < typename OtherAlloc >
1081 
1087 
1091  ~Sequence() noexcept;
1092 
1094  // ============================================================================
1096  // ============================================================================
1098 
1104  Sequence< Key, Alloc >& operator=(const Sequence< Key, Alloc >& aSeq);
1105 
1112  template < typename OtherAlloc >
1113  Sequence< Key, Alloc >& operator=(const Sequence< Key, OtherAlloc >& aSeq);
1114 
1120  Sequence< Key, Alloc >& operator=(Sequence< Key, Alloc >&& aSeq);
1121 
1123  // ============================================================================
1125  // ============================================================================
1127 
1134  template < typename OtherAlloc >
1135  Set< Key, Alloc > diffSet(const Sequence< Key, OtherAlloc >& seq) const;
1136 
1138  };
1139 
1140 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1141 
1142  // dummy classes that will enable discriminate without overhead between
1143  // scalars and non-scalars operators * and ->
1144  template < bool gen >
1145  struct SequenceIteratorGet {
1146  template < typename Key >
1147  INLINE static const Key& op_star(const Key* x) {
1148  return *x;
1149  }
1150  template < typename Key >
1151  INLINE static const Key* op_arrow(const Key* x) {
1152  return x;
1153  }
1154  };
1155 
1156  template <>
1157  struct SequenceIteratorGet< true > {
1158  template < typename Key >
1159  INLINE static const Key& op_star(const Key& x) {
1160  return x;
1161  }
1162  template < typename Key >
1163  INLINE static const Key* op_arrow(const Key& x) {
1164  return &x;
1165  }
1166  };
1167 
1168 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1169 
1170  // ===========================================================================
1171  // class SequenceIteratorSafe
1172  // ===========================================================================
1205  template < typename Key >
1208  template < typename K, typename A, bool >
1210 
1211  public:
1214  using iterator_category = std::bidirectional_iterator_tag;
1215  using value_type = Key;
1216  using reference = Key&;
1217  using const_reference = const Key&;
1218  using pointer = Key*;
1219  using const_pointer = const Key*;
1220  using difference_type = std::ptrdiff_t;
1222 
1223  private:
1225  using Getter = SequenceIteratorGet< std::is_scalar< Key >::value >;
1226 
1227 
1241  template < typename Alloc, bool Gen >
1243  Idx pos = 0) noexcept;
1244 
1245  public:
1246  // ============================================================================
1248  // ============================================================================
1250 
1251 
1264  template < typename Alloc >
1265  SequenceIteratorSafe(const Sequence< Key, Alloc >& seq, Idx pos = 0) noexcept;
1266 
1271  SequenceIteratorSafe(const SequenceIteratorSafe< Key >& source) noexcept;
1272 
1277  SequenceIteratorSafe(SequenceIteratorSafe< Key >&& source) noexcept;
1278 
1282  ~SequenceIteratorSafe() noexcept;
1283 
1285  // ============================================================================
1287  // ============================================================================
1289 
1295  SequenceIteratorSafe< Key >&
1296  operator=(const SequenceIteratorSafe< Key >& source) noexcept;
1297 
1303  SequenceIteratorSafe< Key >&
1304  operator=(SequenceIteratorSafe< Key >&& source) noexcept;
1305 
1312  SequenceIteratorSafe< Key >& operator++() noexcept;
1313 
1321  SequenceIteratorSafe< Key >& operator--() noexcept;
1322 
1333  SequenceIteratorSafe< Key >& operator+=(Size nb) noexcept;
1334 
1345  SequenceIteratorSafe< Key >& operator-=(Size nb) noexcept;
1346 
1356  SequenceIteratorSafe< Key > operator+(Size nb) noexcept;
1357 
1367  SequenceIteratorSafe< Key > operator-(Size nb) noexcept;
1368 
1375  bool operator!=(const SequenceIteratorSafe< Key >& source) const noexcept;
1376 
1383  bool operator==(const SequenceIteratorSafe< Key >& source) const noexcept;
1384 
1390  const Key& operator*() const;
1391 
1398  const Key* operator->() const;
1399 
1401  // ============================================================================
1403  // ============================================================================
1405 
1411  Idx pos() const;
1412 
1414 
1415  private:
1417  Idx __iterator;
1418 
1420  const SequenceImplementation< Key,
1421  std::allocator< Key >,
1422  std::is_scalar< Key >::value >* __seq;
1423 
1426  void __setPos(Idx pos) noexcept;
1427 
1429  void __setAtRend() noexcept;
1430 
1432  void __setAtEnd() noexcept;
1433  };
1434 
1436  template < typename Key, typename Alloc >
1437  std::ostream& operator<<(std::ostream& stream, const Sequence< Key, Alloc >& s);
1438 
1439 } /* namespace gum */
1440 
1441 
1442 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1443 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1444 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1445 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1446 extern template class gum::Sequence< int >;
1447 # endif
1448 # endif
1449 # endif
1450 #endif
1451 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1452 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1453 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1454 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1455 extern template class gum::Sequence< long >;
1456 # endif
1457 # endif
1458 # endif
1459 #endif
1460 
1461 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1462 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1463 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1464 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1465 extern template class gum::Sequence< double >;
1466 # endif
1467 # endif
1468 # endif
1469 #endif
1470 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1471 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1472 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1473 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1474 extern template class gum::Sequence< std::string >;
1475 # endif
1476 # endif
1477 # endif
1478 #endif
1479 
1480 
1481 // always include the implementation of the templates
1482 #include <agrum/core/sequence_tpl.h>
1483 
1484 #endif // GUM_SEQUENCE_H
bool operator!=(const SequenceImplementation< Key, OtherAlloc, Gen > &k) const
Returns true if the content of k is different from that of *this.
Safe iterators for Sequence.
Definition: sequence.h:1206
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
Definition: sequence_tpl.h:518
iterator begin() const
Returns an unsafe begin iterator.
Definition: sequence_tpl.h:657
iterator_safe rbeginSafe() const
Returns a safe rbegin iterator.
Definition: sequence_tpl.h:641
void clear()
Clear the sequence.
Definition: sequence_tpl.h:271
const iterator_safe & rendSafe() const noexcept
Returns the safe rend iterator.
Definition: sequence_tpl.h:650
const iterator_safe & endSafe() const noexcept
Returns the safe end iterator.
Definition: sequence_tpl.h:634
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
A recipient for a pair of key value in a gum::HashTableList.
Definition: hashTable.h:202
friend class SequenceImplementation
Friends to speed up access.
Definition: sequence.h:94
void __insert(HashTableBucket< Key, Idx > &&bucket)
Insert an element at the end of the sequence.
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
std::bidirectional_iterator_tag iterator_category
types for STL compliance
Definition: sequence.h:1214
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1022
STL namespace.
static constexpr Size default_size
The default number of slots in hashtables.
Definition: hashTable.h:80
bool empty() const noexcept
Return true if empty.
Definition: sequence_tpl.h:44
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
SequenceIteratorSafe< Key > __rend_safe
Stores the rend iterator for fast access.
Definition: sequence.h:513
The class for generic Hash Tables.
Definition: hashTable.h:679
The internal class for storing (ordered) sequences of objects.
Definition: sequence.h:90
iterator_safe beginSafe() const
Returns a safe begin iterator.
Definition: sequence_tpl.h:627
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
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
const Key & operator[](Idx i) const
Returns the element at position i (synonym for atPos).
Definition: sequence_tpl.h:512
SequenceImplementation< Key, Alloc, Gen > & operator=(const SequenceImplementation< Key, Alloc, Gen > &aSeq)
Copy operator.
Definition: sequence_tpl.h:365
SequenceImplementation< Key, Alloc, Gen > & operator>>(const Key &k)
Remove k in the sequence (synonym for erase).
Definition: sequence_tpl.h:493
SequenceImplementation< Key, Alloc, Gen > & operator<<(const Key &k)
Insert k at the end of the sequence (synonym for insert).
Definition: sequence_tpl.h:438
bool exists(const Key &k) const
Check the existence of k in the sequence.
Definition: sequence_tpl.h:402
void erase(const Key &k)
Remove an element from the sequence.
Definition: sequence_tpl.h:453
void swap(Idx i, Idx j)
Swap index.
Definition: sequence_tpl.h:547
void emplace(Args &&... args)
Emplace a new element in the sequence.
void __copy(const SequenceImplementation< Key, OtherAlloc, Gen > &aSeq)
Clears the current sequence and fill it with copies the element of aSeq.
const Key & front() const
Returns the first element of the element.
Definition: sequence_tpl.h:562
Size Idx
Type for indexes.
Definition: types.h:53
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
const iterator & rend() const noexcept
Returns the unsafe rend iterator.
Definition: sequence_tpl.h:680
SequenceIteratorGet< std::is_scalar< NodeId >::value > Getter
The Getter used by this iterator.
Definition: sequence.h:1225
const iterator & end() const noexcept
Returns the unsafe end iterator.
Definition: sequence_tpl.h:664
~SequenceImplementation() noexcept
Class destructor.
Definition: sequence_tpl.h:357
iterator rbegin() const
Returns an unsafe rbegin iterator.
Definition: sequence_tpl.h:671
void setAtPos(Idx i, const Key &newKey)
Change the value.
Definition: sequence_tpl.h:525
SequenceIteratorSafe< Key > __end_safe
Stores the end iterator for fast access.
Definition: sequence.h:510
bool operator==(const SequenceImplementation< Key, OtherAlloc, Gen > &k) const
Returns true if the content of k equals that of *this.
Definition: sequence_tpl.h:596
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
const Key & back() const
Returns the last element of the sequence.
Definition: sequence_tpl.h:568
const Key & atPos(Idx i) const
Returns the object at the pos i.
Definition: sequence_tpl.h:500
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:408