momo  3.10
vector.h
Go to the documentation of this file.
1 /**********************************************************\
2 
3  This file is part of the
4  https://github.com/morzhovets/momo
5  project, distributed under the MIT License. See
6  https://github.com/morzhovets/momo/blob/branch_cpp11/LICENSE
7  for details.
8 
9  momo/stdish/vector.h
10 
11  namespace momo::stdish:
12  class vector
13  class vector_intcap
14 
15 \**********************************************************/
16 
17 #ifndef MOMO_INCLUDE_GUARD_STDISH_VECTOR
18 #define MOMO_INCLUDE_GUARD_STDISH_VECTOR
19 
20 #include "../Array.h"
21 
22 #ifdef MOMO_HAS_CONTAINERS_RANGES
23 # include <ranges>
24 #endif
25 
26 namespace momo
27 {
28 
29 namespace stdish
30 {
31 
43 template<typename TValue,
44  typename TAllocator = std::allocator<TValue>,
45  typename TArray = Array<TValue, MemManagerStd<TAllocator>>>
46 class vector
47 {
48 private:
49  typedef TArray Array;
50  typedef typename Array::MemManager MemManager;
51 
53 
54 public:
55  typedef TValue value_type;
56  typedef TAllocator allocator_type;
57 
58  typedef Array nested_container_type;
59 
60  typedef size_t size_type;
61  typedef ptrdiff_t difference_type;
62 
63  typedef typename Array::Iterator iterator;
65 
67  typedef const value_type& const_reference;
68 
69  typedef value_type* pointer;
70  typedef const value_type* const_pointer;
71  //typedef typename std::allocator_traits<allocator_type>::pointer pointer;
72  //typedef typename std::allocator_traits<allocator_type>::const_pointer const_pointer;
73 
74  typedef std::reverse_iterator<iterator> reverse_iterator;
75  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
76 
77 public:
78  vector() noexcept(noexcept(Array()))
79  {
80  }
81 
82  explicit vector(const allocator_type& alloc) noexcept
83  : mArray(MemManager(alloc))
84  {
85  }
86 
87  explicit vector(size_type count, const allocator_type& alloc = allocator_type())
88  : mArray(count, MemManager(alloc))
89  {
90  }
91 
92  vector(size_type count, const value_type& value, const allocator_type& alloc = allocator_type())
93  : mArray(count, value, MemManager(alloc))
94  {
95  }
96 
97  template<typename Iterator,
98  typename = typename std::iterator_traits<Iterator>::iterator_category>
99  vector(Iterator first, Iterator last, const allocator_type& alloc = allocator_type())
100  : mArray(first, last, MemManager(alloc))
101  {
102  }
103 
104  vector(std::initializer_list<value_type> values, const allocator_type& alloc = allocator_type())
105  : mArray(values, MemManager(alloc))
106  {
107  }
108 
109 #ifdef MOMO_HAS_CONTAINERS_RANGES
110  template<std::ranges::input_range Range>
111  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
112  vector(std::from_range_t, Range&& values, const allocator_type& alloc = allocator_type())
113  : mArray(std::ranges::begin(values), std::ranges::end(values), MemManager(alloc))
114  {
115  }
116 #endif // MOMO_HAS_CONTAINERS_RANGES
117 
118  vector(vector&& right) noexcept
119  : mArray(std::move(right.mArray))
120  {
121  }
122 
124  noexcept(std::is_empty<allocator_type>::value)
125  : mArray(pvCreateArray(std::move(right), alloc))
126  {
127  }
128 
129  vector(const vector& right)
130  : mArray(right.mArray)
131  {
132  }
133 
135  : mArray(right.mArray, MemManager(alloc))
136  {
137  }
138 
139  ~vector() = default;
140 
142  noexcept(std::is_empty<allocator_type>::value ||
143  std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
144  {
145  if (this != &right)
146  {
147  bool propagate = std::is_empty<allocator_type>::value ||
148  std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value;
149  allocator_type alloc = (propagate ? &right : this)->get_allocator();
150  mArray = pvCreateArray(std::move(right), alloc);
151  }
152  return *this;
153  }
154 
155  vector& operator=(const vector& right)
156  {
157  if (this != &right)
158  {
159  bool propagate = std::is_empty<allocator_type>::value ||
160  std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value;
161  allocator_type alloc = (propagate ? &right : this)->get_allocator();
162  mArray = Array(right.mArray, MemManager(alloc));
163  }
164  return *this;
165  }
166 
167  vector& operator=(std::initializer_list<value_type> values)
168  {
169  assign(values);
170  return *this;
171  }
172 
173  void swap(vector& right) noexcept
174  {
175  MOMO_ASSERT(std::allocator_traits<allocator_type>::propagate_on_container_swap::value
176  || get_allocator() == right.get_allocator());
177  mArray.Swap(right.mArray);
178  }
179 
180  friend void swap(vector& left, vector& right) noexcept
181  {
182  left.swap(right);
183  }
184 
186  {
187  return mArray;
188  }
189 
191  {
192  return mArray;
193  }
194 
195  const_iterator begin() const noexcept
196  {
197  return mArray.GetBegin();
198  }
199 
200  iterator begin() noexcept
201  {
202  return mArray.GetBegin();
203  }
204 
205  const_iterator end() const noexcept
206  {
207  return mArray.GetEnd();
208  }
209 
210  iterator end() noexcept
211  {
212  return mArray.GetEnd();
213  }
214 
216  {
217  return const_reverse_iterator(end());
218  }
219 
221  {
222  return reverse_iterator(end());
223  }
224 
225  const_reverse_iterator rend() const noexcept
226  {
227  return const_reverse_iterator(begin());
228  }
229 
231  {
232  return reverse_iterator(begin());
233  }
234 
235  const_iterator cbegin() const noexcept
236  {
237  return begin();
238  }
239 
240  const_iterator cend() const noexcept
241  {
242  return end();
243  }
244 
246  {
247  return rbegin();
248  }
249 
250  const_reverse_iterator crend() const noexcept
251  {
252  return rend();
253  }
254 
255  value_type* data() noexcept
256  {
257  return mArray.GetItems();
258  }
259 
260  const value_type* data() const noexcept
261  {
262  return mArray.GetItems();
263  }
264 
265  allocator_type get_allocator() const noexcept
266  {
267  return allocator_type(mArray.GetMemManager().GetByteAllocator());
268  }
269 
270  size_type max_size() const noexcept
271  {
272  return std::allocator_traits<allocator_type>::max_size(get_allocator());
273  }
274 
275  size_type size() const noexcept
276  {
277  return mArray.GetCount();
278  }
279 
281  {
282  mArray.SetCount(size);
283  }
284 
285  void resize(size_type size, const value_type& value)
286  {
287  mArray.SetCount(size, value);
288  }
289 
290  MOMO_NODISCARD bool empty() const noexcept
291  {
292  return mArray.IsEmpty();
293  }
294 
295  void clear() noexcept
296  {
297  mArray.Clear();
298  }
299 
300  size_type capacity() const noexcept
301  {
302  return mArray.GetCapacity();
303  }
304 
305  void reserve(size_type count)
306  {
307  mArray.Reserve(count);
308  }
309 
311  {
312  mArray.Shrink();
313  }
314 
316  {
317  return mArray[index];
318  }
319 
321  {
322  return mArray[index];
323  }
324 
326  {
327  if (index >= size())
328  throw std::out_of_range("invalid vector subscript");
329  return mArray[index];
330  }
331 
333  {
334  if (index >= size())
335  throw std::out_of_range("invalid vector subscript");
336  return mArray[index];
337  }
338 
340  {
341  return mArray[0];
342  }
343 
345  {
346  return mArray[0];
347  }
348 
350  {
351  return mArray.GetBackItem();
352  }
353 
355  {
356  return mArray.GetBackItem();
357  }
358 
359  void push_back(value_type&& value)
360  {
361  mArray.AddBack(std::move(value));
362  }
363 
364  void push_back(const value_type& value)
365  {
366  mArray.AddBack(value);
367  }
368 
370  {
371  size_t index = SMath::Dist(cbegin(), where);
372  mArray.Insert(index, std::move(value));
373  return SMath::Next(begin(), index);
374  }
375 
377  {
378  size_t index = SMath::Dist(cbegin(), where);
379  mArray.Insert(index, value);
380  return SMath::Next(begin(), index);
381  }
382 
383  iterator insert(const_iterator where, size_type count, const value_type& value)
384  {
385  size_t index = SMath::Dist(cbegin(), where);
386  mArray.Insert(index, count, value);
387  return SMath::Next(begin(), index);
388  }
389 
390  template<typename Iterator,
391  typename = typename std::iterator_traits<Iterator>::iterator_category>
392  iterator insert(const_iterator where, Iterator first, Iterator last)
393  {
394  size_t index = SMath::Dist(cbegin(), where);
395  mArray.Insert(index, first, last);
396  return SMath::Next(begin(), index);
397  }
398 
399  iterator insert(const_iterator where, std::initializer_list<value_type> values)
400  {
401  size_t index = SMath::Dist(cbegin(), where);
402  mArray.Insert(index, values);
403  return SMath::Next(begin(), index);
404  }
405 
406  template<typename... ValueArgs>
407  reference emplace_back(ValueArgs&&... valueArgs)
408  {
409  mArray.AddBackVar(std::forward<ValueArgs>(valueArgs)...);
410  return back();
411  }
412 
413  template<typename... ValueArgs>
414  iterator emplace(const_iterator where, ValueArgs&&... valueArgs)
415  {
416  size_t index = SMath::Dist(cbegin(), where);
417  mArray.InsertVar(index, std::forward<ValueArgs>(valueArgs)...);
418  return SMath::Next(begin(), index);
419  }
420 
421 #ifdef MOMO_HAS_CONTAINERS_RANGES
422  template<std::ranges::input_range Range>
423  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
424  void append_range(Range&& values)
425  {
426  insert_range(cend(), std::forward<Range>(values));
427  }
428 
429  template<std::ranges::input_range Range>
430  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
431  iterator insert_range(const_iterator where, Range&& values)
432  {
433  size_t index = SMath::Dist(cbegin(), where);
434  mArray.Insert(index, std::ranges::begin(values), std::ranges::end(values));
435  return SMath::Next(begin(), index);
436  }
437 #endif // MOMO_HAS_CONTAINERS_RANGES
438 
439  void pop_back()
440  {
441  mArray.RemoveBack();
442  }
443 
445  {
446  return erase(where, where + 1);
447  }
448 
450  {
451  size_t index = SMath::Dist(cbegin(), first);
452  mArray.Remove(index, SMath::Dist(first, last));
453  return SMath::Next(begin(), index);
454  }
455 
456  template<typename ValueArg>
457  friend size_type erase(vector& cont, const ValueArg& valueArg)
458  {
459  auto valueFilter = [&valueArg] (const value_type& value)
460  { return value == valueArg; };
461  return cont.mArray.Remove(valueFilter);
462  }
463 
464  template<typename ValueFilter>
465  friend size_type erase_if(vector& cont, const ValueFilter& valueFilter)
466  {
467  return cont.mArray.Remove(valueFilter);
468  }
469 
470  void assign(size_type count, const value_type& value)
471  {
472  mArray = Array(count, value, MemManager(get_allocator()));
473  }
474 
475  template<typename Iterator,
476  typename = typename std::iterator_traits<Iterator>::iterator_category>
477  void assign(Iterator first, Iterator last)
478  {
479  pvAssign(first, last);
480  }
481 
482  void assign(std::initializer_list<value_type> values)
483  {
484  pvAssign(values.begin(), values.end());
485  }
486 
487 #ifdef MOMO_HAS_CONTAINERS_RANGES
488  template<std::ranges::input_range Range>
489  requires std::convertible_to<std::ranges::range_reference_t<Range>, value_type>
490  void assign_range(Range&& values)
491  {
492  pvAssign(std::ranges::begin(values), std::ranges::end(values));
493  }
494 #endif // MOMO_HAS_CONTAINERS_RANGES
495 
496  friend bool operator==(const vector& left, const vector& right)
497  {
498  return left.mArray.IsEqual(right.mArray);
499  }
500 
501 #ifdef MOMO_HAS_THREE_WAY_COMPARISON
502  friend auto operator<=>(const vector& left, const vector& right)
503  requires requires (const_reference ref) { std::tie(ref) <=> std::tie(ref); }
504  {
505  auto comp = [] (const value_type& value1, const value_type& value2)
506  { return std::tie(value1) <=> std::tie(value2); };
507  return std::lexicographical_compare_three_way(left.begin(), left.end(),
508  right.begin(), right.end(), comp);
509  }
510 #else
511  friend bool operator<(const vector& left, const vector& right)
512  {
513  return std::lexicographical_compare(left.begin(), left.end(), right.begin(), right.end());
514  }
515 #endif
516 
518 
519 private:
520  static Array pvCreateArray(vector&& right, const allocator_type& alloc)
521  {
522  if (right.get_allocator() == alloc)
523  return std::move(right.mArray);
524  Array array(std::make_move_iterator(right.begin()),
525  std::make_move_iterator(right.end()), MemManager(alloc));
526  right.clear();
527  return array;
528  }
529 
530  template<typename Iterator, typename Sentinel>
531  void pvAssign(Iterator begin, Sentinel end)
532  {
533  mArray = Array(std::move(begin), std::move(end), MemManager(get_allocator()));
534  }
535 
536 private:
537  Array mArray;
538 };
539 
540 #ifdef MOMO_HAS_DEDUCTION_GUIDES
541 
542 namespace internal
543 {
544  template<typename Allocator,
545  typename = decltype(std::declval<Allocator&>().allocate(size_t{}))>
546  class vector_checker
547  {
548  };
549 }
550 
551 template<typename Iterator,
552  typename Value = typename std::iterator_traits<Iterator>::value_type,
553  typename Allocator = std::allocator<Value>,
554  typename = internal::vector_checker<Allocator>>
555 vector(Iterator, Iterator, Allocator = Allocator())
556  -> vector<Value, Allocator>;
557 
558 #ifdef MOMO_HAS_CONTAINERS_RANGES
559 template<std::ranges::input_range Range,
560  typename Value = std::ranges::range_value_t<Range>,
561  typename Allocator = std::allocator<Value>,
562  typename = internal::vector_checker<Allocator>>
563 vector(std::from_range_t, Range&&, Allocator = Allocator())
564  -> vector<Value, Allocator>;
565 #endif // MOMO_HAS_CONTAINERS_RANGES
566 
567 #endif // MOMO_HAS_DEDUCTION_GUIDES
568 
578 template<size_t tInternalCapacity, typename TValue,
579  typename TAllocator = std::allocator<TValue>>
580 using vector_intcap = vector<TValue, TAllocator,
582 
583 } // namespace stdish
584 
585 } // namespace momo
586 
587 #endif // MOMO_INCLUDE_GUARD_STDISH_VECTOR
momo::stdish::vector::shrink_to_fit
void shrink_to_fit()
Definition: vector.h:310
momo::stdish::vector::back
const_reference back() const
Definition: vector.h:354
momo::stdish::vector::swap
friend void swap(vector &left, vector &right) noexcept
Definition: vector.h:180
momo::stdish::vector::front
reference front()
Definition: vector.h:339
momo::stdish::vector::vector
vector(size_type count, const allocator_type &alloc=allocator_type())
Definition: vector.h:87
momo::stdish::vector::vector
vector(const allocator_type &alloc) noexcept
Definition: vector.h:82
momo::stdish::vector::rbegin
reverse_iterator rbegin() noexcept
Definition: vector.h:220
momo::stdish::vector::crend
const_reverse_iterator crend() const noexcept
Definition: vector.h:250
momo::stdish::vector::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: vector.h:74
momo::stdish::vector::rend
const_reverse_iterator rend() const noexcept
Definition: vector.h:225
momo::stdish::vector::cbegin
const_iterator cbegin() const noexcept
Definition: vector.h:235
momo::stdish::vector::nested_container_type
Array nested_container_type
Definition: vector.h:58
momo::stdish::vector::back
reference back()
Definition: vector.h:349
momo::stdish::vector::front
const_reference front() const
Definition: vector.h:344
momo::Array::Iterator
IteratorSelector::Iterator Iterator
Definition: Array.h:512
momo::stdish::vector::push_back
void push_back(value_type &&value)
Definition: vector.h:359
momo::stdish::vector::vector
vector(std::initializer_list< value_type > values, const allocator_type &alloc=allocator_type())
Definition: vector.h:104
momo::stdish::vector::assign
void assign(Iterator first, Iterator last)
Definition: vector.h:477
momo::stdish::vector::difference_type
ptrdiff_t difference_type
Definition: vector.h:61
momo::stdish::vector::erase_if
friend size_type erase_if(vector &cont, const ValueFilter &valueFilter)
Definition: vector.h:465
momo::stdish::vector::data
const value_type * data() const noexcept
Definition: vector.h:260
momo::stdish::vector::iterator
Array::Iterator iterator
Definition: vector.h:63
momo::stdish::vector::vector
vector(Iterator first, Iterator last, const allocator_type &alloc=allocator_type())
Definition: vector.h:99
momo::stdish::vector::at
const_reference at(size_type index) const
Definition: vector.h:325
momo::stdish::vector::~vector
~vector()=default
momo::stdish::vector::max_size
size_type max_size() const noexcept
Definition: vector.h:270
momo::stdish::vector::operator=
vector & operator=(std::initializer_list< value_type > values)
Definition: vector.h:167
momo::stdish::vector::get_nested_container
const nested_container_type & get_nested_container() const noexcept
Definition: vector.h:185
momo::stdish::vector::size
size_type size() const noexcept
Definition: vector.h:275
momo::stdish::vector::rbegin
const_reverse_iterator rbegin() const noexcept
Definition: vector.h:215
momo::stdish::vector::end
const_iterator end() const noexcept
Definition: vector.h:205
momo::internal::UIntMath::Dist
static UInt Dist(Iterator begin, Iterator end)
Definition: Utility.h:332
momo::stdish::vector::emplace_back
reference emplace_back(ValueArgs &&... valueArgs)
Definition: vector.h:407
momo::stdish::vector
momo::stdish::vector is similar to std::vector.
Definition: vector.h:47
momo::stdish::vector::vector
vector(const vector &right, const momo::internal::Identity< allocator_type > &alloc)
Definition: vector.h:134
momo::stdish::vector::crbegin
const_reverse_iterator crbegin() const noexcept
Definition: vector.h:245
momo::stdish::vector::resize
void resize(size_type size, const value_type &value)
Definition: vector.h:285
momo::stdish::vector::operator=
vector & operator=(vector &&right) noexcept(std::is_empty< allocator_type >::value||std::allocator_traits< allocator_type >::propagate_on_container_move_assignment::value)
Definition: vector.h:141
momo::stdish::vector::operator[]
reference operator[](size_type index)
Definition: vector.h:320
momo::stdish::vector::resize
void resize(size_type size)
Definition: vector.h:280
momo::stdish::vector::get_nested_container
nested_container_type & get_nested_container() noexcept
Definition: vector.h:190
momo::stdish::vector::data
value_type * data() noexcept
Definition: vector.h:255
momo
Definition: Array.h:26
momo::stdish::vector::insert
iterator insert(const_iterator where, size_type count, const value_type &value)
Definition: vector.h:383
momo::stdish::vector::reference
value_type & reference
Definition: vector.h:66
momo::stdish::vector::vector
vector(vector &&right, const momo::internal::Identity< allocator_type > &alloc) noexcept(std::is_empty< allocator_type >::value)
Definition: vector.h:123
momo::stdish::vector::operator<
friend bool operator<(const vector &left, const vector &right)
Definition: vector.h:511
momo::stdish::vector::pop_back
void pop_back()
Definition: vector.h:439
momo::stdish::vector::emplace
iterator emplace(const_iterator where, ValueArgs &&... valueArgs)
Definition: vector.h:414
momo::stdish::vector::insert
iterator insert(const_iterator where, Iterator first, Iterator last)
Definition: vector.h:392
momo::stdish::vector::size_type
size_t size_type
Definition: vector.h:60
momo::internal::Identity
EnableIf< true, Type > Identity
Definition: Utility.h:201
momo::stdish::vector::rend
reverse_iterator rend() noexcept
Definition: vector.h:230
momo::stdish::vector::erase
friend size_type erase(vector &cont, const ValueArg &valueArg)
Definition: vector.h:457
momo::Array::MemManager
TMemManager MemManager
Definition: Array.h:196
momo::stdish::vector::push_back
void push_back(const value_type &value)
Definition: vector.h:364
momo::stdish::vector::swap
void swap(vector &right) noexcept
Definition: vector.h:173
momo::Array::ConstIterator
IteratorSelector::ConstIterator ConstIterator
Definition: Array.h:511
momo::stdish::vector::operator=
vector & operator=(const vector &right)
Definition: vector.h:155
momo::stdish::vector::erase
iterator erase(const_iterator first, const_iterator last)
Definition: vector.h:449
momo::stdish::vector::capacity
size_type capacity() const noexcept
Definition: vector.h:300
momo::stdish::vector::begin
iterator begin() noexcept
Definition: vector.h:200
momo::stdish::vector::assign
void assign(std::initializer_list< value_type > values)
Definition: vector.h:482
momo::stdish::vector::clear
void clear() noexcept
Definition: vector.h:295
momo::stdish::vector::assign
void assign(size_type count, const value_type &value)
Definition: vector.h:470
momo::stdish::vector::vector
vector() noexcept(noexcept(Array()))
Definition: vector.h:78
momo::stdish::vector::cend
const_iterator cend() const noexcept
Definition: vector.h:240
momo::stdish::vector::const_iterator
Array::ConstIterator const_iterator
Definition: vector.h:64
momo::stdish::vector::const_reference
const value_type & const_reference
Definition: vector.h:67
momo::stdish::vector::allocator_type
TAllocator allocator_type
Definition: vector.h:56
std
Definition: ArrayUtility.h:308
momo::stdish::vector::vector
vector(size_type count, const value_type &value, const allocator_type &alloc=allocator_type())
Definition: vector.h:92
momo::stdish::vector::vector
vector(vector &&right) noexcept
Definition: vector.h:118
momo::stdish::vector::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: vector.h:75
momo::internal::UIntMath::Next
static Iterator Next(Iterator iter, UInt dist)
Definition: Utility.h:339
momo::stdish::vector::reserve
void reserve(size_type count)
Definition: vector.h:305
momo::stdish::vector::erase
iterator erase(const_iterator where)
Definition: vector.h:444
momo::stdish::vector::get_allocator
allocator_type get_allocator() const noexcept
Definition: vector.h:265
momo::stdish::vector::operator==
friend bool operator==(const vector &left, const vector &right)
Definition: vector.h:496
momo::stdish::vector::begin
const_iterator begin() const noexcept
Definition: vector.h:195
momo::stdish::vector::vector
vector(const vector &right)
Definition: vector.h:129
momo::stdish::vector::pointer
value_type * pointer
Definition: vector.h:69
MOMO_MORE_COMPARISON_OPERATORS
#define MOMO_MORE_COMPARISON_OPERATORS(ObjectArg)
Definition: Utility.h:77
momo::stdish::vector::insert
iterator insert(const_iterator where, std::initializer_list< value_type > values)
Definition: vector.h:399
momo::stdish::vector::value_type
TValue value_type
Definition: vector.h:55
momo::stdish::vector::const_pointer
const value_type * const_pointer
Definition: vector.h:70
momo::Array
Definition: Array.h:193
momo::stdish::vector::insert
iterator insert(const_iterator where, value_type &&value)
Definition: vector.h:369
momo::internal::UIntMath
Definition: Utility.h:315
MOMO_ASSERT
#define MOMO_ASSERT(expr)
Definition: UserSettings.h:162
momo::stdish::vector::operator[]
const_reference operator[](size_type index) const
Definition: vector.h:315
momo::stdish::vector::insert
iterator insert(const_iterator where, const value_type &value)
Definition: vector.h:376
momo::stdish::vector::empty
MOMO_NODISCARD bool empty() const noexcept
Definition: vector.h:290
MOMO_NODISCARD
#define MOMO_NODISCARD
Definition: UserSettings.h:203
momo::stdish::vector::at
reference at(size_type index)
Definition: vector.h:332
momo::stdish::vector::end
iterator end() noexcept
Definition: vector.h:210