BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
detail.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
15#pragma once
16
17#include <ranges>
18#include <tuple>
19
22
23namespace bio::ranges::detail
24{
25
26// ============================================================================
27// forwards
28// ============================================================================
29
30template <typename left_adaptor_t, typename right_adaptor_t>
31class combined_adaptor;
32
33// ============================================================================
34// adaptor_base
35// ============================================================================
36
78template <typename derived_type, typename... stored_args_ts>
79class adaptor_base
80{
81private:
83 std::tuple<stored_args_ts...> arguments;
84
86 template <typename urng_t, size_t... Is>
87 constexpr auto pass_args_to_impl(urng_t && urange, std::index_sequence<Is...> const &) const &
88 {
89 // std::get returns lvalue-reference to value, but we need to copy the values
90 // so that the view does not depend on the functor
91 return static_cast<derived_type const &>(*this).impl(
92 std::forward<urng_t>(urange),
93 std::tuple_element_t<Is, std::tuple<stored_args_ts...>>(std::get<Is>(arguments))...);
94 }
95
97 template <typename urng_t, size_t... Is>
98 constexpr auto pass_args_to_impl(urng_t && urange, std::index_sequence<Is...> const &) &&
99 {
100 // move out values, because we don't need them anymore (*this is temporary)
101 return static_cast<derived_type &&>(*this).impl(
102 std::forward<urng_t>(urange),
103 std::tuple_element_t<Is, std::tuple<stored_args_ts...>>(std::get<Is>(std::move(arguments)))...);
104 }
105
107 friend derived_type;
108
109public:
113 // a default constructor is not provided, however the constructor below might be one.
114 constexpr adaptor_base(adaptor_base const &) noexcept = default;
115 constexpr adaptor_base(adaptor_base &&) noexcept = default;
116 constexpr adaptor_base & operator=(adaptor_base const &) noexcept = default;
117 constexpr adaptor_base & operator=(adaptor_base &&) noexcept = default;
118 ~adaptor_base() noexcept = default;
119
121 constexpr adaptor_base(stored_args_ts... args) noexcept(
122 noexcept(std::tuple<stored_args_ts...>{std::forward<stored_args_ts>(args)...})) :
123 arguments{std::forward<stored_args_ts>(args)...}
124 {}
126
128 template <std::ranges::input_range urng_t>
129 constexpr auto operator()(urng_t && urange) const &
130 {
131 return pass_args_to_impl(std::forward<urng_t>(urange), std::make_index_sequence<sizeof...(stored_args_ts)>{});
132 }
133
135 template <std::ranges::input_range urng_t>
136 constexpr auto operator()(urng_t && urange) &&
137 {
138 return std::move(*this).pass_args_to_impl(std::forward<urng_t>(urange),
139 std::make_index_sequence<sizeof...(stored_args_ts)>{});
140 }
141
153 template <typename arg_t>
154 constexpr friend auto operator|(arg_t && arg, derived_type const & me)
155 {
156 if constexpr (std::ranges::input_range<arg_t>)
157 return me(std::forward<arg_t>(arg));
158 else
159 return combined_adaptor{std::forward<arg_t>(arg), me};
160 }
161
163 template <typename arg_t>
164 constexpr friend auto operator|(arg_t && arg, derived_type && me)
165 {
166 if constexpr (std::ranges::input_range<arg_t>)
167 return std::move(me)(std::forward<arg_t>(arg));
168 else
169 return combined_adaptor{std::forward<arg_t>(arg), std::move(me)};
170 }
171
188 template <typename arg_t>
189 constexpr friend auto operator|(adaptor_base const & me, arg_t && arg)
190 {
191 return combined_adaptor{static_cast<derived_type const &>(me), std::forward<arg_t>(arg)};
192 }
193
195 template <typename arg_t>
196 constexpr friend auto operator|(adaptor_base && me, arg_t && arg)
197 {
198 return combined_adaptor{static_cast<derived_type &&>(me), std::forward<arg_t>(arg)};
199 }
200};
201
202// ============================================================================
203// combined_adaptor
204// ============================================================================
205
216template <typename left_adaptor_t, typename right_adaptor_t>
217class combined_adaptor :
218 public adaptor_base<combined_adaptor<left_adaptor_t, right_adaptor_t>, left_adaptor_t, right_adaptor_t>
219{
220private:
222 using base_type = adaptor_base<combined_adaptor<left_adaptor_t, right_adaptor_t>, left_adaptor_t, right_adaptor_t>;
223
225 friend base_type;
226
228 template <std::ranges::input_range urng_t, typename left_adaptor_t_, typename right_adaptor_t_>
229 static auto impl(urng_t && urange, left_adaptor_t_ && left_adaptor, right_adaptor_t_ && right_adaptor)
230 {
231 return std::forward<urng_t>(urange) | std::forward<left_adaptor_t_>(left_adaptor) |
232 std::forward<right_adaptor_t_>(right_adaptor);
233 }
234
235public:
239 constexpr combined_adaptor() = default;
240 constexpr combined_adaptor(combined_adaptor const &) noexcept = default;
241 constexpr combined_adaptor(combined_adaptor &&) noexcept = default;
242 constexpr combined_adaptor & operator=(combined_adaptor const &) noexcept = default;
243 constexpr combined_adaptor & operator=(combined_adaptor &&) noexcept = default;
244 ~combined_adaptor() noexcept = default;
245
247 using base_type::base_type;
248
250 constexpr combined_adaptor(left_adaptor_t l, right_adaptor_t r) :
251 base_type{std::forward<left_adaptor_t>(l), std::forward<right_adaptor_t>(r)}
252 {}
254};
255
256// ============================================================================
257// adaptor_for_view_without_args
258// ============================================================================
259
283template <template <typename, typename...> typename view_type>
284class adaptor_for_view_without_args : public adaptor_base<adaptor_for_view_without_args<view_type>>
285{
286private:
288 using base_type = adaptor_base<adaptor_for_view_without_args<view_type>>;
289
291 friend base_type;
292
299 template <typename... arg_types>
300 static auto impl(arg_types &&... args)
301 {
302 return view_type{std::forward<arg_types>(args)...};
303 }
304
305public:
310 constexpr adaptor_for_view_without_args() = default;
312 constexpr adaptor_for_view_without_args(adaptor_for_view_without_args const &) noexcept = default;
314 constexpr adaptor_for_view_without_args(adaptor_for_view_without_args &&) noexcept = default;
316 constexpr adaptor_for_view_without_args & operator=(adaptor_for_view_without_args const &) noexcept = default;
318 constexpr adaptor_for_view_without_args & operator=(adaptor_for_view_without_args &&) noexcept = default;
320 ~adaptor_for_view_without_args() noexcept = default;
321
323 using base_type::base_type;
325};
326
327// ============================================================================
328// adaptor_from_functor
329// ============================================================================
330
362template <typename functor_type, typename... stored_args_ts>
363class adaptor_from_functor :
364 public adaptor_base<adaptor_from_functor<functor_type, stored_args_ts...>, stored_args_ts...>
365{
366private:
368 using base_type = adaptor_base<adaptor_from_functor<functor_type, stored_args_ts...>, stored_args_ts...>;
369
371 friend base_type;
372
374 functor_type fun;
375
383 template <std::ranges::input_range urng_t>
384 constexpr auto impl(urng_t && urange, stored_args_ts... args) const
385 {
386 return fun(std::forward<urng_t>(urange), std::forward<stored_args_ts>(args)...);
387 }
388
389public:
393 constexpr adaptor_from_functor() = default;
394 constexpr adaptor_from_functor(adaptor_from_functor const &) noexcept = default;
395 constexpr adaptor_from_functor(adaptor_from_functor &&) noexcept = default;
396 constexpr adaptor_from_functor & operator=(adaptor_from_functor const &) noexcept = default;
397 constexpr adaptor_from_functor & operator=(adaptor_from_functor &&) noexcept = default;
398 ~adaptor_from_functor() noexcept = default;
399
401 constexpr adaptor_from_functor(functor_type f, stored_args_ts... args) :
402 base_type{std::forward<stored_args_ts>(args)...}, fun{std::move(f)}
403 {}
405};
406
407} // namespace bio::ranges::detail
Provides various type traits on generic types.
T forward(T... args)
constexpr translation_frames operator|(translation_frames lhs, translation_frames rhs) noexcept
Binary operators for bio::alphabet::translation_frames.
Definition: translation.hpp:111
Provides various transformation traits used by the range module.