Loading...
Searching...
No Matches
translate_join.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 <stdexcept>
#include <vector>
#include <seqan3/alphabet/views/translate.hpp>
#include <seqan3/core/range/type_traits.hpp>
#include <seqan3/utility/container/small_string.hpp>
namespace seqan3::detail
{
// ============================================================================
// view_translate_join (range definition)
// ============================================================================
template <std::ranges::view urng_t>
class view_translate_join : public std::ranges::view_base
{
private:
urng_t urange;
translation_frames tf;
small_vector<translation_frames, 6> selected_frames{};
using reference = view_translate_single<std::views::all_t<std::ranges::range_reference_t<urng_t>>>;
using const_reference = reference;
using value_type = reference;
using size_type = std::ranges::range_size_t<std::ranges::range_reference_t<urng_t>>;
using difference_type = std::ranges::range_difference_t<std::ranges::range_reference_t<urng_t>>;
using iterator = detail::random_access_iterator<view_translate_join>;
using const_iterator = detail::random_access_iterator<view_translate_join const>;
template <typename range_type, template <typename...> typename derived_t_template, typename... args_t>
friend class detail::random_access_iterator_base;
public:
static_assert(range_dimension_v<urng_t> == 2,
"This adaptor only handles range-of-range (two dimensions) as input.");
static_assert(std::ranges::viewable_range<urng_t>,
"The range parameter to views::translate_join cannot be a temporary of a non-view range.");
static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
"The inner range of the range parameter to views::translate_join cannot be a temporary of "
"a non-view range.");
static_assert(std::ranges::sized_range<urng_t>,
"The range parameter to views::translate_join must model std::ranges::sized_range.");
static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
"The inner range of the range parameter to views::translate_join must model "
"std::ranges::sized_range.");
static_assert(std::ranges::random_access_range<urng_t>,
"The range parameter to views::translate_join must model std::ranges::random_access_range.");
static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
"The inner range of the range parameter to views::translate_join must model "
"std::ranges::random_access_range.");
static_assert(nucleotide_alphabet<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
"The range parameter to views::translate_join must be over a range over elements of "
"seqan3::nucleotide_alphabet.");
view_translate_join() noexcept = default;
constexpr view_translate_join(view_translate_join const & rhs) noexcept = default;
constexpr view_translate_join(view_translate_join && rhs) noexcept = default;
constexpr view_translate_join & operator=(view_translate_join const & rhs) noexcept = default;
constexpr view_translate_join & operator=(view_translate_join && rhs) noexcept = default;
~view_translate_join() noexcept = default;
view_translate_join(urng_t _urange, translation_frames const _tf = translation_frames::six_frames) :
urange{std::move(_urange)},
tf{_tf}
{
if ((_tf & translation_frames::forward_frame0) == translation_frames::forward_frame0)
selected_frames.push_back(translation_frames::forward_frame0);
if ((_tf & translation_frames::forward_frame1) == translation_frames::forward_frame1)
selected_frames.push_back(translation_frames::forward_frame1);
if ((_tf & translation_frames::forward_frame2) == translation_frames::forward_frame2)
selected_frames.push_back(translation_frames::forward_frame2);
if ((_tf & translation_frames::reverse_frame0) == translation_frames::reverse_frame0)
selected_frames.push_back(translation_frames::reverse_frame0);
if ((_tf & translation_frames::reverse_frame1) == translation_frames::reverse_frame1)
selected_frames.push_back(translation_frames::reverse_frame1);
if ((_tf & translation_frames::reverse_frame2) == translation_frames::reverse_frame2)
selected_frames.push_back(translation_frames::reverse_frame2);
}
template <typename rng_t>
requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate_join>) && std::ranges::viewable_range<rng_t>
&& std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
view_translate_join(rng_t && _urange, translation_frames const _tf = translation_frames::six_frames) :
view_translate_join{std::views::all(std::forward<rng_t>(_urange)), _tf}
{}
iterator begin() noexcept
{
return {*this, 0};
}
const_iterator begin() const noexcept
requires const_iterable_range<urng_t>
{
return {*this, 0};
}
iterator end() noexcept
{
return {*this, size()};
}
const_iterator end() const noexcept
requires const_iterable_range<urng_t>
{
return {*this, size()};
}
size_type size() noexcept
{
return (size_type)std::ranges::size(urange) * selected_frames.size();
}
size_type size() const noexcept
requires const_iterable_range<urng_t>
{
return (size_type)std::ranges::size(urange) * selected_frames.size();
}
reference operator[](size_type const n)
{
assert(n < size());
size_type index_frame = n % selected_frames.size();
size_type index_urange = (n - index_frame) / selected_frames.size();
return urange[index_urange] | views::translate_single(selected_frames[index_frame]);
}
const_reference operator[](size_type const n) const
requires const_iterable_range<urng_t>
{
assert(n < size());
size_type index_frame = n % selected_frames.size();
size_type index_urange = (n - index_frame) / selected_frames.size();
return urange[index_urange] | views::translate_single(selected_frames[index_frame]);
}
};
template <typename urng_t>
view_translate_join(urng_t &&,
translation_frames const = translation_frames{}) -> view_translate_join<std::views::all_t<urng_t>>;
// ============================================================================
// translate_fn (adaptor definition for both views)
// ============================================================================
struct translate_join_fn
{
constexpr auto operator()(translation_frames const tf = translation_frames::six_frames) const
{
return detail::adaptor_from_functor{*this, tf};
}
template <std::ranges::range urng_t>
constexpr auto operator()(urng_t && urange, translation_frames const tf = translation_frames::six_frames) const
{
static_assert(range_dimension_v<urng_t> == 2,
"This adaptor only handles range-of-range (two dimensions) as input.");
static_assert(std::ranges::viewable_range<urng_t>,
"The range parameter to views::translate_join cannot be a temporary of a non-view range.");
static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
"The inner range of the range parameter to views::translate_join cannot be a "
"temporary of a non-view range.");
static_assert(std::ranges::sized_range<urng_t>,
"The range parameter to views::translate_join must model std::ranges::sized_range.");
static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
"The inner range of the range parameter to views::translate_join must model "
"std::ranges::sized_range.");
static_assert(std::ranges::random_access_range<urng_t>,
"The range parameter to views::translate_join must model std::ranges::random_access_range.");
static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
"The inner range of the range parameter to views::translate_join must model "
"std::ranges::random_access_range.");
static_assert(nucleotide_alphabet<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
"The range parameter to views::translate_join must be over a range over elements of "
"seqan3::nucleotide_alphabet.");
return detail::view_translate_join{std::forward<urng_t>(urange), tf};
}
template <std::ranges::range urng_t>
constexpr friend auto operator|(urng_t && urange, translate_join_fn const & me)
{
return me(std::forward<urng_t>(urange));
}
};
} // namespace seqan3::detail
// ============================================================================
// translate (adaptor object)
// ============================================================================
namespace seqan3::views
{
inline constexpr auto translate_join = detail::translate_join_fn{};
} // namespace seqan3::views
type_traits.hpp
Provides various transformation traits used by the range module.
std::forward
T forward(T... args)
seqan3::views::translate_join
constexpr auto translate_join
A view that translates nucleotide into aminoacid alphabet with 1, 2, 3 or 6 frames....
Definition translate_join.hpp:378
seqan3::views::translate_single
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition translate.hpp:520
seqan3::range_dimension_v
constexpr size_t range_dimension_v
Returns the number of times you can call seqan3::value_type_t recursively on t (type trait).
Definition core/range/type_traits.hpp:112
seqan3::views
The SeqAn namespace for views.
Definition char_strictly_to.hpp:19
seqan3::small_vector
small_vector(value_type const (&array)[capacity2]) -> small_vector< value_type, capacity2 >
Deducts the size and value type from an built-in array on construction.
seqan3::translation_frames
translation_frames
Specialisation values for single and multiple translation frames.
Definition translate.hpp:59
seqan3::translation_frames::forward_frame2
@ forward_frame2
The third forward frame starting at position 2.
Definition translate.hpp:62
seqan3::translation_frames::forward_frame0
@ forward_frame0
The first forward frame starting at position 0.
Definition translate.hpp:60
seqan3::translation_frames::six_frames
@ six_frames
All frames.
Definition translate.hpp:71
seqan3::translation_frames::reverse_frame0
@ reverse_frame0
The first reverse frame starting at position 0.
Definition translate.hpp:63
seqan3::translation_frames::reverse_frame2
@ reverse_frame2
The third reverse frame starting at position 2.
Definition translate.hpp:65
seqan3::translation_frames::forward_frame1
@ forward_frame1
The second forward frame starting at position 1.
Definition translate.hpp:61
seqan3::translation_frames::reverse_frame1
@ reverse_frame1
The second reverse frame starting at position 1.
Definition translate.hpp:64
small_string.hpp
A constexpr string implementation to manipulate string literals at compile time.
stdexcept
translate.hpp
Provides seqan3::views::translate and seqan3::views::translate_single.
vector
Hide me