Serialbox  2.2.0
Data serialization library and tools for C/C++, Python and Fortran
StorageViewIterator.h
Go to the documentation of this file.
1 //===-- serialbox/core/StorageViewIterator.h ----------------------------------------*- C++ -*-===//
2 //
3 // S E R I A L B O X
4 //
5 // This file is distributed under terms of BSD license.
6 // See LICENSE.txt for more information.
7 //
8 //===------------------------------------------------------------------------------------------===//
9 //
13 //===------------------------------------------------------------------------------------------===//
14 
15 #ifndef SERIALBOX_CORE_STORAGEVIEWITERATOR_H
16 #define SERIALBOX_CORE_STORAGEVIEWITERATOR_H
17 
19 #include "serialbox/core/Slice.h"
20 #include "serialbox/core/Type.h"
21 #include <iterator>
22 #include <type_traits>
23 #include <vector>
24 
25 namespace serialbox {
26 
29 
33 template <class ValueType>
35 public:
39  using value_type = ValueType;
40  using diffrence_type = std::ptrdiff_t;
41  using pointer = value_type*;
42  using refrence = value_type&;
44  using iterator_category = std::forward_iterator_tag;
45 
49 
51  StorageViewIteratorBase(const iterator&) = default;
52 
54  StorageViewIteratorBase(iterator&&) = default;
55 
64  StorageViewIteratorBase(value_type* originPtr, int bytesPerElement, const std::vector<int>& dims,
65  const std::vector<int>& strides, const Slice& slice, bool beginning)
66  : dims_(dims), strides_(strides), bytesPerElement_(bytesPerElement), slice_(slice) {
67 
68  if(!(end_ = !beginning)) {
69 
70  if(slice_.empty())
71  index_.resize(dims_.size(), 0);
72  else
73  for(const auto& triple : slice.sliceTriples())
74  index_.push_back(triple.start);
75 
76  originPtr_ = originPtr;
77  curPtr_ = originPtr_ + computeCurrentIndex();
78  }
79  }
80 
84 
86  iterator& operator=(const iterator&) = default;
87 
89  iterator& operator=(iterator&&) = default;
90 
92  bool operator==(const iterator& right) const noexcept {
93  return (curPtr_ == right.curPtr_ || (end_ == true && end_ == right.end_));
94  }
95 
97  bool operator!=(const iterator& right) const noexcept { return (!(*this == right)); }
98 
100  iterator& operator++() noexcept {
101  if(!end_) {
102 
103  //
104  // Unsliced increment
105  //
106  if(slice_.empty()) {
107 
108  // Consecutively increment the dimensions (column-major order)
109  int size = index_.size();
110  for(int i = 0; i < size; ++i)
111  if(SERIALBOX_BUILTIN_LIKELY(++index_[i] < dims_[i]))
112  break;
113  else {
114  index_[i] = 0;
115  // If we overflow in the last dimension we reached the end
116  if(SERIALBOX_BUILTIN_UNLIKELY(i == size - 1))
117  end_ = true;
118  }
119 
120  //
121  // Sliced increment
122  //
123  } else {
124 
125  // Consecutively increment the dimensions (column-major order) with associated step
126  int size = index_.size();
127  const auto& triples = slice_.sliceTriples();
128 
129  for(int i = 0; i < size; ++i)
130  if((index_[i] += triples[i].step) < triples[i].stop)
131  break;
132  else {
133  index_[i] = triples[i].start;
134  // If we overflow in the last dimension we reached the end
135  if(SERIALBOX_BUILTIN_UNLIKELY(i == size - 1))
136  end_ = true;
137  }
138  }
139 
140  // Compute the current data pointer
141  curPtr_ = originPtr_ + computeCurrentIndex();
142  }
143  return (*this);
144  }
145 
147  refrence operator*() noexcept { return *curPtr_; }
148 
150  void swap(iterator& other) noexcept {
151  std::swap(curPtr_, other.curPtr_);
152  index_.swap(other.index_);
153 
154  std::swap(originPtr_, other.originPtr_);
155  dims_.swap(other.dims_);
156  strides_.swap(other.strides_);
157  slice_.swap(other.slice_);
158  std::swap(bytesPerElement_, other.bytesPerElement_);
159  }
160 
162  friend std::ostream& operator<<(std::ostream& stream, const iterator& it) {
163  stream << "StorageViewIterator = {\n";
164  stream << " curPtr: " << static_cast<void*>(it.curPtr_) << "\n";
165  stream << " index: [";
166  for(auto i : it.index_)
167  stream << " " << i;
168  stream << " ]\n end: " << std::boolalpha << it.end_ << "\n";
169  stream << " originPtr: " << static_cast<void*>(it.originPtr_) << "\n";
170  stream << " dims: [";
171  for(auto i : it.dims_)
172  stream << " " << i;
173  stream << " ]\n strides: [";
174  for(auto i : it.strides_)
175  stream << " " << i;
176  stream << " ]\n bytesPerElement: " << it.bytesPerElement_ << "\n";
177  stream << "}\n";
178  return stream;
179  }
180 
182 
184  int bytesPerElement() noexcept { return bytesPerElement_; }
185 
187  value_type* ptr() noexcept { return curPtr_; }
188 
190  template <class T>
191  typename match_cv_qualifier<value_type, T>::type& as() noexcept {
192  return *((T*)(curPtr_));
193  }
194  template <class T>
195  typename match_cv_qualifier<value_type, T>::type& as() const noexcept {
196  return *((T*)(curPtr_));
197  }
198 
200  const std::vector<int>& index() const noexcept { return index_; }
201 
202 protected:
204  int computeCurrentIndex() const noexcept {
205  int pos = 0;
206  const int size = index_.size();
207  for(int i = 0; i < size; ++i)
208  pos += bytesPerElement_ * (strides_[i] * index_[i]);
209  return pos;
210  }
211 
212 protected:
213  // Position in the data
214  value_type* curPtr_;
215  std::vector<int> index_;
216  bool end_;
217 
218  // Associated StorageView
219  value_type* originPtr_;
220  std::vector<int> dims_;
221  std::vector<int> strides_;
222  int bytesPerElement_;
223  Slice slice_;
224 };
225 
230 public:
232 
234  StorageViewIterator(const StorageViewIterator&) = default;
235 
238 
247  StorageViewIterator(Base::value_type* originPtr, int bytesPerElement,
248  const std::vector<int>& dims, const std::vector<int>& strides,
249  const Slice& slice, bool beginning)
250  : Base(originPtr, bytesPerElement, dims, strides, slice, beginning) {}
251 };
252 
257 public:
259 
262 
265 
274  ConstStorageViewIterator(Base::value_type* originPtr, int bytesPerElement,
275  const std::vector<int>& dims, const std::vector<int>& strides,
276  const Slice& slice, bool beginning)
277  : Base(originPtr, bytesPerElement, dims, strides, slice, beginning) {}
278 };
279 
281 
282 } // namespace serialbox
283 
284 #endif
StorageViewIteratorBase(value_type *originPtr, int bytesPerElement, const std::vector< int > &dims, const std::vector< int > &strides, const Slice &slice, bool beginning)
Construct iterator at specific location in the data.
#define SERIALBOX_BUILTIN_LIKELY(x)
Mark this expression as being likely evaluated to "true".
Definition: Compiler.h:110
refrence operator*() noexcept
Derefrence.
#define SERIALBOX_BUILTIN_UNLIKELY(x)
Mark this expression as being likely evaluated to "false".
Definition: Compiler.h:118
friend std::ostream & operator<<(std::ostream &stream, const iterator &it)
Convert to stream.
value_type * ptr() noexcept
Get current data pointer.
Namespace of the serialbox library.
Definition: Archive.h:25
void swap(Slice &other) noexcept
Swap with other
Definition: Slice.h:103
StorageViewIterator(Base::value_type *originPtr, int bytesPerElement, const std::vector< int > &dims, const std::vector< int > &strides, const Slice &slice, bool beginning)
Construct iterator at specific location in the data.
const std::vector< int > & index() const noexcept
Get current index position in the data.
ConstStorageViewIterator(Base::value_type *originPtr, int bytesPerElement, const std::vector< int > &dims, const std::vector< int > &strides, const Slice &slice, bool beginning)
Construct iterator at specific location in the data.
bool operator!=(const iterator &right) const noexcept
Test for inequality.
void swap(iterator &other) noexcept
Swap with other.
iterator & operator=(const iterator &)=default
Copy assignment.
bool operator==(const iterator &right) const noexcept
Test for equality.
Non-mutable forward iterator to access the data of a StorageView.
int computeCurrentIndex() const noexcept
Compute the current linear index in the data according to the index vector.
std::vector< SliceTriple > & sliceTriples() noexcept
Get slice triples.
Definition: Slice.h:106
match_cv_qualifier< value_type, T >::type & as() noexcept
Interpret current data pointer as type ´T´
StorageViewIteratorBase(const iterator &)=default
Copy constructor.
bool empty() const noexcept
Check if slice is empty.
Definition: Slice.h:100
serialbox::Slice slice
Specification of the slice indices which is used for partial loading of serialized data...
Definition: Slice.h:43
iterator & operator++() noexcept
Pre-increment.
Forward iterator to access the data of a StorageView.
int bytesPerElement() noexcept
Get bytes per element.
Specification of the slice indices which is used for partial loading of serialized data...
Definition: Slice.h:53
Mutable forward iterator to access the data of a StorageView.