100.00% Lines (4/4) 100.00% Functions (2/2)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
  3 + // Copyright (c) 2026 Michael Vandeberg
3   // 4   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 5   // 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   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 7   //
7   // Official repository: https://github.com/cppalliance/capy 8   // Official repository: https://github.com/cppalliance/capy
8   // 9   //
9   10  
10   #ifndef BOOST_CAPY_DETAIL_RUN_HPP 11   #ifndef BOOST_CAPY_DETAIL_RUN_HPP
11   #define BOOST_CAPY_DETAIL_RUN_HPP 12   #define BOOST_CAPY_DETAIL_RUN_HPP
12   13  
13   #include <boost/capy/detail/config.hpp> 14   #include <boost/capy/detail/config.hpp>
14   #include <boost/capy/detail/frame_memory_resource.hpp> 15   #include <boost/capy/detail/frame_memory_resource.hpp>
15   16  
  17 + #include <concepts>
  18 + #include <coroutine>
16   #include <cstddef> 19   #include <cstddef>
17   #include <memory_resource> 20   #include <memory_resource>
18   21  
19   namespace boost { 22   namespace boost {
20   namespace capy { 23   namespace capy {
21   namespace detail { 24   namespace detail {
  25 +
  26 + // A runnable that a stop ends by abandonment (quitter): its promise
  27 + // says what it delivers instead of its own result, and gives the
  28 + // handle a launcher resumes to start it.
  29 + template<class Task>
  30 + concept stops_by_abandonment = requires(typename Task::promise_type& p) {
  31 + Task::promise_type::stopped_result();
  32 + { p.launch_handle() } -> std::convertible_to<std::coroutine_handle<>>;
  33 + };
22   34  
23   /// Concept for standard Allocator types. 35   /// Concept for standard Allocator types.
24   template<class A> 36   template<class A>
25   concept Allocator = requires(A a, std::size_t n) { 37   concept Allocator = requires(A a, std::size_t n) {
26   typename A::value_type; 38   typename A::value_type;
27   { a.allocate(n) } -> std::same_as<typename A::value_type*>; 39   { a.allocate(n) } -> std::same_as<typename A::value_type*>;
28   }; 40   };
29   41  
30   /// Specialization for memory_resource* - stores pointer directly. 42   /// Specialization for memory_resource* - stores pointer directly.
31   template<> 43   template<>
32   class frame_memory_resource<std::pmr::memory_resource*> 44   class frame_memory_resource<std::pmr::memory_resource*>
33   { 45   {
34   std::pmr::memory_resource* mr_; 46   std::pmr::memory_resource* mr_;
35   47  
36   public: 48   public:
HITCBC 37   17 explicit frame_memory_resource(std::pmr::memory_resource* mr) noexcept 49   17 explicit frame_memory_resource(std::pmr::memory_resource* mr) noexcept
HITCBC 38   17 : mr_(mr) 50   17 : mr_(mr)
39   { 51   {
HITCBC 40   17 } 52   17 }
41   53  
HITCBC 42   17 std::pmr::memory_resource* get() noexcept { return mr_; } 54   17 std::pmr::memory_resource* get() noexcept { return mr_; }
43   }; 55   };
44   56  
45   /// Specialization for void - no allocator (empty). 57   /// Specialization for void - no allocator (empty).
46   template<> 58   template<>
47   class frame_memory_resource<void> 59   class frame_memory_resource<void>
48   { 60   {
49   public: 61   public:
50   frame_memory_resource() = default; 62   frame_memory_resource() = default;
51   63  
52   std::pmr::memory_resource* get() noexcept { return nullptr; } 64   std::pmr::memory_resource* get() noexcept { return nullptr; }
53   }; 65   };
54   66  
55   } // namespace detail 67   } // namespace detail
56   } // namespace capy 68   } // namespace capy
57   } // namespace boost 69   } // namespace boost
58   70  
59   #endif 71   #endif