IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
task_expected_promise.hxx
Go to the documentation of this file.
1
3
4#pragma once
5#include <ice/task_types.hxx>
6#include <ice/task_handle.hxx>
7#include <ice/expected.hxx>
8
9namespace ice
10{
11
12 template<typename Result, typename ErrorType>
13 struct TaskExpected;
14
15 template<typename Result, typename ErrorType>
16 struct TaskExpectedPromise final : public ice::TaskInfoPromise<ice::TaskExpected<Result, ErrorType>>
17 {
19 {
20 this->_info = new TaskInfo{ };
21 }
22
24 {
25 if (this->_info->has_any(TaskState::Succeeded))
26 {
27 // Destroy the object if created
28 result().~Result();
29 }
30 }
31
32 // Support all other TaskInfo tag extensions. (ex.: TaskCancelationToken)
34
35 inline auto get_return_object() noexcept -> ice::TaskExpected<Result, ErrorType>;
36
38 {
39 constexpr bool await_ready() const noexcept { return false; }
40
41 template<typename Promise>
42 inline auto await_suspend(std::coroutine_handle<Promise> coro) noexcept -> std::coroutine_handle<>
43 {
44 TaskInfo* const info = coro.promise()._info;
45
46 if (info->has_any(TaskState::Canceled))
47 {
48 info->state.store(TaskState::Failed | TaskState::Canceled, std::memory_order_relaxed);
49 }
50
51 // Don't resume anything when we got canceled or failed
52 if (info->has_any(TaskState::Failed))
53 {
54 return coro.promise()._error_continuation;
55 }
56
57 // Mark as successful
58 info->state.store(TaskState::Succeeded, std::memory_order_release);
59
60 // Call the parent suspend
62 }
63
64 constexpr void await_resume() const noexcept { }
65 };
66
67 constexpr auto final_suspend() noexcept
68 {
69 return ExpectedFinalAwaiter{ };
70 }
71
72 template<typename TypeExpected> requires (std::is_same_v<ice::clean_type<TypeExpected>, ice::Expected<Result, ErrorType>>)
73 inline void return_value(TypeExpected&& expected) noexcept(std::is_nothrow_move_constructible_v<Result>)
74 {
76 if (expected.succeeded())
77 {
78 new (&_value) Result{ ice::forward<TypeExpected>(expected).value() };
79 }
80 else
81 {
82 this->_info->state.store(TaskState::Failed);
83
85 *_error_pointer = ice::forward<TypeExpected>(expected).error();
86 }
87 }
88
89 inline void return_value(ErrorType error) noexcept
90 {
91 this->_info->state.store(TaskState::Failed);
92
94 *_error_pointer = error;
95 }
96
97 inline void return_value(Result const& value) noexcept(std::is_nothrow_copy_constructible_v<Result>)
98 {
99 new (&_value) Result{ value };
100 }
101
102 inline void return_value(Result&& value) noexcept(std::is_nothrow_move_constructible_v<Result>)
103 {
104 new (&_value) Result{ std::move(value) };
105 }
106
107 inline auto expected() noexcept -> ice::Expected<Result, ErrorType>
108 {
109 if (this->_info->has_any(TaskState::Succeeded))
110 {
111 return *reinterpret_cast<Result*>(_value);
112 }
113 else
114 {
115 return _error_value;
116 }
117 }
118
119 // TODO: Cleanup-this-mess
120 inline auto expected_moved() noexcept -> ice::Expected<Result, ErrorType>
121 {
122 if (this->_info->has_any(TaskState::Succeeded))
123 {
124 return ice::move(*reinterpret_cast<Result*>(_value));
125 }
126 else
127 {
128 return _error_value;
129 }
130 }
131
132 inline auto result() noexcept -> Result&
133 {
135 return *reinterpret_cast<Result*>(_value);
136 }
137
138 union
139 {
140 alignas(Result) char _value[sizeof(Result)];
141 ErrorType _error_value;
142 };
143
145 std::coroutine_handle<> _error_continuation{ std::noop_coroutine() };
146 };
147
148} // namespace ice
#define ICE_ASSERT_CORE(expression)
Definition assert_core.hxx:43
Definition expected.hxx:16
Definition info.hxx:8
SPDX-License-Identifier: MIT.
Definition array.hxx:12
@ Canceled
Task was canceled at any point of it's lifetime.
Definition task_info.hxx:32
@ Succeeded
Task finished execution with a valid result.
Definition task_info.hxx:29
@ Failed
Task finished execution but results are invalid.
Definition task_info.hxx:35
ice::Expected< ice::ErrorCode > Result
Definition expected.hxx:197
Definition task_expected.hxx:12
Definition task_expected_promise.hxx:38
auto await_suspend(std::coroutine_handle< Promise > coro) noexcept -> std::coroutine_handle<>
Definition task_expected_promise.hxx:42
constexpr bool await_ready() const noexcept
Definition task_expected_promise.hxx:39
constexpr void await_resume() const noexcept
Definition task_expected_promise.hxx:64
auto get_return_object() noexcept -> ice::TaskExpected< Result, ErrorType >
Definition task_expected.hxx:276
ErrorType _error_value
Definition task_expected_promise.hxx:141
constexpr auto final_suspend() noexcept
Definition task_expected_promise.hxx:67
char _value[sizeof(Result)]
Definition task_expected_promise.hxx:140
std::coroutine_handle _error_continuation
Definition task_expected_promise.hxx:145
void return_value(ErrorType error) noexcept
Definition task_expected_promise.hxx:89
ErrorType * _error_pointer
Definition task_expected_promise.hxx:144
auto expected_moved() noexcept -> ice::Expected< Result, ErrorType >
Definition task_expected_promise.hxx:120
void return_value(TypeExpected &&expected) noexcept(std::is_nothrow_move_constructible_v< Result >)
Definition task_expected_promise.hxx:73
~TaskExpectedPromise() noexcept
Definition task_expected_promise.hxx:23
auto expected() noexcept -> ice::Expected< Result, ErrorType >
Definition task_expected_promise.hxx:107
void return_value(Result &&value) noexcept(std::is_nothrow_move_constructible_v< Result >)
Definition task_expected_promise.hxx:102
TaskExpectedPromise() noexcept
Definition task_expected_promise.hxx:18
void return_value(Result const &value) noexcept(std::is_nothrow_copy_constructible_v< Result >)
Definition task_expected_promise.hxx:97
auto result() noexcept -> Result &
Definition task_expected_promise.hxx:132
Definition task_info.hxx:50
Definition task_handle.hxx:143
ice::TaskInfo * _info
Definition task_handle.hxx:144
Definition task_promise_base.hxx:15
auto await_suspend(ice::coroutine_handle< Promise > coro) noexcept -> ice::coroutine_handle<>
Definition task_promise_base.hxx:59
Definition task_promise_base.hxx:13