5#include <knowCore/Forward.h>
19 template<
template<
typename>
class _RV_>
27 template<
typename _T_>
33 : m_success(
true), m_value(_value)
36 ReturnValue() : m_success(
false), m_message(
"Unset return value.")
38 ReturnValue(
const ReturnValue& _rhs) : m_success(_rhs.m_success), m_value(_rhs.m_value), m_message(_rhs.m_message)
40 KNOWCORE_ASSERT(m_message !=
"Unset return value.");
44 m_success = _rhs.m_success; m_value = _rhs.m_value; m_message = _rhs.m_message;
45 KNOWCORE_ASSERT(m_message !=
"Unset return value.");
48 template<
typename _TOther_,
template<
typename>
class _RV_, std::enable_if_t<FollowReturnValuePattern<_RV_>::value and std::is_convertible_v<_TOther_, _T_>,
bool> =
true>
49 ReturnValue(
const _RV_<_TOther_>& _rhs) : m_success(_rhs.success()), m_value(_rhs.value()), m_message(_rhs.message())
52 template<
typename _TOther_>
54 : m_success(_rhs.success()), m_value(_rhs.value()), m_message(_rhs.message())
56 template<
typename _TOther_>
57 explicit ReturnValue(
const ReturnValue<_TOther_>& _rhs, std::enable_if_t<details::is_instance_v<_T_, QSharedPointer> and std::is_same_v<_TOther_, _TOther_>>* =
nullptr) : m_success(_rhs.success()), m_value(_rhs.value()), m_message(_rhs.message())
61 bool success()
const {
return m_success; }
62 const _T_& value()
const {
return m_value; }
63 const _T_& expectSuccess()
const {
if(not m_success) { KNOWCORE_LOG_FATAL(
"Success was expected but got error '{}'", m_message); }
return m_value; }
64 const QString& message()
const {
return m_message; }
66 auto const& get()
const & {
67 if constexpr (I == 0)
return m_success;
68 else if constexpr (I == 1)
return m_value;
69 else if constexpr (I == 2)
return m_message;
73 if constexpr (I == 0)
return std::move(m_success);
74 else if constexpr (I == 1)
return std::move(m_value);
75 else if constexpr (I == 2)
return std::move(m_message);
91 ReturnValue() : m_success(
false), m_message(
"Unset return void.")
95 KNOWCORE_ASSERT(m_message !=
"Unset return void.");
97 template<
typename _T_>
98 Q_DECL_DEPRECATED_X(
"Use discardValue() instead")
ReturnValue(
const ReturnValue<_T_>& _rhs): m_success(_rhs.success()), m_message(_rhs.message())
101 KNOWCORE_ASSERT(m_message !=
"Unset return void.");
105 m_success = _rhs.m_success; m_message = _rhs.m_message;
106 KNOWCORE_ASSERT(m_message !=
"Unset return value.");
112 bool success()
const {
return m_success; }
113 void expectSuccess()
const {
if(not m_success) { KNOWCORE_LOG_FATAL(
"Success was expected but got error '{}'", m_message); } }
114 const QString& message()
const {
return m_message; }
116 auto const& get()
const & {
117 if constexpr (I == 0)
return m_success;
118 else if constexpr (I == 1)
return message();
122 if constexpr (I == 0)
return m_success;
123 else if constexpr (I == 1)
return message();
129 template<
typename _T_>
138 ReturnValue(
const QString& _message_value) : m_success(
true), m_message_value(_message_value)
143 bool success()
const {
return m_success; }
144 QString value()
const {
return m_success ? m_message_value : QString(); }
145 QString expectSuccess()
const {
if(Q_UNLIKELY(not m_success)) { KNOWCORE_LOG_FATAL(
"Success was expected but got error '{}'", m_message_value); }
return m_message_value; }
146 QString message()
const {
return m_success ? QString() : m_message_value; }
148 auto const get()
const & {
149 if constexpr (I == 0)
return m_success;
150 else if constexpr (I == 1)
return value();
151 else if constexpr (I == 2)
return message();
155 QString m_message_value;
159template<
typename _T_>
160struct fmt::formatter<knowCore::ReturnValue<_T_>> :
public fmt::formatter<_T_>
162 template <
typename FormatContext>
167 return fmt::formatter<_T_>::format(p.value(), ctx);
169 return format_to(ctx.out(),
"failure({})", p.message());
176 if(p.success())
return forward(
"success()", ctx);
177 else return format(ctx.out(),
"failure({})", p.message());
181 template <
typename _T_>
struct tuple_size<knowCore::ReturnValue<_T_>> : std::integral_constant<size_t, 3> { };
183 template <
typename _T_>
struct tuple_element<0, knowCore::ReturnValue<_T_>> {
using type = bool; };
184 template <
typename _T_>
struct tuple_element<1, knowCore::ReturnValue<_T_>> {
using type = _T_; };
185 template <
typename _T_>
struct tuple_element<2, knowCore::ReturnValue<_T_>> {
using type = QString; };
187 template <>
struct tuple_size<knowCore::ReturnVoid> : std::integral_constant<size_t, 2> { };
189 template <>
struct tuple_element<0, knowCore::ReturnVoid> {
using type = bool; };
190 template <>
struct tuple_element<1, knowCore::ReturnVoid> {
using type = QString; };
197template<
typename _T_>
209 return knowCore::ReturnVoid::createSuccess();
215template<
typename _T_>
218 return kCrvSuccess(_t);
221template<
typename _T_>
236template<
typename... _Args_>
251#define kCrvLogError(...) \
253 QString err = clog_qt::qformat(__VA_ARGS__); \
254 KNOWCORE_LOG_ERROR(err.toStdString()); \
255 return knowCore::ReturnValueError(err); \
258template<
typename _T_>
261 return _lhs.success() and _lhs.value() == _rhs;
264namespace knowCore::details
266 template<
typename _T_,
typename... _Args_>
273 return kCrvSuccess(_value);
275 return kCrvError(_args...);
279 template<
typename... _Args_>
282 ReturnVoid operator()(
bool _cond, _Args_... _args)
286 return kCrvSuccess();
288 return kCrvError(_args...);
294template<
typename _T_,
typename... _Args_>
300template<
typename _T_,
typename... _Args_>
303 static_assert(std::is_same_v<_T_, void>,
"For non void, a value must be given");
311template<
typename _TA_,
typename _TRV_>
314 auto const [success, value, message] = _return_value;
318 return kCrvSuccess();
320 return kCrvError(message);
325#define __KNOWCORE_KCRV_ERROR_2(_ERR_MSG_, _MSG_) _MSG_, _ERR_MSG_
326#define __KNOWCORE_KCRV_ERROR_1(_ERR_MSG_) _ERR_MSG_
328#define __KNOWCORE_KCRV_ERROR_CHOOSER(M, ...) __KNOWCORE_GET_2ND_ARG(__VA_OPT__(,) __VA_ARGS__ , __KNOWCORE_KCRV_ERROR_2, __KNOWCORE_KCRV_ERROR_1, )
330#define __KNOWCORE_KCRV_ERROR(...) __KNOWCORE_KCRV_ERROR_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
332namespace knowCore::details
340 return kCrvError(_err);
346 template<
typename... _TArgs_>
349 return kCrvError(_format, _args..., _err);
353#define __KNOWCORE_EMPTY_ACTION {}
365#define KNOWCORE_RETURN_VALUE_TRY_ASSIGN_DO(_VARIABLE_, _EXPR_, _ACTION_, ...) \
367 auto const [__krv__success__ ## __LINE__, __krv__value__ ## __LINE__, \
368 __krv__message__ ## __LINE__ ] = (_EXPR_); \
369 if(__krv__success__ ## __LINE__) { _VARIABLE_ = __krv__value__ ## __LINE__; } \
370 else { _ACTION_; return knowCore::details::kCrvErrorKRVTA(__krv__message__ ## __LINE__ __VA_OPT__(,) __VA_ARGS__); } \
383#define KNOWCORE_RETURN_VALUE_TRY_ASSIGN(_VARIABLE_, _EXPR_, ...) \
384 KNOWCORE_RETURN_VALUE_TRY_ASSIGN_DO(_VARIABLE_, (_EXPR_), __KNOWCORE_EMPTY_ACTION, __VA_ARGS__)
397#define KNOWCORE_RETURN_VALUE_TRY_DO(_VARIABLE_, _EXPR_, _ACTION_, ...) \
398 std::remove_const_t<std::remove_reference_t<decltype((_EXPR_).value())>> _VARIABLE_; \
399 KNOWCORE_RETURN_VALUE_TRY_ASSIGN_DO(_VARIABLE_, (_EXPR_), _ACTION_ __VA_OPT__(,) __VA_ARGS__)
412#define KNOWCORE_RETURN_VALUE_TRY(_VARIABLE_, _EXPR_, ...) \
413 KNOWCORE_RETURN_VALUE_TRY_DO(_VARIABLE_, (_EXPR_), __KNOWCORE_EMPTY_ACTION __VA_OPT__(,) __VA_ARGS__)
426#define KNOWCORE_RETURN_VALUE_TRY_VOID_DO(_EXPR_, _ACTION_, ...) \
428 auto const [__krv__success__ ## __LINE__, __krv__message__ ## __LINE__ ] = (_EXPR_); \
429 if(not __krv__success__ ## __LINE__) { _ACTION_; return kCrvError(__KNOWCORE_KCRV_ERROR(__krv__message__ ## __LINE__) __VA_OPT__(,) __VA_ARGS__ ); } \
443#define KNOWCORE_RETURN_VALUE_TRY_VOID(_EXPR_, ...) \
444 KNOWCORE_RETURN_VALUE_TRY_VOID_DO((_EXPR_), __KNOWCORE_EMPTY_ACTION, __VA_ARGS__)
449#define KNOWCORE_RETURN_VALUE_CHECK(_CHECK_, _ERROR_MSG_, ...) \
450 if(not (_CHECK_)) { return kCrvError(_ERROR_MSG_ __VA_OPT__(,) __VA_ARGS__); }
Definition NamedType.h:40
Definition ReturnValue.h:85
Definition ReturnValue.h:29
friend knowCore::ReturnValue< _T_ > kCrvSuccess(const _T_ &_t)
Definition ReturnValue.h:198
Definition ReturnValue.h:21
Definition ReturnValue.h:268