BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
transform_by_pos.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 <utility>
17
21
22namespace bio::ranges::detail
23{
24
29template <std::ranges::view urng_t, typename transform_by_pos_t>
30class view_transform_by_pos : public std::ranges::view_base
31{
32private:
34 urng_t urange;
36 transform_by_pos_t transform_by_pos;
38 size_t _size = 0;
39
40 static_assert(std::ranges::sized_range<urng_t>,
41 "The range parameter to views::transform_by_pos must model std::ranges::sized_range.");
42 static_assert(std::ranges::random_access_range<urng_t>,
43 "The range parameter to views::transform_by_pos must model std::ranges::random_access_range.");
44
46 static constexpr bool invocable = std::invocable<transform_by_pos_t, urng_t &, std::ranges::range_size_t<urng_t>>;
47 static_assert(invocable, "Both functors need to be invocable with the range type and an integral as parameters.");
48
50 static constexpr bool const_invocable =
51 const_iterable_range<urng_t> &&
52 std::invocable<transform_by_pos_t const, urng_t const &, std::ranges::range_size_t<urng_t>>;
53
58 using reference = decltype(transform_by_pos(urange, 0ull));
60 using const_reference = decltype(std::as_const(transform_by_pos)(std::as_const(urange), 0ull));
62 using value_type = std::remove_cvref_t<reference>;
64 using difference_type = std::ranges::range_difference_t<urng_t>;
66 using size_type = size_t;
68 using iterator = detail::random_access_iterator<view_transform_by_pos>;
70 using const_iterator = detail::random_access_iterator<view_transform_by_pos const>;
72
74 template <typename, template <typename...> typename>
75 friend class detail::random_access_iterator_base;
76
77public:
81 view_transform_by_pos() noexcept = default;
82 constexpr view_transform_by_pos(view_transform_by_pos const & rhs) noexcept = default;
83 constexpr view_transform_by_pos(view_transform_by_pos && rhs) noexcept = default;
84 constexpr view_transform_by_pos & operator=(view_transform_by_pos const & rhs) noexcept = default;
85 constexpr view_transform_by_pos & operator=(view_transform_by_pos && rhs) noexcept = default;
86 ~view_transform_by_pos() noexcept = default;
87
93 view_transform_by_pos(urng_t _urange, transform_by_pos_t _transform_by_pos, size_t const s) :
94 urange{std::move(_urange)}, transform_by_pos{std::move(_transform_by_pos)}, _size{s}
95 {}
96
102 template <typename rng_t>
103 requires(!meta::decays_to<rng_t, view_transform_by_pos> &&
104 (std::ranges::viewable_range<rng_t> &&
105 std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>))
106 view_transform_by_pos(rng_t && _urange, transform_by_pos_t _transform_by_pos, size_t const s) :
107 view_transform_by_pos{std::views::all(std::forward<rng_t>(_urange)), std::move(_transform_by_pos), s}
108 {}
110
127 auto begin() noexcept { return iterator{*this, 0}; }
129 auto begin() const noexcept
130 requires const_invocable
131 {
132 return const_iterator{*this, 0};
133 }
134
148 auto end() noexcept { return iterator{*this, size()}; }
150 auto end() const noexcept
151 requires const_invocable
152 {
153 return const_iterator{*this, size()};
154 }
156
168 size_t size() const noexcept { return _size; }
169
188 decltype(auto) operator[](size_t const n)
189 {
190 assert(n < size());
191 return transform_by_pos(urange, n);
192 }
193
195 decltype(auto) operator[](size_t const n) const
196 requires const_invocable
197 {
198 assert(n < size());
199 return transform_by_pos(urange, n);
200 }
202};
203
205template <typename urng_t, typename transform_by_pos_t>
206view_transform_by_pos(urng_t &&, transform_by_pos_t, size_t)
207 -> view_transform_by_pos<std::views::all_t<urng_t>, transform_by_pos_t>;
208
209// ============================================================================
210// transform_by_pos_fn (adaptor object)
211// ============================================================================
212
214struct transform_by_pos_fn
215{
217 template <typename transform_by_pos_t, typename size_transform_t = std::remove_cvref_t<decltype(std::ranges::size)>>
218 constexpr auto operator()(transform_by_pos_t transform_by_pos,
219 size_transform_t size_transform = std::ranges::size) const
220 {
221 return detail::adaptor_from_functor{*this, std::move(transform_by_pos), std::move(size_transform)};
222 }
223
230 template <std::ranges::range urng_t,
231 typename transform_by_pos_t,
232 typename size_transform_t = std::remove_cvref_t<decltype(std::ranges::size)>>
233 constexpr auto operator()(urng_t && urange,
234 transform_by_pos_t transform_by_pos,
235 size_transform_t size_transform = std::ranges::size) const
236 {
237 static_assert(std::ranges::viewable_range<urng_t>,
238 "The range parameter to views::transform_by_pos must viewable.");
239 static_assert(std::ranges::sized_range<urng_t>,
240 "The range parameter to views::transform_by_pos must model std::ranges::sized_range.");
241 static_assert(std::ranges::random_access_range<urng_t>,
242 "The range parameter to views::transform_by_pos must model std::ranges::random_access_range.");
243 static_assert(std::convertible_to<std::invoke_result_t<size_transform_t, urng_t &>, size_t>,
244 "The size_transform must be invocable with `urng_t &` and return sth. convertible to size_t.");
245
246 return view_transform_by_pos{std::forward<urng_t>(urange), std::move(transform_by_pos), size_transform(urange)};
247 }
248};
249
250} // namespace bio::ranges::detail
251
252// A view that applies a transformation function to an element of a range using its positional index.
253namespace bio::ranges::views
254{
255
313inline constexpr auto transform_by_pos = detail::transform_by_pos_fn{};
315} // namespace bio::ranges::views
T as_const(T... args)
T begin(T... args)
T end(T... args)
T forward(T... args)
constexpr auto size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:517
constexpr auto transform_by_pos
A view adaptor similar to std::views::transform. Calls the invocable with two arguments: underlying r...
Definition: transform_by_pos.hpp:313
T move(T... args)
The BioC++ namespace for views.
Provides the bio::ranges::detail::random_access_iterator class.
Additional non-standard concepts for ranges.
Auxiliary header for the views submodule .