PMDK C++ bindings  1.2.0
This is the C++ bindings documentation for PMDK's libpmemobj.
contiguous_iterator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018, 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::size_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>
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
241  operator<(const const_contiguous_iterator<T> &lhs,
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
261  operator<=(const const_contiguous_iterator<T> &lhs,
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  snapshot_range(ptr);
321  }
322 
328  reference operator[](std::size_t n)
329  {
330  detail::conditional_add_to_tx(&this->ptr[n]);
331  return base_type::operator[](n);
332  }
333 
337  friend void
339  {
340  std::swap(lhs.ptr, rhs.ptr);
341  std::swap(lhs.data, rhs.data);
342  std::swap(lhs.size, rhs.size);
343  std::swap(lhs.snapshot_size, rhs.snapshot_size);
344  }
345 
346  template <typename Iterator, typename Reference, typename Pointer>
347  friend struct contiguous_iterator;
348 
349 protected:
350  void
351  change_by(std::ptrdiff_t n)
352  {
353  conditional_snapshot_range(this->ptr, n);
354  base_type::change_by(n);
355  }
356 
357 private:
358  /*
359  * Conditionally snapshot range of length snapshot_size,
360  * which contain address equal to ptr + diff.
361  */
362  void
363  conditional_snapshot_range(pointer ptr, difference_type diff)
364  {
365  auto new_ptr = ptr + diff;
366 
367  /* if new pointer is outside of the array */
368  if (new_ptr < data || new_ptr >= data + size)
369  return;
370 
371  /* if new pointer is in the same range */
372  if (static_cast<std::size_t>(ptr - data) / snapshot_size ==
373  static_cast<std::size_t>(new_ptr - data) / snapshot_size)
374  return;
375 
376  snapshot_range(new_ptr);
377  }
378 
379  void
380  snapshot_range(pointer ptr)
381  {
382  /* align index to snapshot_size */
383  auto range_begin =
384  ptr - static_cast<uint64_t>(ptr - data) % snapshot_size;
385  auto range_size = snapshot_size;
386 
387  if (range_begin + range_size > data + size)
388  range_size = static_cast<uint64_t>(data + size -
389  range_begin);
390 #ifndef NDEBUG
391  verify_range(range_begin, range_size);
392 #endif
393 
394  detail::conditional_add_to_tx(range_begin, range_size);
395  }
396 
397 #ifndef NDEBUG
398  void
399  verify_range(pointer range_begin, uint64_t range_size)
400  {
401  auto range_offset = static_cast<uint64_t>(range_begin - data);
402 
403  assert(range_begin >= data);
404  assert(range_offset % snapshot_size == 0);
405  assert((range_offset + range_size) % snapshot_size == 0 ||
406  range_begin + range_size == data + size);
407  }
408 #endif
409 
410  pointer data;
411  std::size_t size;
412  std::size_t snapshot_size;
413 };
414 
419 template <typename T>
421  : public contiguous_iterator<basic_contiguous_iterator<T>, T &, T *>,
422  public operator_base<T> {
423  using iterator_category = std::random_access_iterator_tag;
424  using value_type = T;
425  using difference_type = std::ptrdiff_t;
426  using reference = T &;
427  using pointer = T *;
429  reference, pointer>;
430 
435  basic_contiguous_iterator(pointer ptr = nullptr) : base_type(ptr)
436  {
437  }
438 
443  reference operator*() const
444  {
445  detail::conditional_add_to_tx(this->ptr);
446  return base_type::operator*();
447  }
448 
453  pointer operator->() const
454  {
455  detail::conditional_add_to_tx(this->ptr);
456  return base_type::operator->();
457  }
458 
464  reference operator[](std::size_t n)
465  {
466  detail::conditional_add_to_tx(&this->ptr[n]);
467  return base_type::operator[](n);
468  }
469 
473  friend void
475  {
476  std::swap(lhs.ptr, rhs.ptr);
477  }
478 };
479 
483 template <typename T>
485  : public contiguous_iterator<const_contiguous_iterator<T>, const T &,
486  const T *>,
487  public operator_base<T> {
488  using iterator_category = std::random_access_iterator_tag;
489  using value_type = T;
490  using difference_type = std::ptrdiff_t;
491  using reference = const T &;
492  using pointer = const T *;
494  reference, pointer>;
495 
499  const_contiguous_iterator(pointer ptr = nullptr) : base_type(ptr)
500  {
501  }
502 
507  : base_type(other.get_ptr())
508  {
509  }
510 
515  : base_type(other.get_ptr())
516  {
517  }
518 
522  friend void
524  {
525  std::swap(lhs.ptr, rhs.ptr);
526  }
527 };
528 
529 } /* namespace experimental */
530 
531 } /* namespace obj */
532 
533 } /* namespace pmem */
534 
535 #endif /* LIBPMEMOBJ_CPP_ARRAY_ITERATOR_HPP */
Non-const iterator which adds elements to a transaction in a bulk.
Definition: contiguous_iterator.hpp:294
Iterator & operator+=(std::ptrdiff_t n)
Addition assignment operator.
Definition: contiguous_iterator.hpp:131
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
Default non-const iterator which adds element to a transaction on every access.
Definition: contiguous_iterator.hpp:420
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
reference operator*() const
Dereference operator which adds dereferenced element to a transaction.
Definition: contiguous_iterator.hpp:443
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
Iterator operator--(int)
Postfix decrement operator.
Definition: contiguous_iterator.hpp:120
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
friend void swap(range_snapshotting_iterator &lhs, range_snapshotting_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:338
Iterator & operator++()
Prefix increment operator.
Definition: contiguous_iterator.hpp:89
const_contiguous_iterator(pointer ptr=nullptr)
Constructor taking pointer as argument.
Definition: contiguous_iterator.hpp:499
const_contiguous_iterator(const range_snapshotting_iterator< T > &other)
Conversion operator from non-const iterator.
Definition: contiguous_iterator.hpp:514
friend std::ptrdiff_t operator-(const Iterator &lhs, const Iterator &rhs)
Subtraction operator overload Iterator type.
Definition: contiguous_iterator.hpp:173
void change_by(std::ptrdiff_t n)
Function for changing underlying pointer.
Definition: contiguous_iterator.hpp:199
Commonly used functionality.
friend void swap(basic_contiguous_iterator &lhs, basic_contiguous_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:474
friend bool operator==(const const_contiguous_iterator< T > &lhs, const const_contiguous_iterator< T > &rhs)
Non-member equal operator.
Definition: contiguous_iterator.hpp:221
Iterator & operator-=(std::ptrdiff_t n)
Subtraction assignment operator.
Definition: contiguous_iterator.hpp:141
Iterator operator+(std::ptrdiff_t n)
Addition operator.
Definition: contiguous_iterator.hpp:151
pointer operator->() const
Arrow operator which adds underlying element to a transactions.
Definition: contiguous_iterator.hpp:453
basic_contiguous_iterator(pointer ptr=nullptr)
Constructor taking pointer and snapshotting function as arguments.
Definition: contiguous_iterator.hpp:435
This struct provides comparison operators between const_contigous_iterator for specified type (as all...
Definition: contiguous_iterator.hpp:216
Pointer operator->() const
Arrow operator.
Definition: contiguous_iterator.hpp:80
Base class for iterators which satisfies RandomAccessIterator and operate on contiguous memory...
Definition: contiguous_iterator.hpp:61
Reference operator*() const
Dereference operator.
Definition: contiguous_iterator.hpp:72
constexpr contiguous_iterator(Pointer begin)
Constructor taking a pointer.
Definition: contiguous_iterator.hpp:65
friend void swap(const_contiguous_iterator &lhs, const_contiguous_iterator &rhs)
Non-member swap function.
Definition: contiguous_iterator.hpp:523
Const iterator.
Definition: contiguous_iterator.hpp:208
Iterator & operator--()
Prefix decrement operator.
Definition: contiguous_iterator.hpp:110
Reference operator[](std::size_t n)
Element access operator.
Definition: contiguous_iterator.hpp:181
Iterator operator++(int)
Postfix increment operator.
Definition: contiguous_iterator.hpp:99
reference operator[](std::size_t n)
Element access operator.
Definition: contiguous_iterator.hpp:464
Iterator operator-(std::ptrdiff_t n)
Subtraction operator overload for integral type.
Definition: contiguous_iterator.hpp:162
Definition: allocator.hpp:48
reference operator[](std::size_t n)
Element access operator.
Definition: contiguous_iterator.hpp:328
const_contiguous_iterator(const basic_contiguous_iterator< T > &other)
Conversion operator from non-const iterator.
Definition: contiguous_iterator.hpp:506