Loading...
Searching...
No Matches
two_dimensional_matrix_iterator_base.hpp
Go to the documentation of this file.
// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <concepts>
#include <ranges>
#include <type_traits>
#include <seqan3/alignment/matrix/detail/matrix_coordinate.hpp>
#include <seqan3/core/detail/iterator_traits.hpp>
#include <seqan3/utility/type_traits/basic.hpp>
namespace seqan3::detail
{
enum struct matrix_major_order : uint8_t
{
column,
row
};
template <typename derived_t, matrix_major_order order>
class two_dimensional_matrix_iterator_base
{
private:
friend derived_t;
template <typename other_derived_t, matrix_major_order other_order>
friend class two_dimensional_matrix_iterator_base;
constexpr two_dimensional_matrix_iterator_base() = default;
constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base const &) = default;
constexpr two_dimensional_matrix_iterator_base(two_dimensional_matrix_iterator_base &&) = default;
constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base const &) = default;
constexpr two_dimensional_matrix_iterator_base & operator=(two_dimensional_matrix_iterator_base &&) = default;
~two_dimensional_matrix_iterator_base() = default;
template <typename _derived_t>
using difference_type = typename _derived_t::difference_type;
template <typename _derived_t>
using reference = typename _derived_t::reference;
template <typename _derived_t>
using pointer = typename _derived_t::pointer;
public:
template <typename dummy_t = derived_t>
constexpr reference<dummy_t> operator*() const noexcept
{
return *as_derived().host_iter;
}
template <typename dummy_t = derived_t>
constexpr reference<dummy_t> operator[](std::iter_difference_t<dummy_t> const offset) const noexcept
{
return *(as_derived() + offset);
}
template <typename dummy_t = derived_t>
constexpr reference<dummy_t> operator[](matrix_offset const & offset) const noexcept
{
return *(as_derived() + offset);
}
template <typename dummy_t = derived_t>
constexpr pointer<dummy_t> operator->() const noexcept
{
return std::addressof(*as_derived().host_iter);
}
SEQAN3_DOXYGEN_ONLY(constexpr seqan3::detail::matrix_coordinate coordinate() const noexcept {})
SEQAN3_DOXYGEN_ONLY(constexpr derived_t & operator+=(matrix_offset const & offset) noexcept {})
constexpr derived_t & operator++() noexcept
{
if constexpr (order == matrix_major_order::column)
return as_derived() += matrix_offset{row_index_type{1}, column_index_type{0}};
else
return as_derived() += matrix_offset{row_index_type{0}, column_index_type{1}};
}
constexpr derived_t operator++(int) noexcept
{
derived_t previous{as_derived()};
++(*this);
return previous;
}
template <typename dummy_t = derived_t>
constexpr derived_t & operator+=(std::iter_difference_t<dummy_t> const offset) noexcept
{
if constexpr (order == matrix_major_order::column)
return as_derived() += matrix_offset{row_index_type{offset}, column_index_type{0}};
else
return as_derived() += matrix_offset{row_index_type{0}, column_index_type{offset}};
}
template <typename dummy_t = derived_t>
constexpr derived_t operator+(std::iter_difference_t<dummy_t> const offset) const noexcept
{
derived_t next{as_derived()};
next += offset;
return next;
}
template <typename dummy_t = derived_t>
constexpr friend derived_t operator+(std::iter_difference_t<dummy_t> const offset, derived_t const iter)
{
return iter + offset;
}
constexpr derived_t operator+(matrix_offset const & offset) const noexcept
{
derived_t next{as_derived()};
next += offset;
return next;
}
constexpr friend derived_t operator+(matrix_offset const & offset, derived_t const iter)
{
return iter + offset;
}
constexpr derived_t & operator--() noexcept
{
if constexpr (order == matrix_major_order::column)
return as_derived() += matrix_offset{row_index_type{-1}, column_index_type{0}};
else
return as_derived() += matrix_offset{row_index_type{0}, column_index_type{-1}};
}
constexpr derived_t operator--(int) noexcept
{
derived_t previous{as_derived()};
--(*this);
return previous;
}
template <typename dummy_t = derived_t>
constexpr derived_t & operator-=(std::iter_difference_t<dummy_t> const offset) noexcept
{
return *this += -offset;
}
template <typename dummy_t = derived_t>
constexpr derived_t operator-(std::iter_difference_t<dummy_t> const offset) const noexcept
{
derived_t next{as_derived()};
next -= offset;
return next;
}
constexpr derived_t & operator-=(matrix_offset const & offset) noexcept
{
return as_derived() += matrix_offset{row_index_type{-offset.row}, column_index_type{-offset.col}};
}
constexpr derived_t operator-(matrix_offset const & offset) const noexcept
{
derived_t next{as_derived()};
next -= offset;
return next;
}
template <typename dummy_t = derived_t>
friend constexpr std::iter_difference_t<dummy_t> operator-(derived_t const lhs, derived_t const rhs) noexcept
{
return lhs.as_host_iter() - rhs.as_host_iter();
}
// What if the derived type is different?
// How can make sure this is the same type?
template <typename other_derived_t>
requires std::constructible_from<derived_t, other_derived_t>
|| std::constructible_from<other_derived_t, derived_t>
constexpr bool operator==(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
{
return as_derived().host_iter == rhs.as_derived().host_iter;
}
template <typename other_derived_t>
requires std::constructible_from<derived_t, other_derived_t>
|| std::constructible_from<other_derived_t, derived_t>
constexpr bool operator!=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
{
return !(*this == rhs);
}
template <typename other_derived_t>
requires std::constructible_from<derived_t, other_derived_t>
|| std::constructible_from<other_derived_t, derived_t>
constexpr bool operator<(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
{
return as_derived().host_iter < rhs.as_derived().host_iter;
}
template <typename other_derived_t>
requires std::constructible_from<derived_t, other_derived_t>
|| std::constructible_from<other_derived_t, derived_t>
constexpr bool operator<=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
{
return as_derived().host_iter <= rhs.as_derived().host_iter;
}
template <typename other_derived_t>
requires std::constructible_from<derived_t, other_derived_t>
|| std::constructible_from<other_derived_t, derived_t>
constexpr bool operator>(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
{
return as_derived().host_iter > rhs.as_derived().host_iter;
}
template <typename other_derived_t>
requires std::constructible_from<derived_t, other_derived_t>
|| std::constructible_from<other_derived_t, derived_t>
constexpr bool operator>=(two_dimensional_matrix_iterator_base<other_derived_t, order> const & rhs) const noexcept
{
return as_derived().host_iter >= rhs.as_derived().host_iter;
}
private:
constexpr auto const & as_host_iter() const
{
return as_derived().host_iter;
}
constexpr derived_t & as_derived()
{
return static_cast<derived_t &>(*this);
}
constexpr derived_t const & as_derived() const
{
return static_cast<derived_t const &>(*this);
}
// matrix_iterator_t host_iter{}; //!< The wrapped matrix iterator.
};
} // namespace seqan3::detail
std::addressof
T addressof(T... args)
basic.hpp
Provides various type traits on generic types.
seqan3::field::offset
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
Definition record.hpp:66
iterator_traits.hpp
Provides various transformation traits for use on iterators.
matrix_coordinate.hpp
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
std::next
T next(T... args)
type_traits
Hide me