Loading...
Searching...
No Matches
alignment_matrix_column_major_range_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 <cassert>
#include <iterator>
#include <ranges>
#include <span>
#include <seqan3/core/range/type_traits.hpp>
#include <seqan3/utility/type_traits/basic.hpp>
namespace seqan3::detail
{
template <typename derived_t>
class alignment_matrix_column_major_range_base
{
private:
friend derived_t;
class alignment_column_type : public std::ranges::view_interface<alignment_column_type>
{
private:
using view_type = typename deferred_type<typename derived_t::column_data_view_type>::type;
static_assert(std::ranges::random_access_range<view_type>, "Column view must support random access.");
static_assert(std::ranges::sized_range<view_type>, "Column view must be a sized range.");
static_assert(std::ranges::view<view_type>, "Column view must be a view.");
using sentinel = std::ranges::sentinel_t<view_type>;
class iterator_type
{
public:
using value_type = typename deferred_type<typename derived_t::value_type>::type;
using reference = typename deferred_type<typename derived_t::reference>::type;
using pointer = void;
using difference_type = std::ranges::range_difference_t<view_type>;
using iterator_category = std::forward_iterator_tag;
constexpr iterator_type() = default;
constexpr iterator_type(iterator_type const &) = default;
constexpr iterator_type(iterator_type &&) = default;
constexpr iterator_type & operator=(iterator_type const &) = default;
constexpr iterator_type & operator=(iterator_type &&) = default;
~iterator_type() = default;
explicit constexpr iterator_type(alignment_column_type & host) :
host_ptr{&host},
host_iter{host.ref.begin()}
{
host_ptr->me_ptr->on_column_iterator_creation(host_iter);
}
constexpr reference operator*() const noexcept
{
static_assert(std::convertible_to<decltype(host_ptr->me_ptr->make_proxy(host_iter)), reference>,
"The returned type of make_proxy must be convertible to the reference type.");
assert(host_ptr != nullptr);
return host_ptr->me_ptr->make_proxy(host_iter);
}
constexpr iterator_type & operator++() noexcept
{
assert(host_ptr != nullptr);
assert(host_ptr->me_ptr != nullptr);
host_ptr->me_ptr->before_column_iterator_increment(host_iter);
++host_iter;
host_ptr->me_ptr->after_column_iterator_increment(host_iter);
return *this;
}
constexpr iterator_type operator++(int) noexcept
{
iterator_type tmp{*this};
++(*this);
return tmp;
}
constexpr bool operator==(sentinel const & rhs) const noexcept
{
return host_iter == rhs;
}
friend constexpr bool operator==(sentinel const & lhs, iterator_type const & rhs) noexcept
{
return rhs == lhs;
}
constexpr bool operator==(iterator_type const & rhs) const noexcept
{
return (host_ptr == rhs.host_ptr) && (host_iter == rhs.host_iter);
}
constexpr bool operator!=(sentinel const & rhs) const noexcept
{
return !(*this == rhs);
}
friend constexpr bool operator!=(sentinel const & lhs, iterator_type const & rhs) noexcept
{
return rhs != lhs;
}
constexpr bool operator!=(iterator_type const & rhs) const noexcept
{
return !(*this == rhs);
}
private:
alignment_column_type * host_ptr{nullptr};
std::ranges::iterator_t<view_type> host_iter{};
}; // class iterator_type
public:
constexpr alignment_column_type() = default;
constexpr alignment_column_type(alignment_column_type const &) = default;
constexpr alignment_column_type(alignment_column_type &&) = default;
constexpr alignment_column_type & operator=(alignment_column_type const &) = default;
constexpr alignment_column_type & operator=(alignment_column_type &&) = default;
~alignment_column_type() = default;
constexpr alignment_column_type(derived_t & me, view_type ref) : ref{std::move(ref)}, me_ptr{&me}
{}
constexpr iterator_type begin() noexcept
{
assert(me_ptr != nullptr);
return iterator_type{*this};
}
constexpr auto begin() const noexcept = delete; // Not needed by the alignment algorithm
constexpr sentinel end() noexcept
{
return ref.end();
}
constexpr sentinel end() const noexcept = delete; // Not needed by the alignment algorithm
constexpr size_t size() const noexcept
{
return std::ranges::size(ref);
}
private:
view_type ref{};
derived_t * me_ptr{};
}; // class alignment_column_type
class iterator_type
{
public:
using value_type = alignment_column_type;
using reference = value_type;
using pointer = void;
using difference_type = std::ranges::range_difference_t<alignment_column_type>;
using iterator_category = std::input_iterator_tag;
constexpr iterator_type() = default;
constexpr iterator_type(iterator_type const &) = default;
constexpr iterator_type(iterator_type &&) = default;
constexpr iterator_type & operator=(iterator_type const &) = default;
constexpr iterator_type & operator=(iterator_type &&) = default;
~iterator_type() = default;
explicit constexpr iterator_type(derived_t & me) : me_ptr{&me}, column_index{0}
{}
constexpr reference operator*() const noexcept
{
static_assert(std::convertible_to<decltype(me_ptr->initialise_column(column_index)), reference>,
"The returned type of initialise_column must be convertible to the reference type.");
return me_ptr->initialise_column(column_index);
}
constexpr iterator_type & operator++() noexcept
{
++column_index;
return *this;
}
constexpr void operator++(int) noexcept
{
++(*this);
}
constexpr bool operator==(std::default_sentinel_t const &) const noexcept
{
return column_index == me_ptr->num_cols;
}
friend constexpr bool operator==(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
{
return rhs == lhs;
}
constexpr bool operator!=(std::default_sentinel_t const & rhs) const noexcept
{
return !(*this == rhs);
}
friend constexpr bool operator!=(std::default_sentinel_t const & lhs, iterator_type const & rhs) noexcept
{
return rhs != lhs;
}
private:
derived_t * me_ptr;
size_t column_index{};
}; // class iterator_type
constexpr alignment_matrix_column_major_range_base() = default;
constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base const &) = default;
constexpr alignment_matrix_column_major_range_base(alignment_matrix_column_major_range_base &&) = default;
constexpr alignment_matrix_column_major_range_base &
operator=(alignment_matrix_column_major_range_base const &) = default;
constexpr alignment_matrix_column_major_range_base &
operator=(alignment_matrix_column_major_range_base &&) = default;
~alignment_matrix_column_major_range_base() = default;
SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ value_type;)
SEQAN3_DOXYGEN_ONLY(typedef /*IMPLEMENTATION_DEFINED*/ column_data_view_type;)
SEQAN3_DOXYGEN_ONLY(value_type make_proxy(iter_t host_iter) noexcept {})
SEQAN3_DOXYGEN_ONLY(alignment_column_type initialise_column(size_t column_index){})
template <typename iter_t>
constexpr void on_column_iterator_creation(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
{}
template <typename iter_t>
constexpr void before_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
{}
template <typename iter_t>
constexpr void after_column_iterator_increment(iter_t SEQAN3_DOXYGEN_ONLY(host_iter)) noexcept
{}
using iterator = iterator_type;
using sentinel = std::default_sentinel_t;
public:
constexpr iterator begin() noexcept
{
return iterator{static_cast<derived_t &>(*this)};
}
constexpr iterator begin() const noexcept = delete; // not needed for the alignment algorithm
constexpr sentinel end() noexcept
{
return std::default_sentinel;
}
constexpr sentinel end() const noexcept = delete; // not needed for the alignment algorithm
};
} // namespace seqan3::detail
basic.hpp
Provides various type traits on generic types.
std::begin
T begin(T... args)
cassert
type_traits.hpp
Provides various transformation traits used by the range module.
iterator
std::ref
T ref(T... args)
Hide me