dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
Helpers.hpp
1// SPDX-FileCopyrightText: 2026 Vincent Leroy
2// SPDX-License-Identifier: MIT
3//
4// This file is part of dfx.
5//
6// Licensed under the MIT License. See the LICENSE file in the project root
7// for full license information.
8
9#pragma once
10
11// Standard includes
12#include <cerrno>
13#include <concepts>
14#include <format>
15#include <functional>
16
17// Project includes
20#include <dfx-utilities/Log.hpp>
21
22struct VoidReturnTag { explicit VoidReturnTag() noexcept = default; };
23inline constexpr VoidReturnTag DFX_VOID_ERROR {};
24
25inline constexpr int DFX_NO_ERRNO = -1;
26
28{
29template<int ErrnoValue, auto ErrorCode = DFX_ERROR, auto SuccessCode = DFX_OK, typename F, typename ... Args>
30requires std::invocable<F, Args...>
31auto safeInvokeFFI(std::shared_ptr<spdlog::logger> logger, F && f, Args && ... args) noexcept
32{
33 try
34 {
35 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
36 return SuccessCode;
37 }
38 catch (Utils::Exception const & e)
39 {
40 if (logger != nullptr)
42 }
43 catch (std::exception const & e)
44 {
45 DFX_LLOG(logger, spdlog::level::err, "An error occurred: {}", e.what());
46 }
47 catch (...)
48 {
49 DFX_LLOG(logger, spdlog::level::err, "An unknown error occurred");
50 }
51
52 if constexpr (ErrnoValue != DFX_NO_ERRNO)
53 errno = ErrnoValue;
54 return ErrorCode;
55}
56
57template<int ErrnoValue, auto ErrorCode, typename F, typename ... Args>
58requires std::invocable<F, Args...>
59auto safeInvokeValueFFI(std::shared_ptr<spdlog::logger> logger, F && f, Args && ... args) noexcept
60{
61 using ResultType = std::invoke_result_t<F, Args...>;
62 static_assert(!std::is_void_v<ResultType>,
63 "safeInvokeValueFFI cannot be used with void functions. Use safeInvokeFFI instead.");
64
65 try
66 {
67 return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
68 }
69 catch (Utils::Exception const & e)
70 {
71 if (logger != nullptr)
73 }
74 catch (std::exception const & e)
75 {
76 DFX_LLOG(logger, spdlog::level::err, "An error occurred: {}", e.what());
77 }
78 catch (...)
79 {
80 DFX_LLOG(logger, spdlog::level::err, "An unknown error occurred");
81 }
82
83 if constexpr (ErrnoValue != DFX_NO_ERRNO)
84 errno = ErrnoValue;
85 return static_cast<ResultType>(ErrorCode);
86}
87
88template<int ErrnoValue, auto ErrorCode = DFX_ERROR>
89auto setErrnoAndReturn() noexcept
90{
91 errno = ErrnoValue;
92 if constexpr (!std::is_same_v<decltype(ErrorCode), VoidReturnTag>)
93 return ErrorCode;
94}
95
96template<int ErrnoValue, auto ErrorCode = DFX_ERROR, typename ... Args>
97auto setErrnoLogAndReturn(std::shared_ptr<spdlog::logger> logger, std::format_string<Args ...> message, Args && ... args) noexcept
98{
99 if (logger != nullptr)
100 DFX_LLOG_ERROR(logger, message, std::forward<Args>(args)...);
101
102 return setErrnoAndReturn<ErrnoValue, ErrorCode>();
103}
104} // !namespace dfx::Plugins::Helpers
Exception utilities for dfx (source-location aware exceptions, nested stacks, and safe invocation hel...
C-ABI for the dfx framework plugin system.
#define DFX_OK
Returned value in case of success.
Definition PluginInterface.h:159
#define DFX_ERROR
Returned value in case of error.
Definition PluginInterface.h:161
Runtime error that captures a std::source_location.
Definition Exception.hpp:52
static void printToLogger(Exception const &e, spdlog::level::level_enum lvl=spdlog::level::err, std::string const &loggerName="", std::size_t initialIndentLevel=0, std::string const &logPattern=noFileLogPattern, std::string const &currentLogPattern=defaultLogPattern)
Log an exception (including nested exceptions) using a logger name.
Definition Helpers.hpp:28
Definition Helpers.hpp:22