(C) 2024 - 2026 Niall Douglas http://www.nedproductions.biz/
Reference API docs: https://ned14.github.io/wg14_result/
Can be configured to be a standard library implementation for your standard C library runtime. Licensed permissively.
This is a 100% C reimplementation of https://ned14.github.io/outcome/experimental/, created as Outcome.Experimental is now on the WG14 C standardisation track and I no longer participate on WG21 (C++ standards). Features:
- 100% ABI compatible with the C++ implementation, you can freely switch
between each, even by casting pointers on objects or having C++ call via
virtualfunction into a C implementation, or vice versa. - Unlike the C API which C++ Outcome has shipped for years, this one does not require any C++ runtime to be linked into any final binaries.
- Can be configured as a header-only library (unity build) which has headers
also include their source files. If so:
- The usual C 90 minimum requirement for the headers is raised to C 11, as the library source code needs minimum C 11.
- If a C++ compiler is being used, the minimum requirement for the headers is raised to C++ 20 as previous C++ standards don't implement enough of C 11.
- Comes with optional C++ extensions where the standard member functions for the types (i.e. default, copy, move, destruct) call the C free functions which implement those operations. This means that if you are using this library from C++, or using this library via language bindings generated from the C++, lifetime management is taken care of for you.
- Language bindings are provided for:
- Rust (
bindings/rust) via Rust FFI bindgen. - SWIG
- Python (
bindings/SWIG/python) - Other languages SWIG supports should be trivial to add: C#, D, Go, Guile, Java, Javascript, Lua, OCaml, Octave, Perl, PHP, R, Ruby, Scilab, Tcl/Tk. And FORTRAN via a special fork of SWIG.
- Python (
- Rust (
// To declare to C a Result with an int value type, we use the
// WG14_RESULT_DECLARE(T, name) macro. This declares the type
// and any support functions for that type.
WG14_RESULT_DECLARE(int, int)
// We then typedef it to something concrete
typedef WG14_RESULT(int) result_int;
// A Result with a void (i.e. none) value type is predeclared.
typedef wg14_result_with_void result_void;
// Some function returning a Result with int value type.
result_int test2(int x);
result_void test3(int x)
{
// This is an example of a four macro argument TRY operation:
// out, rettype, cleanup, expression.
WG14_RESULT_TRY(
int r /* variable to extract any successful value into */,
void /* override the return result type */,
printf(
"test3 finds test1 returns failure.\n") /* cleanup to perform if TRY fails */,
test1(x) /* result returning expression to TRY */);
printf("test3 finds test1 returns successful value %d.\n", r);
// This is how to return a successful Result with no value type.
return WG14_RESULT_MAKE_SUCCESS(void, );
}This library should work well on any POSIX implementation, as well as Microsoft Windows. You will need a minimum of C 11 in your toolchain to compile the library, however its header files work in all standards of C right back to C 90 (NOTE that some macros do use features from later C standards, if on an earlier C then don't use that macro).
Current CI test targets:
- Ubuntu Linux, x64.
- Mac OS, AArch64.
- Microsoft Windows, x64.
- ESP32, RISC V.
Current compilers:
- GCC
- clang
- MSVC
You can find a number of user definable macros to override in config.h.
They have sensible defaults on the major platforms and toolchains.
status_code_errored, without Contracts it doesn't really make sense.status_codemixins, which require template trait based inheritance to be easy to use.quick_status_code_from_enumwould need C compiler magic to work I think. Not ruling that out at all, but it's definitely a later proposal paper.system_code_from_exceptionmakes no sense without C++ exceptions.- C++ i/o stream support obviously makes no sense in C.
todo
todo
todo
- Ought to write how to use documentation
- Ought to generate examples to ensure optimised codegen
- Convenience functions for serialising and printing.
- Rust bindings missing wrapping a Rust Result into a C Result i.e. going the other direction.
- Need example bindings for:
- FORTRAN
- Swift
-
status_code_domain -
status_code<void>asstatus_code_untyped -
status_code_generic -
status_code(T) -
status_code_posix -
status_code_system -
result(T) -
TRYmacros
-
status_code_nested -
status_code_getaddrinfo -
status_code_http -
status_code_win32 -
status_code_nt -
status_code_com
-
status_code_cxx_error_code -
status_code_boost_error_code