mdds
delayed_delete_vector.hpp
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 // SPDX-FileCopyrightText: 2025 Kohei Yoshida
4 //
5 // SPDX-License-Identifier: MIT
6 
7 #pragma once
8 
9 #include <vector>
10 #include <algorithm>
11 #include <type_traits>
12 
13 namespace mdds { namespace mtv {
14 
20 template<typename T, typename Allocator = std::allocator<T>>
22 {
23  using store_type = std::vector<T, Allocator>;
24  store_type m_vec;
25  std::size_t m_front_offset = 0; // number of elements removed from front of array
26 public:
27  typedef typename store_type::value_type value_type;
28  typedef typename store_type::size_type size_type;
29  typedef typename store_type::difference_type difference_type;
30  typedef typename store_type::reference reference;
31  typedef typename store_type::const_reference const_reference;
32  typedef typename store_type::pointer pointer;
33  typedef typename store_type::const_pointer const_pointer;
34  typedef typename store_type::iterator iterator;
35  typedef typename store_type::reverse_iterator reverse_iterator;
36  typedef typename store_type::const_iterator const_iterator;
37  typedef typename store_type::const_reverse_iterator const_reverse_iterator;
38 
39  delayed_delete_vector() noexcept(std::is_nothrow_default_constructible_v<store_type>) : m_vec()
40  {}
41 
42  delayed_delete_vector(size_t n, const T& val) : m_vec(n, val)
43  {}
44 
45  delayed_delete_vector(size_t n) : m_vec(n)
46  {}
47 
48  template<typename InputIt>
49  delayed_delete_vector(InputIt first, InputIt last) : m_vec(first, last)
50  {}
51 
52  iterator begin() noexcept
53  {
54  return m_vec.begin() + m_front_offset;
55  }
56 
57  iterator end() noexcept
58  {
59  return m_vec.end();
60  }
61 
62  const_iterator begin() const noexcept
63  {
64  return m_vec.begin() + m_front_offset;
65  }
66 
67  const_iterator end() const noexcept
68  {
69  return m_vec.end();
70  }
71 
72  reverse_iterator rbegin() noexcept
73  {
74  return m_vec.rbegin();
75  }
76 
77  const_reverse_iterator rbegin() const noexcept
78  {
79  return m_vec.rbegin();
80  }
81 
82  reverse_iterator rend() noexcept
83  {
84  return m_vec.rend() - m_front_offset;
85  }
86 
87  const_reverse_iterator rend() const noexcept
88  {
89  return m_vec.rend() - m_front_offset;
90  }
91 
92  reference operator[](size_type pos)
93  {
94  return m_vec[pos + m_front_offset];
95  }
96 
97  const_reference operator[](size_type pos) const
98  {
99  return m_vec[pos + m_front_offset];
100  }
101 
102  reference at(size_type pos)
103  {
104  return m_vec.at(pos + m_front_offset);
105  }
106 
107  const_reference at(size_type pos) const
108  {
109  return m_vec.at(pos + m_front_offset);
110  }
111 
112  void push_back(const T& value)
113  {
114  m_vec.push_back(value);
115  }
116 
117  void push_back(T&& value)
118  {
119  m_vec.push_back(std::move(value));
120  }
121 
122  void swap(delayed_delete_vector& other) noexcept(std::is_nothrow_swappable_v<store_type>)
123  {
124  m_vec.swap(other.m_vec);
125  }
126 
127  template<typename... Args>
128  void emplace_back(Args&&... args)
129  {
130  m_vec.emplace_back(std::forward<Args>(args)...);
131  }
132 
133  iterator insert(iterator pos, const T& value)
134  {
135  return m_vec.insert(pos, value);
136  }
137 
138  iterator insert(const_iterator pos, T&& value)
139  {
140  return m_vec.insert(pos, std::move(value));
141  }
142 
143  template<typename InputIt>
144  void insert(iterator pos, InputIt first, InputIt last)
145  {
146  m_vec.insert(pos, first, last);
147  }
148 
149  void resize(size_type count)
150  {
151  clear_removed();
152  m_vec.resize(count);
153  }
154 
155  iterator erase(iterator pos)
156  {
157  if (pos == m_vec.begin() + m_front_offset)
158  {
159  ++m_front_offset;
160  return m_vec.begin() + m_front_offset;
161  }
162  else
163  return m_vec.erase(pos);
164  }
165 
166  iterator erase(iterator first, iterator last)
167  {
168  return m_vec.erase(first, last);
169  }
170 
171  size_type capacity() const noexcept
172  {
173  return m_vec.capacity();
174  }
175 
176  void shrink_to_fit()
177  {
178  clear_removed();
179  m_vec.shrink_to_fit();
180  }
181 
182  void reserve(size_type new_cap)
183  {
184  clear_removed();
185  m_vec.reserve(new_cap);
186  }
187 
188  size_type size() const
189  {
190  return m_vec.size() - m_front_offset;
191  }
192 
193  template<typename InputIt>
194  void assign(InputIt first, InputIt last)
195  {
196  clear_removed();
197  m_vec.assign(first, last);
198  }
199 
200  T* data()
201  {
202  return m_vec.data() + m_front_offset;
203  }
204 
205  const T* data() const
206  {
207  return m_vec.data() + m_front_offset;
208  }
209 
210 private:
211  void clear_removed()
212  {
213  m_vec.erase(m_vec.begin(), m_vec.begin() + m_front_offset);
214  m_front_offset = 0;
215  }
216 };
217 
218 template<typename T>
219 bool operator==(const delayed_delete_vector<T>& lhs, const delayed_delete_vector<T>& rhs)
220 {
221  return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
222 }
223 
224 namespace detail {
225 
226 template<>
228 {
229  using type = std::true_type;
230 };
231 
232 } // namespace detail
233 
234 }} // namespace mdds::mtv
235 
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: types_util.hpp:124
Definition: cref_wrapper.hpp:12
Definition: delayed_delete_vector.hpp:21