100.00% Lines (8/8) 100.00% Functions (1/1)
TLA Baseline Branch
Line Hits Code Line Hits 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>
HITGNC   39 + 41 own_range(R&& r)
  40 + {
  41 + if constexpr(std::is_same_v<owned_range_t<R>, std::remove_cvref_t<R>>)
  42 + {
HITGNC   43 + 36 return std::forward<R>(r);
  44 + }
  45 + else
  46 + {
HITGNC   47 + 5 owned_range_t<R> v;
HITGNC   48 + 5 v.reserve(std::ranges::size(r));
HITGNC   49 + 34 for(auto&& a : r)
HITGNC   50 + 13 v.push_back(std::move(a));
HITGNC   51 + 8 return v;
HITGNC   52 + 5 }
  53 + }
  54 +
  55 + } // namespace detail
  56 + } // namespace capy
  57 + } // namespace boost
  58 +
  59 + #endif