42template<
typename T,
typename E = std::
string>
43struct Value : std::expected<T, E>
45 using std::expected<T, E>::expected;
53 constexpr static std::array<const char[6], 5>
const m_prefix{
"D::{}",
"I::{}",
"W::{}",
"E::{}",
"C::{}"};
61 template<ns_
string::static_
string fmt>
62 constexpr static int select_prefix()
64 constexpr std::string_view sv{fmt.data};
65 return sv.starts_with(
"D")? 0
66 : sv.starts_with(
"I")? 1
67 : sv.starts_with(
"W")? 2
68 : sv.starts_with(
"E")? 3
89 if (not this->has_value())
91 logger_loc(loc, m_prefix[select_prefix<fmt>()], this->error());
92 logger_loc(loc, fmt.data, std::forward<Args>(args)...);
113 if (not this->has_value())
115 logger_loc(loc, m_prefix[select_prefix<fmt>()], this->error());
116 logger_loc(loc, fmt.data, std::forward<Args>(args)...);
117 return std::unexpected(this->error());
134 T or_default()
requires std::default_initializable<T>
136 if (!this->has_value()) {
139 return std::move(**
this);
154#define NOPT(expr, ...) NOPT_IDENTITY(__VA_OPT__(NOPT_EAT) (expr))
155#define NOPT_IDENTITY(...) __VA_ARGS__
184#define Pop(expr, ...) \
186 auto __expected_ret = (expr); \
187 if (!__expected_ret) \
189 std::string error = std::move(__expected_ret).error(); \
191 logger("D::{}", error); \
194 logger(__VA_ARGS__); \
195 error = [&](auto &&fmt, auto &&...args) \
197 if constexpr (sizeof...(args) > 0) \
199 return ns_log::vformat(std::string_view(fmt).substr(3), \
200 ns_string::to_string(args)...); \
204 return std::string_view(fmt).substr(3); \
208 return __expected_fn(std::unexpected(error)); \
210 std::move(__expected_ret).value(); \
224#define discard(fmt,...) discard_impl<fmt>(ns_log::Location() __VA_OPT__(,) __VA_ARGS__)
238#define forward(fmt,...) forward_impl<fmt>(ns_log::Location() __VA_OPT__(,) __VA_ARGS__)
260 if constexpr (std::is_void_v<std::invoke_result_t<Fn>>)
270 catch (std::exception
const& e)
272 return std::unexpected(e.what());
276 return std::unexpected(
"Unknown exception was thrown");
295#define Try(expr,...) Pop(__except_impl([&]{ return (expr); }), __VA_ARGS__)
311#define Catch(expr, ...) (__except_impl([&]{ return (expr); })__VA_OPT__(.template forward(__VA_ARGS__)))
335#define Error(fmt,...) \
337 logger(fmt __VA_OPT__(,) __VA_ARGS__); \
338 [&](auto&&... __fmt_args) \
340 if constexpr (sizeof...(__fmt_args) > 0) \
342 return std::unexpected( \
343 std::format(std::string_view(fmt).substr(3) \
344 , ns_string::to_string(__fmt_args)...) \
349 return std::unexpected( \
350 std::format(std::string_view(fmt).substr(3)) \
Concept to check if a type is an instance of a specific template.
constexpr auto __expected_fn
Lambda helper for Pop macro error returns.
auto __except_impl(Fn &&f) -> Value< std::invoke_result_t< Fn > >
Convert exceptions to Value errors.
A library for file logging.
#define logger_loc(loc, fmt,...)
Compile-time log level dispatch macro with manual location specification.
Enhanced expected type with integrated logging capabilities.
void discard_impl(ns_log::Location const &loc, Args &&... args)
Log error and discard it if present.
Value< T, E > forward_impl(ns_log::Location const &loc, Args &&... args)
Forward error with logging or return value.
Source code location information for log messages.
Compile-time string container with fixed size.