11#include <memory_resource>
14namespace hi::inline v1 {
26template<
typename T,
typename Allocator = std::allocator<std::
byte>>
30 std::is_same_v<std::allocator_traits<Allocator>::value_type, std::byte>,
31 "Allocator's value_type must be std::byte");
32 using allocator_type = Allocator;
38 allocator_type *allocator;
42 void operator delete(
void *ptr)
45 auto *ptr_ =
reinterpret_cast<std::byte *
>(ptr) -
sizeof(
allocator_info);
46 auto *info_ptr = std::launder(
reinterpret_cast<allocator_info *
>(ptr_));
47 auto info = *info_ptr;
48 std::destroy_at(info_ptr);
51 auto allocator = allocator_type{};
59 [[nodiscard]]
static void *simple_new(
std::size_t size)
61 auto size_plus_info = size +
sizeof(allocator_info);
64 auto allocator = allocator_type{};
66 [[maybe_unused]]
auto *info =
new (ptr) allocator_info(
nullptr, size_plus_info);
67 return ptr +
sizeof(allocator_info);
70 [[nodiscard]]
static void *allocator_new(
std::size_t size, allocator_type &allocator)
72 auto size_plus_info = size +
sizeof(allocator_info);
78 [[maybe_unused]]
auto *info =
new (ptr) allocator_info(&allocator, size_plus_info);
79 return ptr +
sizeof(allocator_info);
82 template<
typename... Args>
83 void *
operator new(
std::size_t size, Args &&...args)
87 return promise_type::simple_new(size);
89 return promise_type::allocator_new(size, get_last_argument(args...));
93 generator get_return_object()
95 return generator{handle_type::from_promise(*
this)};
98 value_type
const &value()
103 static std::suspend_always initial_suspend() noexcept
108 static std::suspend_always final_suspend() noexcept
113 std::suspend_always yield_value(value_type
const &value)
noexcept
119 std::suspend_always yield_value(value_type &&value)
noexcept
125 void return_void() noexcept {}
128 void await_transform() =
delete;
130 [[noreturn]]
static void unhandled_exception()
136 std::optional<value_type> _value;
139 using handle_type = std::coroutine_handle<promise_type>;
143 value_proxy(value_type
const &value) noexcept : _value(value) {}
145 value_type
const &operator*()
const noexcept
158 using difference_type = ptrdiff_t;
159 using value_type = std::remove_cv_t<value_type>;
164 explicit iterator(handle_type coroutine) : _coroutine{coroutine} {}
185 return _coroutine.promise().value();
188 value_type
const *operator->()
const
197 return (not _coroutine) or _coroutine.done();
201 handle_type _coroutine;
204 explicit generator(handle_type coroutine) : _coroutine(coroutine) {}
206 generator() =
default;
210 _coroutine.destroy();
214 generator(
const generator &) =
delete;
215 generator &operator=(
const generator &) =
delete;
217 generator(generator &&other) noexcept : _coroutine{other._coroutine}
219 hi_axiom(&other !=
this);
220 other._coroutine = {};
223 generator &operator=(generator &&other)
noexcept
225 hi_return_on_self_assignment(other);
227 _coroutine.destroy();
229 _coroutine = other._coroutine;
230 other._coroutine = {};
246 std::default_sentinel_t
end()
252 handle_type _coroutine;
258using generator = hi::generator<T, std::pmr::polymorphic_allocator<>>;
This file includes functions for manipulating parameter-packs.
A return value for a generator-function.
Definition generator.hpp:27
iterator begin()
Start the generator-function and return an iterator.
Definition generator.hpp:236
std::default_sentinel_t end()
Return a sentinal for the iterator.
Definition generator.hpp:246
Definition generator.hpp:35
Definition generator.hpp:37
Definition generator.hpp:141
A forward iterator which iterates through values co_yieled by the generator-function.
Definition generator.hpp:156
value_type const & operator*() const
Retrieve the value co_yielded by the generator-function.
Definition generator.hpp:183
bool operator==(std::default_sentinel_t) const
Check if the generator-function has finished.
Definition generator.hpp:195
iterator & operator++()
Resume the generator-function.
Definition generator.hpp:168
Definition concepts.hpp:35
Definition concepts.hpp:38