C system error results
In v2.2.11, C Result support went from second tier to first tier status, and
now you can create, query and manipulate a subset of Result types entirely from
within C by including <outcome/experimental/result.h>
.
The subset supported are those result<T, E>
which are a status_result<T>
i.e. the E
is hardcoded to experimental::error
which is the type erased runtime
polymorphic holder for any errored status_code
whose payload is not bigger
than an intptr_t
. This is the most useful subset of Outcome Experimental’s
possible Result types, allowing arbitrary custom error coding schemes from
any unknown source to work seamlessly with all others, including errors from
the system or third party libraries.
The operations available to C are:
CXX_DECLARE_RESULT_SYSTEM(ident, T)
- Declares to C a
status_result
type uniquely identified byident
.T
is available at the member variable.value
, andstruct cxx_status_code_system
is available at the member variable.error
. If in C++, implements C extern functions for making successful and failure results of this type. If you call this from within C++, make SURE it is not within aextern "C"
block! CXX_RESULT_SYSTEM(ident)
- A reference to a previously declared
status_result
type with uniqueident
. CXX_MAKE_RESULT_SYSTEM_SUCCESS(ident, expr)
(needs C++ counterpart linked into final binary)- This invokes the aforementioned extern function which creates a
status_result
with a successful value of typeT
. CXX_MAKE_RESULT_SYSTEM_FAILURE_POSIX(ident, expr)
(needs C++ counterpart linked into final binary)- This invokes the aforementioned extern function which creates a
status_result
with a failure of typeposix_code
representing a POSIXerrno
. CXX_MAKE_RESULT_SYSTEM_FAILURE_SYSTEM(ident, expr)
(needs C++ counterpart linked into final binary)- This invokes the aforementioned extern function which creates a
status_result
with a failure of typeposix_code
representing a POSIXerrno
if on POSIX; if on Windows then a failure of typewin32_code
representing a Win32 error code from a Windows API.
CXX_RESULT_HAS_VALUE(r)
- Evaluates to 1 (true) if the input
result
has a value. CXX_RESULT_HAS_ERROR(r)
- Evaluates to 1 (true) if the input
result
has an error. CXX_RESULT_ERROR_IS_ERRNO(r)
- Evaluates to 1 (true) if the input
result
's error value is a code in the POSIXerrno
domain.
CXX_RESULT_SYSTEM_TRY(expr)
- If the
status_result
returned byexpr
is errored, exit the current function returning the result. This obviously requires that the return type of the current function matches that ofexpr
. CXX_RESULT_SYSTEM_TRY(cleanup, expr)
- Same as the above, but execute
cleanup
just before exiting the function if returning failure. CXX_RESULT_SYSTEM_TRY(var, cleanup, expr)
- Same as the above, but set
var
equal to the result's.value
on success. CXX_RESULT_SYSTEM_TRY(var, ident, cleanup, expr)
- Same as the above, but use
ident
as the return type instead. This allows the return type of the calling function to differ from that ofexpr
.
CXX_DECLARE_RESULT_SYSTEM_FROM_ENUM(ident, enum_name, uuid, {enum mapping-sequence, ...})
- This declares to C an extern function which creates a
status_result
from a C enum. If in C++, it implements aquick_status_code_from_enum
for the C enum and the associated extern function, and you will need to supplyuuid
and the appropriate enum value mapping sequence as per thequick_status_code_from_enum
documentation. CXX_MAKE_RESULT_SYSTEM_FROM_ENUM(ident, enum_name, expr)
(needs C++ counterpart linked into final binary)- This invokes the aforementioned extern function which creates a
status_result
from a C enum.
The operations available to C++ are:
CXX_TO_RESULT_SYSTEM_CODE(ident, status_code<T>)
- Returns a previously declared C Result from its matching C++
status_code
. NOTE that the destructor of the C++ status code is NOT called. If this is important to your status code, it is 100% on you to ensure that your C Result reenters a C++ Result at the end of its lifetime. to_result(any C Result)
- This is an overloaded C++ free function which returns the C++ status_code<T> matching its input C Result.
Using the above you can write C code using Outcome.Experimental’s Result type quite effectively. Let’s look at an example of use next.