BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
deep.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 <ranges>
17
19
20namespace bio::ranges::views
21{
22
102template <typename underlying_adaptor_t>
103class deep : public detail::adaptor_base<deep<underlying_adaptor_t>, underlying_adaptor_t>
104{
105private:
107 using base_type = detail::adaptor_base<deep<underlying_adaptor_t>, underlying_adaptor_t>;
108
110 friend base_type;
111
112public:
116 constexpr deep() noexcept = default;
117 constexpr deep(deep const &) noexcept = default;
118 constexpr deep(deep &&) noexcept = default;
119 constexpr deep & operator=(deep const &) noexcept = default;
120 constexpr deep & operator=(deep &&) noexcept = default;
121 ~deep() noexcept = default;
122
123 using base_type::base_type;
125
127
129 using base_type::operator();
130
138 template <std::ranges::input_range urng_t, typename underlying_adaptor_t_>
139 static constexpr auto impl(urng_t && urange, underlying_adaptor_t_ && adap)
140 {
141 return std::forward<urng_t>(urange) | std::forward<underlying_adaptor_t_>(adap);
142 }
143
154 template <std::ranges::input_range urng_t>
155 requires std::ranges::input_range<std::ranges::range_reference_t<urng_t>>
156 constexpr auto operator()(urng_t && urange) const &
157 {
158 return std::forward<urng_t>(urange) |
159 std::views::transform([me = *this](auto && e) { return std::forward<decltype(e)>(e) | me; });
160 }
161
163 template <std::ranges::input_range urng_t>
164 requires std::ranges::input_range<std::ranges::range_reference_t<urng_t>>
165 constexpr auto operator()(urng_t && urange) &&
166 {
167 return std::forward<urng_t>(urange) |
168 std::views::transform([me = std::move(*this)](auto && e) { return std::forward<decltype(e)>(e) | me; });
169 }
170
179 template <typename first_arg_t, typename... stored_arg_types>
180 requires(!std::ranges::input_range<first_arg_t>)
181 constexpr auto operator()(first_arg_t && first, stored_arg_types &&... args) const
182 {
183 // The adaptor currently wrapped is a proto-adaptor and this function has the arguments to "complete" it.
184 // We extract the adaptor that is stored and invoke it with the given arguments.
185 // This returns an adaptor closure object.
186 auto adaptor_closure =
187 std::get<0>(this->arguments)(std::forward<first_arg_t>(first), std::forward<stored_arg_types>(args)...);
188 // Now we wrap this closure object back into a views::deep to get the deep behaviour.
189 return deep<decltype(adaptor_closure)>{std::move(adaptor_closure)};
190 }
191
193 constexpr auto operator()() const
194 {
195 // Proto-adaptors require arguments by definition, but some support defaulting those (e.g. views::translate).
196 // This extracts the proto adaptor and invokes it without args which yields a different object, the closure
197 // with defaulted arguments.
198 auto adaptor_closure = std::get<0>(this->arguments)();
199 // Now we wrap this closure object back into a views::deep to get the deep behaviour.
200 return deep<decltype(adaptor_closure)>{std::move(adaptor_closure)};
201 }
202
215 template <std::ranges::input_range urng_t, typename... stored_arg_types>
216 requires(sizeof...(stored_arg_types) > 0)
217 constexpr auto operator()(urng_t && urange, stored_arg_types &&... args) const
218 {
219 auto adaptor_closure = std::get<0>(this->arguments)(std::forward<stored_arg_types>(args)...);
220 return std::forward<urng_t>(urange) | std::move(adaptor_closure);
221 }
222};
223
229template <typename underlying_adaptor_t>
230deep(underlying_adaptor_t && inner) -> deep<underlying_adaptor_t>;
231
233
234} // namespace bio::ranges::views
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
Definition: deep.hpp:104
deep(underlying_adaptor_t &&inner) -> deep< underlying_adaptor_t >
Template argument deduction helper that preserves lvalue references and turns rvalue references into ...
constexpr deep() noexcept=default
Defaulted.
The BioC++ namespace for views.
Auxiliary header for the views submodule .