Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
result_helpers.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
21#pragma once
22
23#include "result.h"
24#include <utility>
25#include <type_traits>
26
27namespace kcenon::common {
28namespace helpers {
29
42template<typename T>
43[[nodiscard]] auto return_if_error(const Result<T>& result)
44 -> std::optional<error_info>
45{
46 if (result.is_err()) {
47 return result.error();
48 }
49 return std::nullopt;
50}
51
52// TRY_UNWRAP macro removed: it used GCC statement expressions ({ }) which
53// are not supported on MSVC. Use the type-safe alternatives instead:
54// - return_if_error() above for early-return on error
55// - try_extract() below for extracting values
56// - safe_execute() below for exception-to-Result conversion
57
65template<typename T>
66[[nodiscard]] auto try_extract(Result<T>&& result)
67 -> std::conditional_t<std::is_void_v<T>, Result<std::monostate>, Result<T>>
68{
69 return std::forward<Result<T>>(result);
70}
71
83[[nodiscard]] inline auto error_if(bool condition, const error_info& error)
84 -> std::optional<error_info>
85{
86 if (condition) {
87 return error;
88 }
89 return std::nullopt;
90}
91
99[[nodiscard]] inline auto make_error(int code,
100 const std::string& message,
101 const std::string& module = "") noexcept
102 -> error_info
103{
104 return error_info{code, message, module};
105}
106
115[[nodiscard]] inline auto make_error_with_details(
116 int code,
117 const std::string& message,
118 const std::string& module,
119 const std::string& details) noexcept
120 -> error_info
121{
122 return error_info{code, message, module, details};
123}
124
137template<typename... Funcs>
138[[nodiscard]] auto chain(Funcs&&... funcs) {
139 using FirstResult = std::invoke_result_t<std::tuple_element_t<0, std::tuple<Funcs...>>>;
140
141 FirstResult result = std::get<0>(std::forward_as_tuple(funcs...))();
142
143 if constexpr (sizeof...(funcs) > 1) {
144 ([&]<typename Func>(Func&& func) {
145 if (result.is_ok()) {
146 result = func(result.value());
147 }
148 }(std::forward<Funcs>(funcs)), ...);
149 }
150
151 return result;
152}
153
162template<typename Func>
163[[nodiscard]] auto safe_execute(Func&& func, const std::string& module = "")
165{
166 using ReturnType = std::invoke_result_t<Func>;
167
168 try {
169 if constexpr (std::is_void_v<ReturnType>) {
170 func();
171 return Result<std::monostate>(std::monostate{});
172 } else {
173 return Result<ReturnType>(func());
174 }
175 } catch (const std::exception& e) {
176 return Result<ReturnType>(error_info{-99, e.what(), module});
177 } catch (...) {
178 return Result<ReturnType>(error_info{-99, "Unknown error", module});
179 }
180}
181
193template<typename T, typename ErrorHandler>
194[[nodiscard]] auto unwrap_or_handle(Result<T>&& result, ErrorHandler&& error_handler) -> T
195{
196 if (result.is_err()) {
197 error_handler(result.error());
198 return T{};
199 }
200 return std::move(result).value();
201}
202
218template<typename... Results>
219[[nodiscard]] auto combine_results(Results&&... results)
221{
222 // Check if any result is error
223 bool has_error = (... || results.is_err());
224 if (has_error) {
225 // Return first error found
226 error_info first_error;
227 ((results.is_err() && (first_error = results.error(), true)) || ...);
229 }
230
231 // All ok, combine values
233 std::make_tuple(std::forward<Results>(results).value()...)
234 );
235}
236
237} // namespace helpers
238} // namespace kcenon::common
Result type for error handling with member function support.
Definition core.cppm:165
auto make_error(int code, const std::string &message, const std::string &module="") noexcept -> error_info
Create error_info with code, message, and module (type-safe)
auto return_if_error(const Result< T > &result) -> std::optional< error_info >
Return error if Result is in error state (type-safe alternative to RETURN_IF_ERROR)
auto safe_execute(Func &&func, const std::string &module="") -> Result< std::invoke_result_t< Func > >
Execute function and convert exceptions to Result.
auto error_if(bool condition, const error_info &error) -> std::optional< error_info >
Check condition and return error if false (type-safe alternative to RETURN_ERROR_IF)
auto try_extract(Result< T > &&result) -> std::conditional_t< std::is_void_v< T >, Result< std::monostate >, Result< T > >
Safely extract value from Result or return error.
auto unwrap_or_handle(Result< T > &&result, ErrorHandler &&error_handler) -> T
Unwrap Result with custom error handler.
auto chain(Funcs &&... funcs)
Chain multiple Result-returning operations.
auto make_error_with_details(int code, const std::string &message, const std::string &module, const std::string &details) noexcept -> error_info
Create error_info with code, message, module, and details.
auto combine_results(Results &&... results) -> Result< std::tuple< typename std::decay_t< Results >::value_type... > >
Combine multiple Results into a single Result containing a tuple.
Core interfaces.
Definition adapter.h:21
Umbrella header for Result<T> type and related utilities.
Standard error information used by Result<T>.
Definition core.cppm:106