mdds
Loading...
Searching...
No Matches
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
13namespace mdds { namespace mtv {
14
20template<typename T, typename Allocator = std::allocator<T>>
21class delayed_delete_vector
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
26public:
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
210private:
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
218template<typename T>
219bool 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
224namespace detail {
225
226template<>
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 delayed_delete_vector.hpp:22
Definition types_util.hpp:125