PMDK C++ bindings 1.13.0
This is the C++ bindings documentation for PMDK's libpmemobj.
contiguous_iterator.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2018-2021, Intel Corporation */
3
9#ifndef LIBPMEMOBJ_CPP_CONTIGUOUS_ITERATOR_HPP
10#define LIBPMEMOBJ_CPP_CONTIGUOUS_ITERATOR_HPP
11
12#include <algorithm>
13#include <cassert>
14#include <functional>
15
17
18namespace pmem
19{
20
21namespace detail
22{
23
28template <typename Iterator, typename Reference, typename Pointer>
33 constexpr contiguous_iterator(Pointer begin) : ptr(begin)
34 {
35 }
36
40 Reference operator*() const
41 {
42 return *ptr;
43 }
44
48 Pointer operator->() const
49 {
50 return ptr;
51 }
52
56 Iterator &
58 {
59 static_cast<Iterator *>(this)->change_by(1);
60 return *static_cast<Iterator *>(this);
61 }
62
66 Iterator
68 {
69 Iterator tmp(*static_cast<Iterator *>(this));
70 static_cast<Iterator *>(this)->change_by(1);
71 return tmp;
72 }
73
77 Iterator &
79 {
80 static_cast<Iterator *>(this)->change_by(-1);
81 return *static_cast<Iterator *>(this);
82 }
83
87 Iterator
89 {
90 Iterator tmp(*static_cast<Iterator *>(this));
91 static_cast<Iterator *>(this)->change_by(-1);
92 return tmp;
93 }
94
98 Iterator &
99 operator+=(std::ptrdiff_t n)
100 {
101 static_cast<Iterator *>(this)->change_by(n);
102 return *static_cast<Iterator *>(this);
103 }
104
108 Iterator &
109 operator-=(std::ptrdiff_t n)
110 {
111 static_cast<Iterator *>(this)->change_by(-n);
112 return *static_cast<Iterator *>(this);
113 }
114
118 Iterator
119 operator+(std::ptrdiff_t n) const
120 {
121 Iterator tmp(*static_cast<const Iterator *>(this));
122 tmp += n;
123 return tmp;
124 }
125
129 Iterator
130 operator-(std::ptrdiff_t n) const
131 {
132 Iterator tmp(*static_cast<const Iterator *>(this));
133 tmp -= n;
134 return tmp;
135 }
136
140 friend std::ptrdiff_t
141 operator-(const Iterator &lhs, const Iterator &rhs)
142 {
143 return lhs.ptr - rhs.ptr;
144 }
145
149 Reference operator[](std::ptrdiff_t n)
150 {
151 return ptr[n];
152 }
153
154 Pointer
155 get_ptr() const
156 {
157 return ptr;
158 }
159
160protected:
166 void
167 change_by(std::ptrdiff_t n)
168 {
169 ptr += n;
170 }
171
172 Pointer ptr;
173};
174
190template <typename T>
192 : public contiguous_iterator<range_snapshotting_iterator<T>, T &, T *> {
193 using iterator_category = std::random_access_iterator_tag;
194 using value_type = T;
195 using difference_type = std::ptrdiff_t;
196 using reference = T &;
197 using pointer = T *;
199 reference, pointer>;
200
205 range_snapshotting_iterator(pointer ptr = nullptr,
206 pointer data = nullptr,
207 std::size_t size = 0,
208 std::size_t snapshot_size = 1)
209 : base_type(ptr),
210 data(data),
211 size(size),
212 snapshot_size(snapshot_size)
213 {
214 assert(data <= ptr);
215
216 if (snapshot_size && ptr)
217 snapshot_range(ptr);
218 }
219
223 operator const T *() const
224 {
225 return this->ptr;
226 }
227
233 reference operator[](std::ptrdiff_t n)
234 {
235 detail::conditional_add_to_tx(&this->ptr[n], 1,
236 POBJ_XADD_ASSUME_INITIALIZED);
237 return base_type::operator[](n);
238 }
239
243 friend void
245 {
246 std::swap(lhs.ptr, rhs.ptr);
247 std::swap(lhs.data, rhs.data);
248 std::swap(lhs.size, rhs.size);
249 std::swap(lhs.snapshot_size, rhs.snapshot_size);
250 }
251
252 template <typename Iterator, typename Reference, typename Pointer>
253 friend struct contiguous_iterator;
254
255protected:
256 void
257 change_by(std::ptrdiff_t n)
258 {
259 conditional_snapshot_range(this->ptr, n);
261 }
262
263private:
264 /*
265 * Conditionally snapshot range of length snapshot_size,
266 * which contain address equal to ptr + diff.
267 */
268 void
269 conditional_snapshot_range(pointer ptr, difference_type diff)
270 {
271 if (snapshot_size == 0)
272 return;
273
274 auto new_ptr = ptr + diff;
275
276 /* if new pointer is outside of the array */
277 if (new_ptr < data || new_ptr >= data + size)
278 return;
279
280 /* if new pointer is in the same range */
281 if (static_cast<std::size_t>(ptr - data) / snapshot_size ==
282 static_cast<std::size_t>(new_ptr - data) / snapshot_size)
283 return;
284
285 snapshot_range(new_ptr);
286 }
287
288 void
289 snapshot_range(pointer ptr)
290 {
291 /* align index to snapshot_size */
292 auto range_begin =
293 ptr - static_cast<uint64_t>(ptr - data) % snapshot_size;
294 auto range_size = snapshot_size;
295
296 if (range_begin + range_size > data + size)
297 range_size = static_cast<uint64_t>(data + size -
298 range_begin);
299#ifndef NDEBUG
300 verify_range(range_begin, range_size);
301#endif
302
303 detail::conditional_add_to_tx(range_begin, range_size,
304 POBJ_XADD_ASSUME_INITIALIZED);
305 }
306
307#ifndef NDEBUG
308 void
309 verify_range(pointer range_begin, uint64_t range_size)
310 {
311 auto range_offset = static_cast<uint64_t>(range_begin - data);
312
313 assert(range_begin >= data);
314 assert(range_offset % snapshot_size == 0);
315 assert((range_offset + range_size) % snapshot_size == 0 ||
316 range_begin + range_size == data + size);
317 }
318#endif
319
320 pointer data;
321 std::size_t size;
322 std::size_t snapshot_size;
323};
324
329template <typename T>
331 : public contiguous_iterator<basic_contiguous_iterator<T>, T &, T *> {
332 using iterator_category = std::random_access_iterator_tag;
333 using value_type = T;
334 using difference_type = std::ptrdiff_t;
335 using reference = T &;
336 using pointer = T *;
338 reference, pointer>;
339
344 basic_contiguous_iterator(pointer ptr = nullptr) : base_type(ptr)
345 {
346 }
347
351 operator const T *() const
352 {
353 return this->ptr;
354 }
355
360 reference operator*() const
361 {
362 detail::conditional_add_to_tx(this->ptr, 1,
363 POBJ_XADD_ASSUME_INITIALIZED);
364 return base_type::operator*();
365 }
366
371 pointer operator->() const
372 {
373 detail::conditional_add_to_tx(this->ptr, 1,
374 POBJ_XADD_ASSUME_INITIALIZED);
375 return base_type::operator->();
376 }
377
383 reference operator[](std::ptrdiff_t n)
384 {
385 detail::conditional_add_to_tx(&this->ptr[n], 1,
386 POBJ_XADD_ASSUME_INITIALIZED);
387 return base_type::operator[](n);
388 }
389
393 friend void
395 {
396 std::swap(lhs.ptr, rhs.ptr);
397 }
398};
399
400} /* namespace detail */
401
402} /* namespace pmem */
403
404#endif /* LIBPMEMOBJ_CPP_CONTIGUOUS_ITERATOR_HPP */
Commonly used functionality.
pmem::obj::array< T, N >::iterator begin(pmem::obj::array< T, N > &a)
Non-member begin.
Definition: array.hpp:829
void swap(pmem::obj::array< T, N > &lhs, pmem::obj::array< T, N > &rhs)
Non-member swap function.
Definition: array.hpp:909
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Default non-const iterator which adds element to a transaction on every access.
Definition: contiguous_iterator.hpp:331
friend void swap(basic_contiguous_iterator &lhs, basic_contiguous_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:394
basic_contiguous_iterator(pointer ptr=nullptr)
Constructor taking pointer and snapshotting function as arguments.
Definition: contiguous_iterator.hpp:344
pointer operator->() const
Arrow operator which adds underlying element to a transactions.
Definition: contiguous_iterator.hpp:371
reference operator[](std::ptrdiff_t n)
Element access operator.
Definition: contiguous_iterator.hpp:383
reference operator*() const
Dereference operator which adds dereferenced element to a transaction.
Definition: contiguous_iterator.hpp:360
Base class for iterators which satisfies RandomAccessIterator and operate on contiguous memory.
Definition: contiguous_iterator.hpp:29
void change_by(std::ptrdiff_t n)
Function for changing underlying pointer.
Definition: contiguous_iterator.hpp:167
Iterator operator--(int)
Postfix decrement operator.
Definition: contiguous_iterator.hpp:88
Iterator operator-(std::ptrdiff_t n) const
Subtraction operator overload for integral type.
Definition: contiguous_iterator.hpp:130
Iterator & operator--()
Prefix decrement operator.
Definition: contiguous_iterator.hpp:78
Reference operator[](std::ptrdiff_t n)
Element access operator.
Definition: contiguous_iterator.hpp:149
Iterator & operator-=(std::ptrdiff_t n)
Subtraction assignment operator.
Definition: contiguous_iterator.hpp:109
Iterator & operator+=(std::ptrdiff_t n)
Addition assignment operator.
Definition: contiguous_iterator.hpp:99
Iterator operator+(std::ptrdiff_t n) const
Addition operator.
Definition: contiguous_iterator.hpp:119
friend std::ptrdiff_t operator-(const Iterator &lhs, const Iterator &rhs)
Subtraction operator overload Iterator type.
Definition: contiguous_iterator.hpp:141
Iterator & operator++()
Prefix increment operator.
Definition: contiguous_iterator.hpp:57
Iterator operator++(int)
Postfix increment operator.
Definition: contiguous_iterator.hpp:67
Pointer operator->() const
Arrow operator.
Definition: contiguous_iterator.hpp:48
Reference operator*() const
Dereference operator.
Definition: contiguous_iterator.hpp:40
constexpr contiguous_iterator(Pointer begin)
Constructor taking a pointer.
Definition: contiguous_iterator.hpp:33
Non-const iterator which adds elements to a transaction in a bulk.
Definition: contiguous_iterator.hpp:192
friend void swap(range_snapshotting_iterator &lhs, range_snapshotting_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:244
range_snapshotting_iterator(pointer ptr=nullptr, pointer data=nullptr, std::size_t size=0, std::size_t snapshot_size=1)
Constructor taking pointer to data, pointer to the beginning of the array and snapshot_size.
Definition: contiguous_iterator.hpp:205
reference operator[](std::ptrdiff_t n)
Element access operator.
Definition: contiguous_iterator.hpp:233