native/include/utility.hpp (51 lines of code) (raw):

#pragma once #include <cstdint> #include <system_error> #include <type_traits> namespace events { ////////////////////// //// Result types //// ///////////////////// struct error_t { std::error_code value; const char * message; }; template <class T = void> class result_t { union { T result; error_t error; }; bool is_error; public: result_t() : result_t(0, "Unknown error") {} result_t(T result) : result{ std::move(result) }, is_error{ false } {} result_t(std::error_code error, const char * message) : error{ error, message } , is_error{ true } {} result_t(uint32_t error, const char * message) : result_t{ { static_cast<int>(error), std::system_category() }, message } {} explicit operator bool() const noexcept { return !is_error; } const T & get() const { if(is_error) throw std::system_error(error.value, error.message); return result; } const error_t * try_get_error() const noexcept { if(is_error) return &error; return nullptr; } operator const T & () const { return get(); } }; template <> class result_t<void> { error_t error; public: result_t(uint32_t error = 0, const char * message = nullptr) : error{ { static_cast<int>(error), std::system_category() }, message } {} explicit operator bool() const noexcept { return error.message == nullptr && error.value.value() == 0; } const error_t * try_get_error() const noexcept { if(!operator bool()) return &error; return nullptr; } }; }