BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
interleave.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <cmath>
17#include <concepts>
18#include <ranges>
19
21
22namespace bio::ranges::detail
23{
24
25// ============================================================================
26// interleave_fn (adaptor definition)
27// ============================================================================
28
31struct interleave_fn
32{
33private:
35 template <typename irange_t>
36 struct func
37 {
39 std::views::all_t<irange_t> irange;
41 size_t step_size = 0;
42
44 template <typename urng_t>
45 constexpr auto operator()(urng_t && urange, size_t const i) const
47 std::ranges::range_reference_t<decltype(std::as_const(irange))>>
48 {
49 size_t const div = i / (step_size + std::ranges::size(irange));
50 size_t const rest = i % (step_size + std::ranges::size(irange));
51 return (rest < step_size) ? urange[i - div * std::ranges::size(irange)] : irange[rest - step_size];
52 }
53 };
54
55public:
57 template <std::ranges::forward_range inserted_rng_t>
58 constexpr auto operator()(size_t const size, inserted_rng_t && i) const noexcept
59 {
60 return detail::adaptor_from_functor{*this, size, std::views::all(std::forward<inserted_rng_t>(i))};
61 }
62
69 template <std::ranges::range urng_t, std::ranges::range inserted_rng_t>
70 constexpr auto operator()(urng_t && urange, size_t const step_size, inserted_rng_t && irange) const noexcept
71 {
72 static_assert(std::ranges::random_access_range<urng_t>,
73 "The underlying range parameter in views::interleave must model "
74 "std::ranges::random_access_range.");
75 static_assert(std::ranges::viewable_range<urng_t>,
76 "The underlying range parameter in views::interleave must model std::ranges::viewable_range.");
77 static_assert(std::ranges::sized_range<urng_t>,
78 "The underlying range parameter in views::interleave must model std::ranges::sized_range.");
79
80 static_assert(std::ranges::random_access_range<inserted_rng_t>,
81 "The range to be inserted by views::interleave must model std::ranges::forward_range.");
82 static_assert(std::ranges::sized_range<inserted_rng_t>,
83 "The range to be inserted by views::interleave must model std::ranges::sized_range.");
84
85 static_assert(std::common_reference_with<std::ranges::range_reference_t<urng_t>,
86 std::ranges::range_reference_t<inserted_rng_t const>>,
87 "The underlying range and the CONST inserted range must have reference types that have a "
88 "common_reference type.");
89
90 size_t const size =
91 std::ranges::size(urange) +
92 (((std::ranges::size(urange) / step_size) - (std::ranges::size(urange) % step_size == 0 ? 1 : 0)) *
93 std::ranges::size(irange));
94
95 func<std::views::all_t<inserted_rng_t>> fn{.irange = std::views::all(std::forward<inserted_rng_t>(irange)),
96 .step_size = step_size};
97
98 return view_transform_by_pos{std::forward<urng_t>(urange), std::move(fn), size};
99 }
100};
101
102} // namespace bio::ranges::detail
103
104// ============================================================================
105// views::interleave (adaptor instance definition)
106// ============================================================================
107
108namespace bio::ranges::views
109{
110
164inline constexpr auto interleave = detail::interleave_fn{};
165
167
168} // namespace bio::ranges::views
T as_const(T... args)
T div(T... args)
constexpr auto size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:517
constexpr auto interleave
A view that interleaves a given range into another range at regular intervals.
Definition: interleave.hpp:164
The BioC++ namespace for views.
Provides bio::views::transform_by_pos.