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