Merge branch 'amiranda/81-make-admire-error_code-a-fully-fledged-class' into 'main'
Resolve "Make `admire::error_code` a fully fledged class" This MR redefines the `admire::error_code` typedef transforming it into a fully-fledged C++ object. This has the following advantages: 1. The default `error_code` constructor initializes to `ADM_SUCCESS`. Thus, we can now do `error_code ec;` instead of `error_code ec = ADM_SUCCESS;`. 2. `error_code`s can be constructed explicitly from `ADM_return_t` values. 3. `error_code`s can be constructed explicitly from `int32_t` (for RPC types). 4. `error_code`s can be converted implicitly to `ADM_return_t`, which makes code less verbose when returning from C++ code to the C code. 5. `error_code`s are convertible to `bool`. This means that we can now do ```c++ error_code ec = fun(); if(ec) { /* there was an error, do something */ } ``` whereas previously we were forced to explicitly check against `ADM_SUCCESS`. ```c++ error_code ec = fun(); if(ec != ADM_SUCCESS) { /* there was an error, do something */ } ``` 6. `error_code`s provide `value()`, `name()`, and `message()` functions that make them much more flexible. 7. Several `error_code` constants are defined to avoid using `ADM_return_t` directly in C++ code, hopefully making the code more readable: ```c++ constexpr error_code error_code::success = error_code{ADM_SUCCESS}; constexpr error_code error_code::snafu = error_code{ADM_ESNAFU}; constexpr error_code error_code::bad_args = error_code{ADM_EBADARGS}; constexpr error_code error_code::out_of_memory = error_code{ADM_ENOMEM}; constexpr error_code error_code::entity_exists = error_code{ADM_EEXISTS}; constexpr error_code error_code::no_such_entity = error_code{ADM_ENOENT}; constexpr error_code error_code::adhoc_in_use = error_code{ADM_EADHOC_BUSY}; constexpr error_code error_code::other = error_code{ADM_EOTHER}; ``` Also, most of the implementation is `constexpr`, which is always nice. Closes #81 See merge request !61