aGrUM  0.14.2
sequence.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  ***************************************************************************/
27 #ifndef GUM_SEQUENCE_H
28 #define GUM_SEQUENCE_H
29 
30 #include <initializer_list>
31 #include <limits>
32 #include <type_traits>
33 #include <vector>
34 
35 #include <agrum/agrum.h>
36 #include <agrum/core/hashTable.h>
37 #include <agrum/core/set.h>
38 
39 namespace gum {
40 
41 #ifndef DOXYGEN_SHOULD_SKIP_THIS
42  template < typename Key, typename Alloc, bool >
43  class SequenceImplementation;
44  template < typename Key, typename Alloc >
45  class Sequence;
46  template < typename Key >
47  class SequenceIteratorSafe;
48  template < typename Key >
49  using SequenceIterator = SequenceIteratorSafe< Key >;
50  template < typename Key >
51  using SequenceConstIterator = SequenceIteratorSafe< Key >;
52 #endif
53 
54  // ===========================================================================
55  // === NON SCALAR GUM SEQUENCE IMPLEMENTATION ===
56  // ===========================================================================
86  template < typename Key, typename Alloc, bool Gen >
90  template < typename K, typename A, bool >
91  friend class SequenceImplementation;
92  friend class SequenceIteratorSafe< Key >;
93  friend class Sequence< Key, Alloc >;
95 
96  public:
99  using value_type = Key;
100  using reference = Key&;
101  using const_reference = const Key&;
102  using pointer = Key*;
103  using const_pointer = const Key*;
104  using size_type = std::size_t;
105  using difference_type = std::ptrdiff_t;
106  using allocator_type = Alloc;
107  using iterator = SequenceIterator< Key >;
108  using const_iterator = SequenceIterator< Key >;
112 
113  private:
114  // ============================================================================
116  // ============================================================================
118 
123 
128  SequenceImplementation(std::initializer_list< Key > list);
129 
138 
147  template < typename OtherAlloc >
150 
156 
158 
159  public:
160  // ============================================================================
162  // ============================================================================
164 
168  ~SequenceImplementation() noexcept;
169 
171  // ============================================================================
173  // ============================================================================
175 
180  iterator_safe beginSafe() const;
181 
186  iterator_safe rbeginSafe() const;
187 
192  const iterator_safe& endSafe() const noexcept;
193 
198  const iterator_safe& rendSafe() const noexcept;
199 
204  iterator begin() const;
205 
210  iterator rbegin() const;
211 
216  const iterator& end() const noexcept;
217 
222  const iterator& rend() const noexcept;
223 
225 
226  private:
227  // ============================================================================
229  // ============================================================================
231 
237  SequenceImplementation< Key, Alloc, Gen >&
238  operator=(const SequenceImplementation< Key, Alloc, Gen >& aSeq);
239 
246  template < typename OtherAlloc >
247  SequenceImplementation< Key, Alloc, Gen >&
248  operator=(const SequenceImplementation< Key, OtherAlloc, Gen >& aSeq);
249 
255  SequenceImplementation< Key, Alloc, Gen >&
256  operator=(SequenceImplementation< Key, Alloc, Gen >&& aSeq);
257 
259 
260  public:
261  // ============================================================================
263  // ============================================================================
265 
272  SequenceImplementation< Key, Alloc, Gen >& operator<<(const Key& k);
273 
280  SequenceImplementation< Key, Alloc, Gen >& operator<<(Key&& k);
281 
291  SequenceImplementation< Key, Alloc, Gen >& operator>>(const Key& k);
292 
299  const Key& operator[](Idx i) const;
300 
311  template < typename OtherAlloc >
312  bool operator==(const SequenceImplementation< Key, OtherAlloc, Gen >& k) const;
313 
324  template < typename OtherAlloc >
325  bool operator!=(const SequenceImplementation< Key, OtherAlloc, Gen >& k) const;
326 
328  // ============================================================================
330  // ============================================================================
332 
336  void clear();
337 
342  Size size() const noexcept;
343 
348  bool empty() const noexcept;
349 
358  bool exists(const Key& k) const;
359 
368  void insert(const Key& k);
369 
378  void insert(Key&& k);
379 
390  template < typename... Args >
391  void emplace(Args&&... args);
392 
402  void erase(const Key& k);
403 
413  void erase(const iterator_safe& k);
414 
421  const Key& atPos(Idx i) const;
422 
430  Idx pos(const Key& key) const;
431 
440  void setAtPos(Idx i, const Key& newKey);
441 
450  void setAtPos(Idx i, Key&& newKey);
451 
457  void swap(Idx i, Idx j);
458 
464  const Key& front() const;
465 
471  const Key& back() const;
472 
477  std::string toString() const;
478 
491  void resize(Size new_size);
492 
494 
495  private:
497  HashTable< Key, Idx, Alloc > __h;
498 
500  std::vector< Key*, typename Alloc::template rebind< Key* >::other > __v;
501 
502  // Note that, using Key* in __v, we actually store the Key only once in the
503  // sequence (that is, within __h). This enables storing big objects within
504  // sequences without having memory overhead.
505 
508 
511 
516  void __update_end() noexcept;
517 
524  template < typename OtherAlloc >
525  void __copy(const SequenceImplementation< Key, OtherAlloc, Gen >& aSeq);
526 
532  void __insert(HashTableBucket< Key, Idx >&& bucket);
533  };
534 
535 #ifndef DOXYGEN_SHOULD_SKIP_THIS
536 
537  // ===========================================================================
538  // === GUM_SEQUENCE_IMPLEMENTATION OPTIMIZED FOR SCALARS ===
539  // ===========================================================================
557  template < typename Key, typename Alloc >
558  class SequenceImplementation< Key, Alloc, true > {
561  template < typename K, typename A, bool >
562  friend class SequenceImplementation;
563  friend class SequenceIteratorSafe< Key >;
564  friend class Sequence< Key, Alloc >;
566 
567  public:
570  using value_type = Key;
571  using size_type = std::size_t;
572  using difference_type = std::ptrdiff_t;
573  using allocator_type = Alloc;
574  using iterator = SequenceIterator< Key >;
575  using const_iterator = SequenceIterator< Key >;
579 
580  private:
581  // ============================================================================
583  // ============================================================================
585 
590 
595  SequenceImplementation(std::initializer_list< Key > list);
596 
605 
614  template < typename OtherAlloc >
617 
623 
625  public:
626  // ============================================================================
628  // ============================================================================
630 
634  ~SequenceImplementation() noexcept;
635 
637  // ============================================================================
639  // ============================================================================
641 
646  iterator_safe beginSafe() const;
647 
652  iterator_safe rbeginSafe() const;
653 
658  const iterator_safe& endSafe() const noexcept;
659 
664  const iterator_safe& rendSafe() const noexcept;
665 
670  iterator begin() const;
671 
676  iterator rbegin() const;
677 
682  const iterator& end() const noexcept;
683 
688  const iterator& rend() const noexcept;
689 
691 
692  private:
693  // ============================================================================
695  // ============================================================================
697 
705 
712  template < typename OtherAlloc >
715 
723 
725 
726  public:
727  // ============================================================================
729  // ============================================================================
731 
739 
750 
757  const Key& operator[](Idx i) const;
758 
769  template < typename OtherAlloc >
770  bool
772 
783  template < typename OtherAlloc >
784  bool
786 
788  // ============================================================================
790  // ============================================================================
792 
796  void clear();
797 
802  Size size() const noexcept;
803 
808  bool empty() const noexcept;
809 
818  bool exists(Key k) const;
819 
828  void insert(Key k);
829 
840  template < typename... Args >
841  void emplace(Args&&... args);
842 
852  void erase(Key k);
853 
863  void erase(const iterator_safe& k);
864 
871  const Key& atPos(Idx i) const;
872 
880  Idx pos(Key key) const;
881 
890  void setAtPos(Idx i, Key newKey);
891 
897  void swap(Idx i, Idx j);
898 
904  const Key& front() const;
905 
911  const Key& back() const;
912 
917  std::string toString() const;
918 
931  void resize(Size new_size);
932 
934 
935  private:
938 
940  std::vector< Key, Alloc > __v;
941 
944 
947 
952  void __update_end() noexcept;
953 
960  template < typename OtherAlloc >
962 
968  void __insert(Key k);
969  };
970 
971 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
972 
973  // ===========================================================================
974  // === GUM_SEQUENCE ===
975  // ===========================================================================
1018  template < typename Key, typename Alloc = std::allocator< Key > >
1019  class Sequence
1020  : public SequenceImplementation< Key, Alloc, std::is_scalar< Key >::value > {
1021  public:
1024  using value_type = Key;
1025  using reference = Key&;
1026  using const_reference = const Key&;
1027  using pointer = Key*;
1028  using const_pointer = const Key*;
1029  using size_type = std::size_t;
1030  using difference_type = std::ptrdiff_t;
1031  using allocator_type = Alloc;
1032  using iterator = SequenceIterator< Key >;
1033  using const_iterator = SequenceIterator< Key >;
1037 
1039  using Implementation =
1041 
1042  // ============================================================================
1044  // ============================================================================
1046 
1052 
1057  Sequence(std::initializer_list< Key > list);
1058 
1066  Sequence(const Sequence< Key, Alloc >& aSeq);
1067 
1076  template < typename OtherAlloc >
1078 
1084 
1088  ~Sequence() noexcept;
1089 
1091  // ============================================================================
1093  // ============================================================================
1095 
1101  Sequence< Key, Alloc >& operator=(const Sequence< Key, Alloc >& aSeq);
1102 
1109  template < typename OtherAlloc >
1110  Sequence< Key, Alloc >& operator=(const Sequence< Key, OtherAlloc >& aSeq);
1111 
1117  Sequence< Key, Alloc >& operator=(Sequence< Key, Alloc >&& aSeq);
1118 
1120  // ============================================================================
1122  // ============================================================================
1124 
1131  template < typename OtherAlloc >
1132  Set< Key, Alloc > diffSet(const Sequence< Key, OtherAlloc >& seq) const;
1133 
1135  };
1136 
1137 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1138 
1139  // dummy classes that will enable discriminate without overhead between
1140  // scalars and non-scalars operators * and ->
1141  template < bool gen >
1142  struct SequenceIteratorGet {
1143  template < typename Key >
1144  INLINE static const Key& op_star(const Key* x) {
1145  return *x;
1146  }
1147  template < typename Key >
1148  INLINE static const Key* op_arrow(const Key* x) {
1149  return x;
1150  }
1151  };
1152 
1153  template <>
1154  struct SequenceIteratorGet< true > {
1155  template < typename Key >
1156  INLINE static const Key& op_star(const Key& x) {
1157  return x;
1158  }
1159  template < typename Key >
1160  INLINE static const Key* op_arrow(const Key& x) {
1161  return &x;
1162  }
1163  };
1164 
1165 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1166 
1167  // ===========================================================================
1168  // class SequenceIteratorSafe
1169  // ===========================================================================
1202  template < typename Key >
1205  template < typename K, typename A, bool >
1207 
1208  public:
1211  using iterator_category = std::bidirectional_iterator_tag;
1212  using value_type = Key;
1213  using reference = Key&;
1214  using const_reference = const Key&;
1215  using pointer = Key*;
1216  using const_pointer = const Key*;
1217  using difference_type = std::ptrdiff_t;
1219 
1220  private:
1222  using Getter = SequenceIteratorGet< std::is_scalar< Key >::value >;
1223 
1224 
1238  template < typename Alloc, bool Gen >
1240  Idx pos = 0) noexcept;
1241 
1242  public:
1243  // ============================================================================
1245  // ============================================================================
1247 
1248 
1261  template < typename Alloc >
1262  SequenceIteratorSafe(const Sequence< Key, Alloc >& seq, Idx pos = 0) noexcept;
1263 
1268  SequenceIteratorSafe(const SequenceIteratorSafe< Key >& source) noexcept;
1269 
1274  SequenceIteratorSafe(SequenceIteratorSafe< Key >&& source) noexcept;
1275 
1279  ~SequenceIteratorSafe() noexcept;
1280 
1282  // ============================================================================
1284  // ============================================================================
1286 
1292  SequenceIteratorSafe< Key >&
1293  operator=(const SequenceIteratorSafe< Key >& source) noexcept;
1294 
1300  SequenceIteratorSafe< Key >&
1301  operator=(SequenceIteratorSafe< Key >&& source) noexcept;
1302 
1309  SequenceIteratorSafe< Key >& operator++() noexcept;
1310 
1318  SequenceIteratorSafe< Key >& operator--() noexcept;
1319 
1330  SequenceIteratorSafe< Key >& operator+=(Size nb) noexcept;
1331 
1342  SequenceIteratorSafe< Key >& operator-=(Size nb) noexcept;
1343 
1353  SequenceIteratorSafe< Key > operator+(Size nb) noexcept;
1354 
1364  SequenceIteratorSafe< Key > operator-(Size nb) noexcept;
1365 
1372  bool operator!=(const SequenceIteratorSafe< Key >& source) const noexcept;
1373 
1380  bool operator==(const SequenceIteratorSafe< Key >& source) const noexcept;
1381 
1387  const Key& operator*() const;
1388 
1395  const Key* operator->() const;
1396 
1398  // ============================================================================
1400  // ============================================================================
1402 
1408  Idx pos() const;
1409 
1411 
1412  private:
1414  Idx __iterator;
1415 
1417  const SequenceImplementation< Key,
1418  std::allocator< Key >,
1419  std::is_scalar< Key >::value >* __seq;
1420 
1423  void __setPos(Idx pos) noexcept;
1424 
1426  void __setAtRend() noexcept;
1427 
1429  void __setAtEnd() noexcept;
1430  };
1431 
1433  template < typename Key, typename Alloc >
1434  std::ostream& operator<<(std::ostream& stream, const Sequence< Key, Alloc >& s);
1435 
1436 } /* namespace gum */
1437 
1438 
1439 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1440 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1441 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1442 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1443 extern template class gum::Sequence< int >;
1444 # endif
1445 # endif
1446 # endif
1447 #endif
1448 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1449 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1450 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1451 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1452 extern template class gum::Sequence< long >;
1453 # endif
1454 # endif
1455 # endif
1456 #endif
1457 
1458 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1459 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1460 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1461 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1462 extern template class gum::Sequence< double >;
1463 # endif
1464 # endif
1465 # endif
1466 #endif
1467 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1468 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1469 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1470 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
1471 extern template class gum::Sequence< std::string >;
1472 # endif
1473 # endif
1474 # endif
1475 #endif
1476 
1477 
1478 // always include the implementation of the templates
1479 #include <agrum/core/sequence_tpl.h>
1480 
1481 #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:1203
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
Definition: sequence_tpl.h:515
iterator begin() const
Returns an unsafe begin iterator.
Definition: sequence_tpl.h:654
iterator_safe rbeginSafe() const
Returns a safe rbegin iterator.
Definition: sequence_tpl.h:638
void clear()
Clear the sequence.
Definition: sequence_tpl.h:268
const iterator_safe & rendSafe() const noexcept
Returns the safe rend iterator.
Definition: sequence_tpl.h:647
const iterator_safe & endSafe() const noexcept
Returns the safe end iterator.
Definition: sequence_tpl.h:631
Sets of elements (i.e.
A recipient for a pair of key value in a gum::HashTableList.
Definition: hashTable.h:199
friend class SequenceImplementation
Friends to speed up access.
Definition: sequence.h:91
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:683
Size size() const noexcept
Returns the size of the sequence.
Definition: sequence_tpl.h:35
std::bidirectional_iterator_tag iterator_category
types for STL compliance
Definition: sequence.h:1211
The generic class for storing (ordered) sequences of objects.
Definition: sequence.h:1019
STL namespace.
static constexpr Size default_size
The default number of slots in hashtables.
Definition: hashTable.h:77
bool empty() const noexcept
Return true if empty.
Definition: sequence_tpl.h:41
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
SequenceIteratorSafe< Key > __rend_safe
Stores the rend iterator for fast access.
Definition: sequence.h:510
The class for generic Hash Tables.
Definition: hashTable.h:676
The internal class for storing (ordered) sequences of objects.
Definition: sequence.h:87
iterator_safe beginSafe() const
Returns a safe begin iterator.
Definition: sequence_tpl.h:624
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
Template implementation file of gum::Sequence, a class for storing (ordered) sequences of objects...
const Key & operator[](Idx i) const
Returns the element at position i (synonym for atPos).
Definition: sequence_tpl.h:509
SequenceImplementation< Key, Alloc, Gen > & operator=(const SequenceImplementation< Key, Alloc, Gen > &aSeq)
Copy operator.
Definition: sequence_tpl.h:362
SequenceImplementation< Key, Alloc, Gen > & operator>>(const Key &k)
Remove k in the sequence (synonym for erase).
Definition: sequence_tpl.h:490
SequenceImplementation< Key, Alloc, Gen > & operator<<(const Key &k)
Insert k at the end of the sequence (synonym for insert).
Definition: sequence_tpl.h:435
bool exists(const Key &k) const
Check the existence of k in the sequence.
Definition: sequence_tpl.h:399
void erase(const Key &k)
Remove an element from the sequence.
Definition: sequence_tpl.h:450
void swap(Idx i, Idx j)
Swap index.
Definition: sequence_tpl.h:544
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:559
Size Idx
Type for indexes.
Definition: types.h:50
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
const iterator & rend() const noexcept
Returns the unsafe rend iterator.
Definition: sequence_tpl.h:677
SequenceIteratorGet< std::is_scalar< NodeId >::value > Getter
The Getter used by this iterator.
Definition: sequence.h:1222
const iterator & end() const noexcept
Returns the unsafe end iterator.
Definition: sequence_tpl.h:661
~SequenceImplementation() noexcept
Class destructor.
Definition: sequence_tpl.h:354
iterator rbegin() const
Returns an unsafe rbegin iterator.
Definition: sequence_tpl.h:668
void setAtPos(Idx i, const Key &newKey)
Change the value.
Definition: sequence_tpl.h:522
SequenceIteratorSafe< Key > __end_safe
Stores the end iterator for fast access.
Definition: sequence.h:507
bool operator==(const SequenceImplementation< Key, OtherAlloc, Gen > &k) const
Returns true if the content of k equals that of *this.
Definition: sequence_tpl.h:593
Class hash tables iterators.
const Key & back() const
Returns the last element of the sequence.
Definition: sequence_tpl.h:565
const Key & atPos(Idx i) const
Returns the object at the pos i.
Definition: sequence_tpl.h:497
void insert(const Key &k)
Insert an element at the end of the sequence.
Definition: sequence_tpl.h:405