PMDK C++ bindings  1.5.2
This is the C++ bindings documentation for PMDK's libpmemobj.
contiguous_iterator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-2020, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
38 #ifndef LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP
39 #define LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP
40 
41 #include <algorithm>
42 #include <cassert>
43 #include <functional>
44 
46 
47 namespace pmem
48 {
49 
50 namespace obj
51 {
52 
53 namespace experimental
54 {
55 
60 template <typename Iterator, typename Reference, typename Pointer>
65  constexpr contiguous_iterator(Pointer begin) : ptr(begin)
66  {
67  }
68 
72  Reference operator*() const
73  {
74  return *ptr;
75  }
76 
80  Pointer operator->() const
81  {
82  return ptr;
83  }
84 
88  Iterator &
90  {
91  static_cast<Iterator *>(this)->change_by(1);
92  return *static_cast<Iterator *>(this);
93  }
94 
98  Iterator
100  {
101  Iterator tmp(*static_cast<Iterator *>(this));
102  static_cast<Iterator *>(this)->change_by(1);
103  return tmp;
104  }
105 
109  Iterator &
111  {
112  static_cast<Iterator *>(this)->change_by(-1);
113  return *static_cast<Iterator *>(this);
114  }
115 
119  Iterator
121  {
122  Iterator tmp(*static_cast<Iterator *>(this));
123  static_cast<Iterator *>(this)->change_by(-1);
124  return tmp;
125  }
126 
130  Iterator &
131  operator+=(std::ptrdiff_t n)
132  {
133  static_cast<Iterator *>(this)->change_by(n);
134  return *static_cast<Iterator *>(this);
135  }
136 
140  Iterator &
141  operator-=(std::ptrdiff_t n)
142  {
143  static_cast<Iterator *>(this)->change_by(-n);
144  return *static_cast<Iterator *>(this);
145  }
146 
150  Iterator
151  operator+(std::ptrdiff_t n)
152  {
153  Iterator tmp(*static_cast<Iterator *>(this));
154  tmp += n;
155  return tmp;
156  }
157 
161  Iterator
162  operator-(std::ptrdiff_t n)
163  {
164  Iterator tmp(*static_cast<Iterator *>(this));
165  tmp -= n;
166  return tmp;
167  }
168 
172  friend std::ptrdiff_t
173  operator-(const Iterator &lhs, const Iterator &rhs)
174  {
175  return lhs.ptr - rhs.ptr;
176  }
177 
181  Reference operator[](std::ptrdiff_t n)
182  {
183  return ptr[n];
184  }
185 
186  Pointer
187  get_ptr() const
188  {
189  return ptr;
190  }
191 
192 protected:
198  void
199  change_by(std::ptrdiff_t n)
200  {
201  ptr += n;
202  }
203 
204  Pointer ptr;
205 };
206 
207 template <typename T>
208 struct const_contiguous_iterator;
209 
215 template <typename T>
220  friend bool
222  const const_contiguous_iterator<T> &rhs)
223  {
224  return lhs.get_ptr() == rhs.get_ptr();
225  }
226 
230  friend bool
232  const const_contiguous_iterator<T> &rhs)
233  {
234  return !(lhs == rhs);
235  }
236 
240  friend bool
242  const const_contiguous_iterator<T> &rhs)
243  {
244  return lhs.get_ptr() < rhs.get_ptr();
245  }
246 
250  friend bool
252  const const_contiguous_iterator<T> &rhs)
253  {
254  return lhs.get_ptr() > rhs.get_ptr();
255  }
256 
260  friend bool
262  const const_contiguous_iterator<T> &rhs)
263  {
264  return !(lhs > rhs);
265  }
266 
270  friend bool
272  const const_contiguous_iterator<T> &rhs)
273  {
274  return !(lhs < rhs);
275  }
276 };
277 
293 template <typename T>
295  : public contiguous_iterator<range_snapshotting_iterator<T>, T &, T *>,
296  public operator_base<T> {
297  using iterator_category = std::random_access_iterator_tag;
298  using value_type = T;
299  using difference_type = std::ptrdiff_t;
300  using reference = T &;
301  using pointer = T *;
303  reference, pointer>;
304 
309  range_snapshotting_iterator(pointer ptr = nullptr,
310  pointer data = nullptr,
311  std::size_t size = 0,
312  std::size_t snapshot_size = 1)
313  : base_type(ptr),
314  data(data),
315  size(size),
316  snapshot_size(snapshot_size)
317  {
318  assert(data <= ptr);
319 
320  if (snapshot_size > 0)
321  snapshot_range(ptr);
322  }
323 
329  reference operator[](std::ptrdiff_t n)
330  {
331  detail::conditional_add_to_tx(&this->ptr[n]);
332  return base_type::operator[](n);
333  }
334 
338  friend void
340  {
341  std::swap(lhs.ptr, rhs.ptr);
342  std::swap(lhs.data, rhs.data);
343  std::swap(lhs.size, rhs.size);
344  std::swap(lhs.snapshot_size, rhs.snapshot_size);
345  }
346 
347  template <typename Iterator, typename Reference, typename Pointer>
348  friend struct contiguous_iterator;
349 
350 protected:
351  void
352  change_by(std::ptrdiff_t n)
353  {
354  conditional_snapshot_range(this->ptr, n);
356  }
357 
358 private:
359  /*
360  * Conditionally snapshot range of length snapshot_size,
361  * which contain address equal to ptr + diff.
362  */
363  void
364  conditional_snapshot_range(pointer ptr, difference_type diff)
365  {
366  if (snapshot_size == 0)
367  return;
368 
369  auto new_ptr = ptr + diff;
370 
371  /* if new pointer is outside of the array */
372  if (new_ptr < data || new_ptr >= data + size)
373  return;
374 
375  /* if new pointer is in the same range */
376  if (static_cast<std::size_t>(ptr - data) / snapshot_size ==
377  static_cast<std::size_t>(new_ptr - data) / snapshot_size)
378  return;
379 
380  snapshot_range(new_ptr);
381  }
382 
383  void
384  snapshot_range(pointer ptr)
385  {
386  /* align index to snapshot_size */
387  auto range_begin =
388  ptr - static_cast<uint64_t>(ptr - data) % snapshot_size;
389  auto range_size = snapshot_size;
390 
391  if (range_begin + range_size > data + size)
392  range_size = static_cast<uint64_t>(data + size -
393  range_begin);
394 #ifndef NDEBUG
395  verify_range(range_begin, range_size);
396 #endif
397 
398  detail::conditional_add_to_tx(range_begin, range_size);
399  }
400 
401 #ifndef NDEBUG
402  void
403  verify_range(pointer range_begin, uint64_t range_size)
404  {
405  auto range_offset = static_cast<uint64_t>(range_begin - data);
406 
407  assert(range_begin >= data);
408  assert(range_offset % snapshot_size == 0);
409  assert((range_offset + range_size) % snapshot_size == 0 ||
410  range_begin + range_size == data + size);
411  }
412 #endif
413 
414  pointer data;
415  std::size_t size;
416  std::size_t snapshot_size;
417 };
418 
423 template <typename T>
425  : public contiguous_iterator<basic_contiguous_iterator<T>, T &, T *>,
426  public operator_base<T> {
427  using iterator_category = std::random_access_iterator_tag;
428  using value_type = T;
429  using difference_type = std::ptrdiff_t;
430  using reference = T &;
431  using pointer = T *;
433  reference, pointer>;
434 
439  basic_contiguous_iterator(pointer ptr = nullptr) : base_type(ptr)
440  {
441  }
442 
447  reference operator*() const
448  {
449  detail::conditional_add_to_tx(this->ptr);
450  return base_type::operator*();
451  }
452 
457  pointer operator->() const
458  {
459  detail::conditional_add_to_tx(this->ptr);
460  return base_type::operator->();
461  }
462 
468  reference operator[](std::ptrdiff_t n)
469  {
470  detail::conditional_add_to_tx(&this->ptr[n]);
471  return base_type::operator[](n);
472  }
473 
477  friend void
479  {
480  std::swap(lhs.ptr, rhs.ptr);
481  }
482 };
483 
487 template <typename T>
489  : public contiguous_iterator<const_contiguous_iterator<T>, const T &,
490  const T *>,
491  public operator_base<T> {
492  using iterator_category = std::random_access_iterator_tag;
493  using value_type = T;
494  using difference_type = std::ptrdiff_t;
495  using reference = const T &;
496  using pointer = const T *;
498  reference, pointer>;
499 
503  const_contiguous_iterator(pointer ptr = nullptr) : base_type(ptr)
504  {
505  }
506 
511  : base_type(other.get_ptr())
512  {
513  }
514 
519  : base_type(other.get_ptr())
520  {
521  }
522 
526  friend void
528  {
529  std::swap(lhs.ptr, rhs.ptr);
530  }
531 };
532 
533 } /* namespace experimental */
534 
535 } /* namespace obj */
536 
537 } /* namespace pmem */
538 
539 #endif /* LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP */
pmem::obj::experimental::operator_base::operator!=
friend bool operator!=(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member not equal operator.
Definition: contiguous_iterator.hpp:231
pmem::obj::experimental::operator_base
This struct provides comparison operators between const_contiguous_iterator for specified type (as al...
Definition: contiguous_iterator.hpp:216
pmem::obj::experimental::contiguous_iterator::operator--
Iterator operator--(int)
Postfix decrement operator.
Definition: contiguous_iterator.hpp:120
common.hpp
Commonly used functionality.
pmem::obj::experimental::operator_base::operator<
friend bool operator<(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member less than operator.
Definition: contiguous_iterator.hpp:241
pmem::obj::experimental::const_contiguous_iterator::const_contiguous_iterator
const_contiguous_iterator(pointer ptr=nullptr)
Constructor taking pointer as argument.
Definition: contiguous_iterator.hpp:503
pmem::obj::experimental::begin
pmem::obj::experimental::array< T, N >::iterator begin(pmem::obj::experimental::array< T, N > &a)
Non-member begin.
Definition: array.hpp:691
pmem::obj::experimental::contiguous_iterator::operator-
friend std::ptrdiff_t operator-(const Iterator &lhs, const Iterator &rhs)
Subtraction operator overload Iterator type.
Definition: contiguous_iterator.hpp:173
pmem::obj::experimental::operator_base::operator>=
friend bool operator>=(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member greater or equal operator.
Definition: contiguous_iterator.hpp:271
pmem::obj::experimental::contiguous_iterator::operator[]
Reference operator[](std::ptrdiff_t n)
Element access operator.
Definition: contiguous_iterator.hpp:181
pmem::obj::experimental::contiguous_iterator
Base class for iterators which satisfies RandomAccessIterator and operate on contiguous memory.
Definition: contiguous_iterator.hpp:61
pmem::obj::experimental::const_contiguous_iterator::const_contiguous_iterator
const_contiguous_iterator(const range_snapshotting_iterator< T > &other)
Conversion operator from non-const iterator.
Definition: contiguous_iterator.hpp:518
pmem::obj::experimental::basic_contiguous_iterator::basic_contiguous_iterator
basic_contiguous_iterator(pointer ptr=nullptr)
Constructor taking pointer and snapshotting function as arguments.
Definition: contiguous_iterator.hpp:439
pmem::obj::experimental::contiguous_iterator::operator->
Pointer operator->() const
Arrow operator.
Definition: contiguous_iterator.hpp:80
pmem::obj::experimental::contiguous_iterator::operator*
Reference operator*() const
Dereference operator.
Definition: contiguous_iterator.hpp:72
pmem::obj::experimental::range_snapshotting_iterator::range_snapshotting_iterator
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:309
pmem::obj::experimental::contiguous_iterator::operator+
Iterator operator+(std::ptrdiff_t n)
Addition operator.
Definition: contiguous_iterator.hpp:151
pmem::obj::experimental::contiguous_iterator::change_by
void change_by(std::ptrdiff_t n)
Function for changing underlying pointer.
Definition: contiguous_iterator.hpp:199
pmem::obj::experimental::const_contiguous_iterator::swap
friend void swap(const_contiguous_iterator &lhs, const_contiguous_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:527
pmem::obj::experimental::contiguous_iterator::operator-=
Iterator & operator-=(std::ptrdiff_t n)
Subtraction assignment operator.
Definition: contiguous_iterator.hpp:141
pmem::obj::experimental::const_contiguous_iterator
Const iterator.
Definition: contiguous_iterator.hpp:491
pmem::obj::experimental::basic_contiguous_iterator::swap
friend void swap(basic_contiguous_iterator &lhs, basic_contiguous_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:478
pmem::obj::experimental::contiguous_iterator::contiguous_iterator
constexpr contiguous_iterator(Pointer begin)
Constructor taking a pointer.
Definition: contiguous_iterator.hpp:65
pmem::obj::experimental::basic_contiguous_iterator::operator*
reference operator*() const
Dereference operator which adds dereferenced element to a transaction.
Definition: contiguous_iterator.hpp:447
pmem::obj::experimental::operator_base::operator==
friend bool operator==(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member equal operator.
Definition: contiguous_iterator.hpp:221
pmem::obj::experimental::range_snapshotting_iterator
Non-const iterator which adds elements to a transaction in a bulk.
Definition: contiguous_iterator.hpp:296
pmem::obj::experimental::range_snapshotting_iterator::swap
friend void swap(range_snapshotting_iterator &lhs, range_snapshotting_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:339
pmem::obj::experimental::range_snapshotting_iterator::operator[]
reference operator[](std::ptrdiff_t n)
Element access operator.
Definition: contiguous_iterator.hpp:329
pmem::obj::experimental::operator_base::operator<=
friend bool operator<=(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member less or equal operator.
Definition: contiguous_iterator.hpp:261
pmem::obj::experimental::contiguous_iterator::operator-
Iterator operator-(std::ptrdiff_t n)
Subtraction operator overload for integral type.
Definition: contiguous_iterator.hpp:162
pmem::obj::experimental::contiguous_iterator::operator--
Iterator & operator--()
Prefix decrement operator.
Definition: contiguous_iterator.hpp:110
pmem::obj::experimental::basic_contiguous_iterator::operator->
pointer operator->() const
Arrow operator which adds underlying element to a transactions.
Definition: contiguous_iterator.hpp:457
pmem::obj::experimental::const_contiguous_iterator::const_contiguous_iterator
const_contiguous_iterator(const basic_contiguous_iterator< T > &other)
Conversion operator from non-const iterator.
Definition: contiguous_iterator.hpp:510
pmem::obj::experimental::contiguous_iterator::operator+=
Iterator & operator+=(std::ptrdiff_t n)
Addition assignment operator.
Definition: contiguous_iterator.hpp:131
pmem::obj::experimental::basic_contiguous_iterator::operator[]
reference operator[](std::ptrdiff_t n)
Element access operator.
Definition: contiguous_iterator.hpp:468
pmem::obj::experimental::contiguous_iterator::operator++
Iterator operator++(int)
Postfix increment operator.
Definition: contiguous_iterator.hpp:99
pmem::obj::experimental::basic_contiguous_iterator
Default non-const iterator which adds element to a transaction on every access.
Definition: contiguous_iterator.hpp:426
pmem::obj::experimental::contiguous_iterator::operator++
Iterator & operator++()
Prefix increment operator.
Definition: contiguous_iterator.hpp:89
pmem::obj::experimental::operator_base::operator>
friend bool operator>(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member greater than operator.
Definition: contiguous_iterator.hpp:251