OTB  10.0.0
Orfeo Toolbox
otbZipIterator.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbZipIterator_h
22 #define otbZipIterator_h
23 
24 #include "otbIteratorHelpers.h"
25 #include "otbSpan.h"
26 #include "itkMacro.h"
27 #include <type_traits>
28 #include <vector>
29 #include <cassert>
30 
31 namespace otb
32 {
33 namespace internals
34 {
35 
46 template <typename TImageIterator, typename ConstOrMutable>
48 {
49 public:
50 
53 
55  using ImageIteratorType = TImageIterator;
56 
58  using ImageType = typename TImageIterator::ImageType;
59 
64  static constexpr unsigned int ImageIteratorDimension = ImageIteratorType::ImageIteratorDimension;
65 
66  using Self = ZipIterator;
67 
70 
72  using IndexType = typename ImageIteratorType::IndexType;
73 
75  using SizeType = typename ImageIteratorType::SizeType;
76 
78  using OffsetType = typename ImageIteratorType::OffsetType;
79 
81  using RegionType = typename ImageIteratorType::RegionType;
82 
86  using PixelContainer = typename ImageIteratorType::PixelContainer;
87  using PixelContainerPointer = typename PixelContainer::Pointer;
88 
90  using InternalPixelType = typename ImageIteratorType::InternalPixelType;
91 
93  using PixelType = typename ImageIteratorType::PixelType;
94 
97  using AccessorType = typename ImageIteratorType::AccessorType;
98  using AccessorFunctorType = typename ImageIteratorType::AccessorFunctorType;
100 
106  ZipIterator () = default;
107  ~ZipIterator () = default;
108  ZipIterator (ZipIterator const&) = default;
109  ZipIterator (ZipIterator &&) = default;
110  ZipIterator& operator=(ZipIterator const&) = default;
113 
118  template <bool IsConst_ = std::is_same<ConstOrMutable, ConstTag>::value, class = std::enable_if<IsConst_>>
120  : m_iterators(rhs.m_iterators())
121  {}
122 
127  template <bool IsConst_ = std::is_same<ConstOrMutable, ConstTag>::value, class = std::enable_if<IsConst_>>
129  : m_iterators(move(rhs.m_iterators()))
130  {}
131 
140  {
141  assert(! images.empty());
142  m_iterators.reserve(images.size());
144 
145  for (auto & im: images)
146  m_iterators.emplace_back(im, region);
147  }
148 
149  // static_assert(std::is_copy_constructible<Self>::value, "Requires copy construction");
150  // static_assert(std::is_trivially_copy_constructible<Self>::value, "Requires trivial copy construction");
152 
155  friend bool operator==(ZipIterator const& lhs, ZipIterator const& rhs)
156  {
157  assert(!lhs.m_iterators.empty());
158  assert(lhs.m_iterators.size() == rhs.m_iterators.size());
160 
161  return lhs.m_iterators.front() == rhs.m_iterators.front();
162  }
163  friend bool operator!=(ZipIterator const& lhs, ZipIterator const& rhs)
164  { return ! (lhs == rhs); }
165 
166  friend bool operator<=(ZipIterator const& lhs, ZipIterator const& rhs)
167  {
168  assert(!lhs.m_iterators.empty());
169  assert(lhs.m_iterators.size() == rhs.m_iterators.size());
170 
171  return lhs.m_iterators.front() <= rhs.m_iterators.front();
172  }
173  friend bool operator<(ZipIterator const& lhs, ZipIterator const& rhs)
174  {
175  assert(!lhs.m_iterators.empty());
176  assert(lhs.m_iterators.size() == rhs.m_iterators.size());
177 
178  return lhs.m_iterators.front() < rhs.m_iterators.front();
179  }
180  friend bool operator>=(ZipIterator const& lhs, ZipIterator const& rhs)
181  { return ! (lhs < rhs); }
182  friend bool operator>(ZipIterator const& lhs, ZipIterator const& rhs)
183  { return ! (lhs <= rhs); }
185 
188  // What about GetIndex() and SetIndex ?
189 
191  auto const& GetRegion() const
192  {
193  assert(!m_iterators.empty());
194  return m_iterators.front().GetRegion();
195  }
197 
199  void SetRegion(RegionType const& region)
200  {
201  for (auto & it : m_iterators)
202  it.SetRegion(region);
203  }
204 
207  for (auto & it : m_iterators)
208  it.GoToBegin();
209  return *this;
210  }
211 
214  for (auto & it : m_iterators)
215  it.GoToEnd();
216  return *this;
217  }
219 
221  bool IsAtBegin() const {
222  assert(!m_iterators.empty());
223  return m_iterators.front().IsAtBegin();
224  }
226 
228  bool IsAtEnd() const {
229  assert(!m_iterators.empty());
230  return m_iterators.front().IsAtEnd();
231  }
233 
238  assert(!IsAtEnd());
239  for (auto & it : m_iterators)
240  ++it;
241  return *this;
242  }
243 
247  Self operator++(int) = delete;
248 
250  using ImageIteratorList_t = std::vector<ImageIteratorType>;
251 
258  {
259 
263  explicit PixelListProxy(ImageIteratorList_t const& iterators) noexcept
264  : m_iterators(iterators)
265  {}
266  bool empty() const noexcept {return m_iterators.empty();}
267  auto size() const noexcept {return m_iterators.size();}
269 
275  struct iterator__
276  {
277  using difference_type = typename ImageIteratorList_t::difference_type;
278  using value_type = decltype(typename ImageIteratorList_t::const_iterator{}->Get());
279  using pointer = value_type*;
281  using iterator_category = std::forward_iterator_tag;
283 
284  explicit iterator__(typename ImageIteratorList_t::const_iterator ref)
285  : reference_to_value(ref){}
286  friend bool operator==(iterator__ const& lhs, iterator__ const& rhs) noexcept
287  { return lhs.reference_to_value == rhs.reference_to_value;}
288  friend bool operator!=(iterator__ const& lhs, iterator__ const& rhs) noexcept
289  { return ! (lhs == rhs);}
290  iterator__ & operator++() noexcept {
292  return *this;
293  }
294  iterator__ & operator--() noexcept {
296  return *this;
297  }
298  iterator__ operator+(std::ptrdiff_t offset) const noexcept{
299  return iterator__{reference_to_value + offset};
300  }
301  iterator__ operator-(std::ptrdiff_t offset) const noexcept{
302  return iterator__{reference_to_value - offset};
303  }
304  decltype(auto) operator*() const {
305  return reference_to_value->Get();
306  }
307 
308  private:
309  typename ImageIteratorList_t::const_iterator reference_to_value;
310  };
311 
312  auto begin() noexcept { return iterator__(m_iterators.begin()); }
313  auto end() noexcept { return iterator__{m_iterators.end()}; }
314  auto begin() const noexcept { return iterator__{m_iterators.begin()}; }
315  auto end() const noexcept { return iterator__{m_iterators.end()}; }
316  auto cbegin() const noexcept { return iterator__{m_iterators.cbegin()}; }
317  auto cend() const noexcept { return iterator__{m_iterators.cend()}; }
318 
319  decltype(auto) operator[](std::size_t idx) const {
320  assert(idx < size());
321  return m_iterators[idx].Get();
322  }
323  decltype(auto) operator[](std::size_t idx) {
324  assert(idx < size());
325  return m_iterators[idx].Get();
326  }
327 
328  decltype(auto) front() const {
329  assert(!empty());
330  return m_iterators.front().Get();
331  }
332  decltype(auto) front() {
333  assert(!empty());
334  return m_iterators.front().Get();
335  }
336  decltype(auto) back() const {
337  assert(!empty());
338  return m_iterators.back().Get();
339  }
340  decltype(auto) back() {
341  assert(!empty());
342  return m_iterators.back().Get();
343  }
344  private:
346  };
347 
351  PixelListProxy Get() const {
352  return PixelListProxy{m_iterators};
353  }
354 
356 
359  template <typename MultiCompPixelType>
360  void Set(MultiCompPixelType const& p)
361  {
362  assert(p.size() == m_iterators.size());
363  for (std::size_t i = 0; i!=m_iterators.size(); ++i)
364  {
365  m_iterators[i].Set(p[i]);
366  }
367  }
368  // PixelType & Value(); -- cannot be defined and still preserve direct access
369  // to memory => we don't provide it.
371 
372  // ImageType * GetImages();
374 
377 
380  for (auto & it : m_iterators)
381  it.NextLine();
382  return *this;
383  }
384 
387  for (auto & it : m_iterators)
388  it.GoToBeginOfLine();
389  return *this;
390  }
391 
394  for (auto & it : m_iterators)
395  it.GoToEndOfLine();
396  return *this;
397  }
398 
402  bool IsAtEndOfLine() const {
403  assert(!m_iterators.empty());
404  // Const qualifier has been added to ScanLineIterator::IsAtEndOfLine in ITK
405  // 5.1 => Use const_cast in the mean time...
406  return const_cast<typename ImageIteratorList_t::value_type &>(m_iterators.front()).IsAtEndOfLine();
407  }
409 
410 
411 private:
413 };
414 
415 } // otb::internal namespace
416 
424 template <typename TImageIterator>
426 
434 template <typename TImageIterator>
436 
437 } // otb namespace
438 
439 #endif // otbZipIterator_h
typename ImageIteratorType::PixelType PixelType
typename ImageIteratorType::SizeType SizeType
PixelListProxy Get() const
typename ImageIteratorType::RegionType RegionType
ZipIterator(Span< ImageType *const > images, RegionType const &region)
friend bool operator<(ZipIterator const &lhs, ZipIterator const &rhs)
typename PixelContainer::Pointer PixelContainerPointer
ZipIterator(ZipIterator const &)=default
std::vector< ImageIteratorType > ImageIteratorList_t
Self operator++(int)=delete
friend bool operator!=(ZipIterator const &lhs, ZipIterator const &rhs)
friend bool operator<=(ZipIterator const &lhs, ZipIterator const &rhs)
typename TImageIterator::ImageType ImageType
typename ImageIteratorType::IndexType IndexType
auto const & GetRegion() const
typename ImageIteratorType::OffsetType OffsetType
friend bool operator>(ZipIterator const &lhs, ZipIterator const &rhs)
friend bool operator==(ZipIterator const &lhs, ZipIterator const &rhs)
friend bool operator>=(ZipIterator const &lhs, ZipIterator const &rhs)
ZipIterator & operator=(ZipIterator &&)=default
itkTypeMacroNoParent(ZipIterator)
TImageIterator ImageIteratorType
ZipIterator(ZipIterator &&)=default
ZipIterator & operator=(ZipIterator const &)=default
ImageIteratorList_t m_iterators
void SetRegion(RegionType const &region)
typename ImageIteratorType::AccessorFunctorType AccessorFunctorType
static constexpr unsigned int ImageIteratorDimension
typename ImageIteratorType::PixelContainer PixelContainer
typename ImageIteratorType::InternalPixelType InternalPixelType
typename ImageIteratorType::AccessorType AccessorType
void Set(MultiCompPixelType const &p)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
constexpr bool empty() const noexcept
Definition: otbSpan.h:175
constexpr index_type size() const noexcept
Definition: otbSpan.h:174
iterator__ operator+(std::ptrdiff_t offset) const noexcept
iterator__(typename ImageIteratorList_t::const_iterator ref)
iterator__ operator-(std::ptrdiff_t offset) const noexcept
friend bool operator==(iterator__ const &lhs, iterator__ const &rhs) noexcept
typename ImageIteratorList_t::difference_type difference_type
friend bool operator!=(iterator__ const &lhs, iterator__ const &rhs) noexcept
decltype(typename ImageIteratorList_t::const_iterator{}->Get()) value_type
ImageIteratorList_t::const_iterator reference_to_value
ImageIteratorList_t const & m_iterators
PixelListProxy(ImageIteratorList_t const &iterators) noexcept