Loading...
Searching...
No Matches
coordinate_matrix.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 <seqan3/alignment/matrix/detail/matrix_coordinate.hpp>
#include <seqan3/core/detail/template_inspection.hpp>
#include <seqan3/utility/container/aligned_allocator.hpp>
#include <seqan3/utility/simd/algorithm.hpp>
#include <seqan3/utility/simd/concept.hpp>
#include <seqan3/utility/simd/simd_traits.hpp>
#include <seqan3/utility/simd/views/iota_simd.hpp>
#include <seqan3/utility/type_traits/lazy_conditional.hpp>
namespace seqan3::detail
{
//------------------------------------------------------------------------------
// coordinate_matrix
//------------------------------------------------------------------------------
template <typename index_t>
requires (std::integral<index_t> || simd_index<index_t>)
class coordinate_matrix
{
private:
struct convert_to_matrix_coordinate
{
index_t column_index{};
auto operator()(index_t const row_index) noexcept
{
return matrix_index<index_t>{row_index_type{row_index}, column_index_type{column_index}};
}
};
template <typename simd_index_t>
using lazy_scalar_type_t = typename simd_traits<simd_index_t>::scalar_type;
using size_type = lazy_conditional_t<simd_concept<index_t>, lazy<lazy_scalar_type_t, index_t>, index_t>;
// The coordinate matrix iterator.
class iterator;
size_type column_count{};
size_type row_count{};
public:
coordinate_matrix() = default;
coordinate_matrix(coordinate_matrix const &) = default;
coordinate_matrix(coordinate_matrix &&) = default;
coordinate_matrix & operator=(coordinate_matrix const &) = default;
coordinate_matrix & operator=(coordinate_matrix &&) = default;
~coordinate_matrix() = default;
template <std::integral column_index_t, std::integral row_index_t>
void resize(column_index_type<column_index_t> const column_count,
row_index_type<row_index_t> const row_count) noexcept
{
this->column_count = column_count.get();
this->row_count = row_count.get();
}
iterator begin() const noexcept
{
return iterator{size_type{}, row_count};
}
iterator end() const noexcept
{
return iterator{column_count, row_count};
}
};
//------------------------------------------------------------------------------
// iterator
//------------------------------------------------------------------------------
template <typename index_t>
requires (std::integral<index_t> || simd_index<index_t>)
class coordinate_matrix<index_t>::iterator
{
private:
using iota_view_t = lazy_conditional_t<simd_index<index_t>,
lazy<iota_simd_view, index_t>,
decltype(std::views::iota(size_type{}, size_type{}))>;
index_t column_id{0};
size_type row_count{0};
public:
using value_type = decltype(std::declval<iota_view_t>()
| std::views::transform(convert_to_matrix_coordinate{index_t{} /*column_id*/}));
using reference = value_type;
using pointer = void;
using difference_type = std::ptrdiff_t;
using iterator_category = std::forward_iterator_tag;
iterator() = default;
iterator(iterator const &) = default;
iterator(iterator &&) = default;
iterator & operator=(iterator const &) = default;
iterator & operator=(iterator &&) = default;
~iterator() = default;
explicit iterator(size_type column_id, size_type row_count) noexcept : row_count{std::move(row_count)}
{
if constexpr (simd_index<index_t>)
this->column_id = simd::fill<index_t>(std::move(column_id));
else
this->column_id = std::move(column_id);
}
auto operator*() const
{
if constexpr (simd_index<index_t>)
{
return views::iota_simd<index_t>(size_type{}, row_count)
| std::views::transform(convert_to_matrix_coordinate{column_id});
}
else
{
return std::views::iota(size_type{}, row_count)
| std::views::transform(convert_to_matrix_coordinate{column_id});
}
}
iterator & operator++()
{
// clang: pre-increment of a SIMD vector does not work
if constexpr (simd_index<index_t>)
column_id = column_id + simd::fill<index_t>(1);
else
++column_id;
return *this;
}
iterator operator++(int)
{
iterator tmp{*this};
++(*this);
return tmp;
}
friend bool operator==(iterator const & lhs, iterator const & rhs)
{
if constexpr (simd_index<index_t>)
return lhs.column_id[0] == rhs.column_id[0];
else
return lhs.column_id == rhs.column_id;
}
friend bool operator!=(iterator const & lhs, iterator const & rhs)
{
return !(lhs == rhs);
}
};
} // namespace seqan3::detail
aligned_allocator.hpp
Provides seqan3::aligned_allocator.
std::begin
T begin(T... args)
std::declval
T declval(T... args)
std::end
T end(T... args)
lazy_conditional.hpp
Provides lazy template instantiation traits.
matrix_coordinate.hpp
Provides seqan3::detail::matrix_index, seqan3::detail::matrix_coordinate and associated strong types.
template_inspection.hpp
Provides type traits for working with templates.
Hide me