Newer
Older
/*
* Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbVLVPointVLVPointIterator_h
#define otbVLVPointVLVPointIterator_h
#include "itkVariableLengthVector.h"
#include <iterator>
#include <type_traits>
#include <cassert>
namespace otb
{
/**
* C++ standard compliant iterator for contiguous arrays of
* `itk::VariableLengthVector`.
* This minimalist iterator permits the building block to define iterable
* ranges over set of `itk::VariableLengthVector` that can then be used in C++
* \internal The important part is that `+1` needs to take the number of
* components/bands into account.
* \tparam T sub-pixel data type
*/
template <typename T>
struct VLVPointIterator
{
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = itk::VariableLengthVector<typename std::remove_cv<T>::type>;
explicit VLVPointIterator(T* p, unsigned nb_bands) noexcept
: m_p(p), m_nb_bands(nb_bands)
{}
VLVPointIterator& operator+=(difference_type o) noexcept {
m_p += o * m_nb_bands;
return *this;
}
friend VLVPointIterator operator+(VLVPointIterator it, difference_type o) noexcept {
friend VLVPointIterator operator+(difference_type o, VLVPointIterator it) noexcept {
VLVPointIterator& operator-=(difference_type o) noexcept {
m_p -= o * m_nb_bands;
return *this;
}
friend VLVPointIterator operator-(VLVPointIterator it, difference_type o) noexcept {
friend difference_type operator-(VLVPointIterator const& lhs, VLVPointIterator const& rhs) noexcept {
assert(lhs.m_nb_bands == rhs.m_nb_bands);
return (lhs.m_p - rhs.m_p) / lhs.m_nb_bands;
}
VLVPointIterator& operator++() noexcept {
m_p += m_nb_bands;
return *this;
}
VLVPointIterator operator++(int) noexcept {
auto tmp = *this;
m_p += m_nb_bands;
return tmp;
}
VLVPointIterator& operator--() noexcept {
m_p -= m_nb_bands;
return *this;
}
VLVPointIterator operator--(int) noexcept {
auto tmp = *this;
m_p -= m_nb_bands;
return tmp;
}
#if 0
T& operator[](unsigned p) noexcept {
assert(p < m_nb_bands);
return m_p[p];
}
T const& operator[](unsigned p) const noexcept {
assert(p < m_nb_bands);
return m_p[p];
}
reference operator*() const noexcept {
return itk::VariableLengthVector<typename std::remove_cv<T>::type>(m_p, m_nb_bands);
}
decltype(auto) data() const noexcept { return m_p; }
friend bool operator==(VLVPointIterator const& rhs, VLVPointIterator const& lhs) noexcept
{ return rhs.m_p == lhs.m_p; }
friend bool operator!=(VLVPointIterator const& rhs, VLVPointIterator const& lhs) noexcept
{ return rhs.m_p != lhs.m_p; }
friend bool operator<=(VLVPointIterator const& rhs, VLVPointIterator const& lhs) noexcept
{ return rhs.m_p <= lhs.m_p; }
friend bool operator<(VLVPointIterator const& rhs, VLVPointIterator const& lhs) noexcept
{ return rhs.m_p < lhs.m_p; }
friend bool operator>(VLVPointIterator const& rhs, VLVPointIterator const& lhs) noexcept
{ return rhs.m_p > lhs.m_p; }
friend bool operator>=(VLVPointIterator const& rhs, VLVPointIterator const& lhs) noexcept
{ return rhs.m_p >= lhs.m_p; }
// itk::VariableLengthVector<typename std::remove_cv<T>::type> operator*() noexcept {
// return itk::VariableLengthVector<T>(m_p, m_nb_bands);
// }
private:
T* m_p;
unsigned m_nb_bands;
};
} // otb namespace
#endif // otbVLVPointVLVPointIterator_h