3 * @brief Template implementation for Promise class - asynchronous result handling with continuation chaining
17 // ========== Template implementation for Promise<tValue> ==========
20 * @brief Default constructor - creates promise with shared state
21 * @tparam tValue Value type for promise result
23 * Initializes a new promise with a shared State object for
24 * communication between promise and future/continuation handlers.
26 * @see \ref swt::Promise "Promise", \ref swt::State "State"
28 template <typename tValue>
29 Promise<tValue>::Promise() : m_state(std::make_shared<State<tValue>>()) {}
32 * @brief Set the promise value and trigger continuation chain
33 * @tparam tValue Value type being set
34 * @param value Value to set (moved into promise state)
36 * Resolves the promise with the provided value and triggers any
37 * registered continuation callbacks. This can only be called once
38 * per promise instance.
41 * Promise<int> promise;
42 * promise.set_value(42); // Resolves promise and triggers continuations
45 * @see \ref swt::Promise::set_value "set_value()"
47 template <typename tValue>
48 void Promise<tValue>::set_value(tValue value) {
49 m_state->setValue(std::move(value));
53 * @brief Set exception state and trigger error handlers
54 * @tparam tValue Value type (not used for exception)
55 * @param exception Exception pointer to set
57 * Rejects the promise with the provided exception and triggers any
58 * registered error handlers. This can only be called once per promise.
61 * Promise<int> promise;
63 * // Some operation that may fail
65 * promise.set_exception(std::current_exception());
69 * @see \ref swt::Promise::set_exception "set_exception()"
71 template <typename tValue>
72 void Promise<tValue>::set_exception(std::exception_ptr exception) {
73 m_state->setException(exception);
77 * @brief Chain continuation callback for promise resolution
78 * @tparam tValue Current promise value type
79 * @tparam F Function type for continuation callback
80 * @param looper_ SLLooper instance for callback execution
81 * @param func Continuation function to execute when promise resolves
82 * @return Promise<ReturnType> New promise for further chaining
84 * Registers a continuation callback that executes when the promise resolves
85 * successfully. The continuation function receives the resolved value and
86 * can return a new value, creating a chain of promise transformations.
89 * - **Type transformation**: Return type can differ from input type
90 * - **Exception handling**: Automatic exception propagation in continuation chain
91 * - **Void support**: Handles both value-returning and void continuations
92 * - **Asynchronous execution**: Callbacks execute via SLLooper message queue
95 * promise.then(looper, [](int x) {
97 * }).then(looper, [](int doubled) {
98 * std::cout << "Result: " << doubled << std::endl;
102 * @see \ref swt::Promise::then "then()", \ref swt::SLLooper "SLLooper"
104 template <typename tValue>
105 template <typename F>
106 auto Promise<tValue>::then(std::shared_ptr<SLLooper>& looper_, F func) -> Promise<std::invoke_result_t<F, tValue>> {
107 using ReturnType = std::invoke_result_t<F, tValue>;
108 Promise<ReturnType> nextPromise;
110 // Set continuation that handles success case
111 m_state->setContinuation(looper_, [func = std::move(func), nextPromise](tValue value) mutable {
113 if constexpr (std::is_void_v<ReturnType>) {
114 // Handle void-returning continuation
115 func(std::move(value));
116 nextPromise.set_value();
118 // Handle value-returning continuation
119 auto result = func(std::move(value));
120 nextPromise.set_value(std::move(result));
123 // Automatic exception propagation
124 nextPromise.set_exception(std::current_exception());
128 // Set error handler that propagates exception through chain
129 m_state->setErrorHandler(looper_, [nextPromise](std::exception_ptr exception) mutable {
130 nextPromise.set_exception(exception);
137 * @brief Chain error handler for promise rejection
138 * @tparam tValue Current promise value type
139 * @tparam F Function type for error handler callback
140 * @param looper_ SLLooper instance for callback execution
141 * @param func Error handler function to execute when promise is rejected
142 * @return Promise<tValue> New promise for further chaining
144 * Registers an error handler that executes when the promise is rejected.
145 * The error handler can recover from the error by returning a value, or
146 * let the error propagate by throwing or not handling it.
149 * promise.catchError(looper, [](std::exception_ptr ex) -> int {
151 * std::rethrow_exception(ex);
152 * } catch (const MyException& e) {
153 * return 42; // Recovery value
155 * // Other exceptions will be re-thrown
159 * @see \ref swt::Promise::catchError "catchError()", \ref swt::SLLooper "SLLooper"
161 template <typename tValue>
162 template <typename F>
163 auto Promise<tValue>::catchError(std::shared_ptr<SLLooper>& looper_, F func) -> Promise<tValue> {
164 Promise<tValue> nextPromise;
166 // Set continuation that propagates success value
167 m_state->setContinuation(looper_, [nextPromise](tValue value) mutable {
168 nextPromise.set_value(std::move(value));
171 // Set error handler that calls the catch function
172 m_state->setErrorHandler(looper_, [func = std::move(func), nextPromise](std::exception_ptr exception) mutable {
174 if constexpr (std::is_void_v<std::invoke_result_t<F, std::exception_ptr>>) {
175 // Void error handler - propagate original exception
177 nextPromise.set_exception(exception);
179 // Value-returning error handler - use result as recovery value
180 auto result = func(exception);
181 nextPromise.set_value(std::move(result));
184 // Error handler threw - propagate new exception
185 nextPromise.set_exception(std::current_exception());
192 // ========== Template specialization for Promise<void> ==========
195 * @brief Chain continuation callback for void promise resolution
196 * @tparam F Function type for continuation callback
197 * @param looper_ SLLooper instance for callback execution
198 * @param func Continuation function (takes no parameters)
199 * @return Promise<ReturnType> New promise for further chaining
201 * Specialization for void promises that handles continuation chaining
202 * when the current promise doesn't produce a value. The continuation
203 * function takes no parameters and can return any type.
206 * voidPromise.then(looper, []() {
207 * return "Void promise completed!";
208 * }).then(looper, [](const std::string& msg) {
209 * std::cout << msg << std::endl;
213 * @see \ref swt::Promise::then "then()", \ref swt::SLLooper "SLLooper"
215 template <typename F>
216 auto Promise<void>::then(std::shared_ptr<SLLooper>& looper_, F func) -> Promise<std::invoke_result_t<F>> {
217 using ReturnType = std::invoke_result_t<F>;
218 Promise<ReturnType> nextPromise;
220 // Set continuation that handles success case for void promise
221 m_state->setContinuation(looper_, [func = std::move(func), nextPromise]() mutable {
223 if constexpr (std::is_void_v<ReturnType>) {
224 // Void -> Void continuation
226 nextPromise.set_value();
228 // Void -> Value continuation
229 auto result = func();
230 nextPromise.set_value(std::move(result));
233 // Automatic exception propagation
234 nextPromise.set_exception(std::current_exception());
238 // Set error handler that propagates exception through chain
239 m_state->setErrorHandler(looper_, [nextPromise](std::exception_ptr exception) mutable {
240 nextPromise.set_exception(exception);
247 * @brief Chain error handler for void promise rejection
248 * @tparam F Function type for error handler callback
249 * @param looper_ SLLooper instance for callback execution
250 * @param func Error handler function to execute when promise is rejected
251 * @return Promise<void> New void promise for further chaining
253 * Specialization for void promises that handles error recovery.
254 * If the error handler executes successfully (without throwing),
255 * the promise chain continues with success state.
258 * voidPromise.catchError(looper, [](std::exception_ptr ex) {
259 * std::cerr << "Error handled, continuing..." << std::endl;
260 * // Not throwing means error is handled
261 * }).then(looper, []() {
262 * std::cout << "Promise chain continues!" << std::endl;
266 * @see \ref swt::Promise::catchError "catchError()", \ref swt::SLLooper "SLLooper"
268 template <typename F>
269 auto Promise<void>::catchError(std::shared_ptr<SLLooper>& looper_, F func) -> Promise<void> {
270 Promise<void> nextPromise;
272 // Set continuation that propagates success (no value)
273 m_state->setContinuation(looper_, [nextPromise]() mutable {
274 nextPromise.set_value();
277 // Set error handler that calls the catch function
278 m_state->setErrorHandler(looper_, [func = std::move(func), nextPromise](std::exception_ptr exception) mutable {
280 // Call error handler
282 // If no exception thrown, error is handled - continue with success
283 nextPromise.set_value();
285 // Error handler threw - propagate new exception
286 nextPromise.set_exception(std::current_exception());
295 #endif // PROMISE_TPP