TLA Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/capy
8 : //
9 :
10 : #ifndef BOOST_CAPY_DETAIL_OWNED_RANGE_HPP
11 : #define BOOST_CAPY_DETAIL_OWNED_RANGE_HPP
12 :
13 : #include <boost/capy/detail/config.hpp>
14 :
15 : #include <ranges>
16 : #include <type_traits>
17 : #include <utility>
18 : #include <vector>
19 :
20 : namespace boost {
21 : namespace capy {
22 : namespace detail {
23 :
24 : // A join's runners refer to their awaitables in place until they start,
25 : // so the range it owns must yield lvalues that outlive the iteration.
26 : // Only a forward range guarantees that: an input iterator may hold the
27 : // element it yields and replace it on the next step. Any other range is
28 : // moved into a vector instead.
29 : template<class R>
30 : using owned_range_t = std::conditional_t<
31 : std::ranges::forward_range<std::remove_cvref_t<R>&> &&
32 : std::is_lvalue_reference_v<
33 : std::ranges::range_reference_t<std::remove_cvref_t<R>&>>,
34 : std::remove_cvref_t<R>,
35 : std::vector<std::ranges::range_value_t<R>>>;
36 :
37 : template<class R>
38 : owned_range_t<R>
39 HIT 41 : own_range(R&& r)
40 : {
41 : if constexpr(std::is_same_v<owned_range_t<R>, std::remove_cvref_t<R>>)
42 : {
43 36 : return std::forward<R>(r);
44 : }
45 : else
46 : {
47 5 : owned_range_t<R> v;
48 5 : v.reserve(std::ranges::size(r));
49 34 : for(auto&& a : r)
50 13 : v.push_back(std::move(a));
51 8 : return v;
52 5 : }
53 : }
54 :
55 : } // namespace detail
56 : } // namespace capy
57 : } // namespace boost
58 :
59 : #endif
|