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