SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
|
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view. More...
#include <seqan3/utility/views/deep.hpp>
Public Member Functions | |
Constructors, destructor and assignment | |
constexpr | deep () noexcept=default |
Defaulted. | |
constexpr | deep (deep const &) noexcept=default |
Defaulted. | |
constexpr | deep (deep &&) noexcept=default |
Defaulted. | |
constexpr deep & | operator= (deep const &) noexcept=default |
Defaulted. | |
constexpr deep & | operator= (deep &&) noexcept=default |
Defaulted. | |
~deep () noexcept=default | |
Defaulted. | |
Public Member Functions inherited from seqan3::detail::adaptor_base< deep< underlying_adaptor_t >, underlying_adaptor_t > | |
constexpr auto | operator() (urng_t &&urange) && |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. | |
constexpr auto | operator() (urng_t &&urange) const & |
Function-style overload for ranges. | |
constexpr | adaptor_base (adaptor_base const &) noexcept=default |
Defaulted. | |
constexpr | adaptor_base (adaptor_base &&) noexcept=default |
Defaulted. | |
constexpr | adaptor_base (stored_args_ts... args) noexcept(noexcept(std::tuple< stored_args_ts... >{ std::forward< stored_args_ts >(args)...})) |
Constructor with possible arguments; becomes a default constructor for adaptors without args. | |
constexpr adaptor_base & | operator= (adaptor_base const &) noexcept=default |
Defaulted. | |
constexpr adaptor_base & | operator= (adaptor_base &&) noexcept=default |
Defaulted. | |
~adaptor_base () noexcept=default | |
Defaulted. | |
Private Types | |
using | base_type = detail::adaptor_base< deep< underlying_adaptor_t >, underlying_adaptor_t > |
Type of the CRTP-base. | |
Private Member Functions | |
constexpr auto | operator() () const |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. | |
template<typename first_arg_t , typename... stored_arg_types> requires (!std::ranges::input_range<first_arg_t>) | |
constexpr auto | operator() (first_arg_t &&first, stored_arg_types &&... args) const |
Called to produce a range adaptor closure object if the wrapped functor was not a range adaptor closure object before, i.e. requires arguments. | |
template<std::ranges::input_range urng_t, typename... stored_arg_types> requires (sizeof...(stored_arg_types) > 0) | |
constexpr auto | operator() (urng_t &&urange, stored_arg_types &&... args) const |
Called to produce a range if the wrapped functor was not a range adaptor closure object before but necessary arguments are also provided. | |
Static Private Member Functions | |
template<std::ranges::input_range urng_t, typename underlying_adaptor_t_ > | |
static constexpr auto | impl (urng_t &&urange, underlying_adaptor_t_ &&deep_adaptor) |
Unwrap the internal adaptor closure object and pipe the range into it. | |
template<std::size_t range_dimension> | |
static constexpr decltype(auto) | recursive_adaptor (underlying_adaptor_t deep_adaptor) |
recursively construct the deep adaptor | |
Private Attributes | |
friend | base_type |
Befriend the base class so it can call impl(). | |
Related Symbols | |
(Note that these are not member symbols.) | |
Template argument deduction guides. | |
template<typename underlying_adaptor_t > | |
deep (underlying_adaptor_t &&inner) -> deep< underlying_adaptor_t > | |
Template argument deduction helper that preserves lvalue references and turns rvalue references into values. | |
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
underlying_adaptor_t | The type of the adaptor being wrapped. |
If you pass a range to a view that view performs some transformation on that range. If the range passed is multi-dimensional (i.e. a range-of-ranges) that transformation happens on the outermost range. So if you call std::views::reverse on a range-of-dna-ranges, it will revert the order of the dna-ranges, but leave the dna-ranges themselves unchanged.
In some cases this is not desirable or even possible, i.e. seqan3::views::complement performs it's operation on nucleotide-ranges and it would be logical to do so, even it is passed a range-of-nucleotide-ranges (it obviously cannot transform the outer range). We call these views "deep views" as they always perform their operation on the innermost ranges of a multi-dimensional range; in case the input is a one-dimensional range, deepness does not modify the behaviour.
Strictly speaking, seqan3::views::deep is a view adaptor adaptor, i.e. it gets passed another adaptor when being constructed (not via the pipe!) and returns an adaptor that behaves like the underlying one, except being deep.
You can use it mostly like any other view (adaptor) with some subtle differences, illustrated in the examples below.
The returned view has the same requirements and guarantees as those of the underlying adaptor type, except that it is also deep, i.e. if the underlying range is range-of-ranges, all transformations apply to the innermost ranges and conversely the requirements also apply to the innermost ranges of the underlying range and guarantees apply to the innermost ranges of the returned range.
For the higher dimensions (all except the innermost ranges) the following properties hold:
Concepts and traits | urng_t (underlying range type) | rrng_t (returned range type) |
---|---|---|
std::ranges::input_range | required | preserved |
std::ranges::forward_range | preserved | |
std::ranges::bidirectional_range | preserved | |
std::ranges::random_access_range | preserved | |
std::ranges::contiguous_range | lost | |
std::ranges::viewable_range | required | guaranteed |
std::ranges::view | guaranteed | |
std::ranges::sized_range | preserved | |
std::ranges::common_range | preserved | |
std::ranges::output_range | lost | |
seqan3::const_iterable_range | preserved | |
std::ranges::range_reference_t | std::ranges::input_range | std::ranges::input_range + std::ranges::view |
Wrapping an adaptor that takes no parameters ("range adaptor <i>closure</i> object"):
Wrapping an adaptor that takes parameters:
The above example illustrates that views::deep has two sets of arguments, the arguments to construct this adaptor, and the arguments passed to the underlying adaptor when calling this adaptor. You can use ()
for both, but we highly recommend to use {}
to not confuse these; or just use an alias.
Wrapping an adaptor including its arguments:
In the above example the argument to the underlying adaptor is hardcoded and can't be changed at the call-site. It is less flexible, but does not require workarounds for arguments that are expensive (or impossible) to copy.
|
inlinestaticconstexprprivate |
Unwrap the internal adaptor closure object and pipe the range into it.
urng_t | Type of the underlying range. |
underlying_adaptor_t_ | Same as underlying_adaptor_t with possibly different cref qualification. |
[in] | urange | The view's underlying range. |
[in] | deep_adaptor | The stored adaptor unwrapped by the base-classes explode()-member. |
|
inlineconstexprprivate |
Called to produce a range adaptor closure object if the wrapped functor was not a range adaptor closure object before, i.e. requires arguments.
first_arg_t | The type of the first argument; must not model std::ranges::input_range. |
stored_arg_types | The argument types, note that temporaries will be copied on recursion! |
[in] | first | First argument. |
[in] | args | Further arguments (optional). |
|
inlineconstexprprivate |
Called to produce a range if the wrapped functor was not a range adaptor closure object before but necessary arguments are also provided.
urng_t | Type of the underlying range. |
arg_types | The argument types, note that temporaries will be copied on recursion! |
[in] | urange | The view's underlying range. |
[in] | args | Further arguments. |
Recurses and calls std::views::transform if the underlying range is a range-of-ranges.
|
inlinestaticconstexprprivate |
recursively construct the deep adaptor
this function recursively constructs a range adaptor: