SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
deep.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
16 #include <seqan3/std/ranges>
17 
18 namespace seqan3::views
19 {
20 
100 template <typename underlying_adaptor_t>
101 class deep : public detail::adaptor_base<deep<underlying_adaptor_t>, underlying_adaptor_t>
102 {
103 private:
105  using base_type = detail::adaptor_base<deep<underlying_adaptor_t>, underlying_adaptor_t>;
106 
108  friend base_type;
109 
110 public:
114  constexpr deep() noexcept = default;
115  constexpr deep(deep const &) noexcept = default;
116  constexpr deep(deep &&) noexcept = default;
117  constexpr deep & operator=(deep const &) noexcept = default;
118  constexpr deep & operator=(deep &&) noexcept = default;
119  ~deep() noexcept = default;
120 
121  using base_type::base_type;
123 
125 
127  using base_type::operator();
128 
136  template <std::ranges::input_range urng_t, typename underlying_adaptor_t_>
137  static constexpr auto impl(urng_t && urange, underlying_adaptor_t_ && adap)
138  {
139  return std::forward<urng_t>(urange) | std::forward<underlying_adaptor_t_>(adap);
140  }
141 
152  template <std::ranges::input_range urng_t>
154  requires std::ranges::input_range<reference_t<urng_t>>
156  constexpr auto operator()(urng_t && urange) const &
157  {
158  return std::forward<urng_t>(urange) | std::views::transform([me = *this] (auto && e)
159  {
160  return std::forward<decltype(e)>(e) | me;
161  });
162  }
163 
165  template <std::ranges::input_range urng_t>
167  requires std::ranges::input_range<reference_t<urng_t>>
169  constexpr auto operator()(urng_t && urange) &&
170  {
171  return std::forward<urng_t>(urange) | std::views::transform([me = std::move(*this)] (auto && e)
172  {
173  return std::forward<decltype(e)>(e) | me;
174  });
175  }
176 
185  template <typename first_arg_t, typename ...stored_arg_types>
187  requires !std::ranges::input_range<first_arg_t>
189  constexpr auto operator()(first_arg_t && first, stored_arg_types && ...args) const
190  {
191  // The adaptor currently wrapped is a proto-adaptor and this function has the arguments to "complete" it.
192  // We extract the adaptor that is stored and invoke it with the given arguments.
193  // This returns an adaptor closure object.
194  auto adaptor_closure = std::get<0>(this->arguments)(std::forward<first_arg_t>(first),
195  std::forward<stored_arg_types>(args)...);
196  // Now we wrap this closure object back into a views::deep to get the deep behaviour.
197  return deep<decltype(adaptor_closure)>{std::move(adaptor_closure)};
198  }
199 
201  constexpr auto operator()() const
202  {
203  // Proto-adaptors require arguments by definition, but some support defaulting those (e.g. views::translate).
204  // This extracts the proto adaptor and invokes it without args which yields a different object, the closure
205  // with defaulted arguments.
206  auto adaptor_closure = std::get<0>(this->arguments)();
207  // Now we wrap this closure object back into a views::deep to get the deep behaviour.
208  return deep<decltype(adaptor_closure)>{std::move(adaptor_closure)};
209  }
210 
223  template <std::ranges::input_range urng_t, typename ...stored_arg_types>
225  requires sizeof...(stored_arg_types) > 0
227  constexpr auto operator()(urng_t && urange, stored_arg_types && ...args) const
228  {
229  auto adaptor_closure = std::get<0>(this->arguments)(std::forward<stored_arg_types>(args)...);
230  return std::forward<urng_t>(urange) | std::move(adaptor_closure);
231  }
232 };
233 
237 template <typename underlying_adaptor_t>
240 deep(underlying_adaptor_t && inner) -> deep<underlying_adaptor_t>;
241 
243 
244 } // namespace seqan3::views
seqan3::views
The SeqAn namespace for views.
Definition: view_to_simd.hpp:672
seqan3::views::move
const auto move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
seqan3::views::deep
A wrapper type around an existing view adaptor that enables "deep view" behaviour for that view.
Definition: deep.hpp:101
seqan3::views::deep::deep
constexpr deep() noexcept=default
Defaulted.
seqan3::views::deep::~deep
~deep() noexcept=default
Defaulted.
ranges
Adaptations of concepts from the Ranges TS.
seqan3::pack_traits::transform
seqan3::type_list< trait_t< pack_t >... > transform
Apply a transformation trait to every type in the pack and return a seqan3::type_list of the results.
Definition: traits.hpp:307
seqan3::views::deep::operator=
constexpr deep & operator=(deep const &) noexcept=default
Defaulted.
detail.hpp
Auxiliary header for the views submodule .