SeqAn3
detail.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
41 #pragma once
42 
43 #include <range/v3/range_fwd.hpp>
44 
48 #include <seqan3/std/ranges>
49 
50 namespace seqan3::detail
51 {
52 
53 // ============================================================================
54 // view_base
55 // ============================================================================
56 
60 struct view_base : public ranges::view_base
61 {};
62 
63 // ============================================================================
64 // pipable_adaptor_base
65 // ============================================================================
66 
89 template <typename derived_type>
90 class pipable_adaptor_base
91 {
92 public:
116  template <std::ranges::InputRange urng_t, typename ...arg_types>
117  auto operator()(urng_t && urange, arg_types && ...args) const
118  {
119  return static_cast<derived_type const *>(this)->impl(std::forward<urng_t>(urange),
120  std::forward<arg_types>(args)...);
121  }
122 
135  template <typename ...arg_types>
137  requires (sizeof...(arg_types) > 0)
139  struct auxiliary_functor_t
140  {
146  template <std::ranges::InputRange urng_t>
147  auto operator()(urng_t && urange)
148  {
149  return explode(std::forward<urng_t>(urange), std::make_index_sequence<sizeof...(arg_types)>{});
150  }
151 
153  template <std::ranges::InputRange urng_t>
154  auto operator()(urng_t && urange) const
155  {
156  return explode(std::forward<urng_t>(urange), std::make_index_sequence<sizeof...(arg_types)>{});
157  }
158 
160  std::tuple<arg_types...> _arguments;
161 
162  protected:
164  template <typename urng_t, size_t... Is>
165  auto explode(urng_t && urange, std::index_sequence<Is...> const &) const &
166  {
167  // std::get returns lvalue-reference to value, but we need to copy the values
168  return pipable_adaptor_base{}(
169  std::forward<urng_t>(urange),
170  static_cast<std::tuple_element_t<Is, std::tuple<arg_types...>>>(std::get<Is>(_arguments))...);
171  }
172 
174  template <typename urng_t, size_t... Is>
175  auto explode(urng_t && urange, std::index_sequence<Is...> const &) &
176  {
177  // std::get returns lvalue-reference to value, but we need to copy the values
178  return pipable_adaptor_base{}(
179  std::forward<urng_t>(urange),
180  static_cast<std::tuple_element_t<Is, std::tuple<arg_types...>>>(std::get<Is>(_arguments))...);
181  }
182 
184  template <typename urng_t, size_t... Is>
185  auto explode(urng_t && urange, std::index_sequence<Is...> const &) &&
186  {
187  // move out values, because we don't need them anymore (this is temporary)
188  return pipable_adaptor_base{}(std::forward<urng_t>(urange),
189  std::forward<arg_types>(std::get<Is>(_arguments))...);
190  }
191  };
192 
211  template <typename ...arg_types>
212  auxiliary_functor_t<arg_types...> operator()(arg_types && ...args) const
213  {
214  return {{std::forward<arg_types>(args)...}};
215  }
216 
238  template <std::ranges::InputRange urng_t, typename ...arg_types>
239  friend auto operator|(urng_t && urange, auxiliary_functor_t<arg_types...> & bound_functor)
240  requires (sizeof...(arg_types) > 0)
241  {
242  return bound_functor(std::forward<urng_t>(urange));
243  }
244 
246  template <std::ranges::InputRange urng_t, typename ...arg_types>
247  friend auto operator|(urng_t && urange, auxiliary_functor_t<arg_types...> const & bound_functor)
248  requires (sizeof...(arg_types) > 0)
249  {
250  return bound_functor(std::forward<urng_t>(urange));
251  }
252 
254  template <std::ranges::InputRange urng_t, typename ...arg_types>
255  friend auto operator|(urng_t && urange, auxiliary_functor_t<arg_types...> && bound_functor)
256  requires (sizeof...(arg_types) > 0)
257  {
258  return bound_functor(std::forward<urng_t>(urange));
259  }
260 
280  template <std::ranges::InputRange urng_t>
281  friend auto operator|(urng_t && urange,
282  derived_type const & fn)
283  {
284  return fn(std::forward<urng_t>(urange));
285  }
286 
287 private:
293  pipable_adaptor_base() = default;
294  constexpr pipable_adaptor_base(pipable_adaptor_base const &) = default;
295  constexpr pipable_adaptor_base(pipable_adaptor_base &&) = default;
296  constexpr pipable_adaptor_base & operator =(pipable_adaptor_base const &) = default;
297  constexpr pipable_adaptor_base & operator =(pipable_adaptor_base &&) = default;
298  ~pipable_adaptor_base() = default;
300  friend derived_type;
302 };
303 
304 // ============================================================================
305 // generic_pipable_view_adaptor
306 // ============================================================================
307 
326 template <template <typename, typename...> class view_type>
327 class generic_pipable_view_adaptor : public pipable_adaptor_base<generic_pipable_view_adaptor<view_type>>
328 {
329 private:
331  using base_type = pipable_adaptor_base<generic_pipable_view_adaptor<view_type>>;
332 
333 public:
335  using base_type::base_type;
336 
337 private:
339  friend base_type;
340 
347  template <typename ... arg_types>
348  static auto impl(arg_types && ... args)
349  {
350  return view_type{std::forward<arg_types>(args)...};
351  }
352 };
353 
354 } // namespace seqan3::detail
Specifies requirements of a Range type for which begin returns a type that models std::InputIterator...
Provides seqan3::type_list and auxiliary metafunctions.
Provides seqan3::type_list and auxiliary metafunctions.
Adaptations of concepts from the Ranges TS.
Definition: aligned_sequence_concept.hpp:288
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators. !
Definition: validators.hpp:671
Provides various metafunctions used by the range module.