Header file status_code_domain.hpp

#include "config.hpp"

namespace system_error2
{
    template <class DomainType>
    class status_code;

    using generic_code = status_code<system_error2::_generic_code_domain>;

    class status_code_domain;
}

Class system_error2::status_code

template <class DomainType>
class status_code;

The main workhorse of the system_error2 library, can be typed (status_code<DomainType>), erased-immutable (status_code<void>) or erased-mutable (status_code<erased<T>>).

Be careful of placing these into containers! Equality and inequality operators are semantic* not exact. Therefore two distinct items will test true! To help prevent surprise on this, operator< and std::hash<> are NOT implemented in order to trap potential incorrectness. Define your own custom comparison functions for your container which perform exact comparisons.


Type alias system_error2::generic_code

using generic_code = status_code<system_error2::_generic_code_domain>;

The generic code is a status code with the generic code domain, which is that of errc (POSIX).


Class system_error2::status_code_domain

class status_code_domain
{
public:
    using unique_id_type = unsigned long long;

    class string_ref;

    class atomic_refcounted_string_ref;

protected:
    constexpr status_code_domain(system_error2::status_code_domain::unique_id_type id) noexcept;

    status_code_domain(system_error2::status_code_domain const&) = default;

    status_code_domain(system_error2::status_code_domain&&) = default;

    system_error2::status_code_domain& operator=(system_error2::status_code_domain const&) = default;

    system_error2::status_code_domain& operator=(system_error2::status_code_domain&&) = default;

    ~status_code_domain() = default;

public:
    constexpr bool operator==(system_error2::status_code_domain const& o) const noexcept;

    constexpr bool operator!=(system_error2::status_code_domain const& o) const noexcept;

    constexpr bool operator<(system_error2::status_code_domain const& o) const noexcept;

    constexpr unique_id_type id() const noexcept;

    virtual system_error2::status_code_domain::string_ref name() const noexcept = 0;

protected:
    virtual bool _do_failure(status_code<void> const& code) const noexcept = 0;

    virtual bool _do_equivalent(status_code<void> const& code1, status_code<void> const& code2) const noexcept = 0;

    virtual system_error2::generic_code _generic_code(status_code<void> const& code) const noexcept = 0;

    virtual system_error2::status_code_domain::string_ref _do_message(status_code<void> const& code) const noexcept = 0;

    virtual void _do_throw_exception(status_code<void> const& code) const = 0;

    virtual void _do_erased_copy(status_code<void>& dst, status_code<void> const& src, size_t bytes) const;

    virtual void _do_erased_destroy(status_code<void>& code, size_t bytes) const noexcept;
};

Abstract base class for a coding domain of a status code.

Type alias system_error2::status_code_domain::unique_id_type

using unique_id_type = unsigned long long;

Type of the unique id for this domain.


Class system_error2::status_code_domain::string_ref

class string_ref
{
public:
    using value_type = char const;

    using size_type = size_t;

    using pointer = char const*;

    using const_pointer = char const*;

    using iterator = char const*;

    using const_iterator = char const*;

protected:
    enum class _thunk_op;

    using _thunk_spec = void(*)(system_error2::status_code_domain::string_ref*, system_error2::status_code_domain::string_ref const*, system_error2::status_code_domain::string_ref::_thunk_op);

    pointer _begin;

    pointer _end;

    void* _state[3];

    _thunk_spec _thunk;

    constexpr string_ref(system_error2::status_code_domain::string_ref::_thunk_spec thunk) noexcept;

public:
    constexpr string_ref(char const* str, system_error2::status_code_domain::string_ref::size_type len = static_cast<size_type>(-1, void* state0 = nullptr, void* state1 = nullptr, void* state2 = nullptr, system_error2::status_code_domain::string_ref::_thunk_spec thunk = _checking_string_thunk) noexcept;

    string_ref(system_error2::status_code_domain::string_ref const& o);

    string_ref(system_error2::status_code_domain::string_ref&& o) noexcept;

    system_error2::status_code_domain::string_ref& operator=(system_error2::status_code_domain::string_ref const& o);

    system_error2::status_code_domain::string_ref& operator=(system_error2::status_code_domain::string_ref&& o) noexcept;

    ~string_ref();

    bool empty() const noexcept;

    size_type size() const noexcept;

    const_pointer c_str() const noexcept;

    const_pointer data() const noexcept;

    iterator begin() noexcept;

    const_iterator begin() const noexcept;

    const_iterator cbegin() const noexcept;

    iterator end() noexcept;

    const_iterator end() const noexcept;

    const_iterator cend() const noexcept;
};

(Potentially thread safe) Reference to a message string.

Be aware that you cannot add payload to implementations of this class. You get exactly the void *[3] array to keep state, this is usually sufficient for a std::shared_ptr<> or a std::string.

You can install a handler to be called when this object is copied, moved and destructed. This takes the form of a C function pointer.

Member variables

Type alias system_error2::status_code_domain::string_ref::value_type

using value_type = char const;

The value type


Type alias system_error2::status_code_domain::string_ref::size_type

using size_type = size_t;

The size type


Type alias system_error2::status_code_domain::string_ref::pointer

using pointer = char const*;

The pointer type


Type alias system_error2::status_code_domain::string_ref::const_pointer

using const_pointer = char const*;

The const pointer type


Type alias system_error2::status_code_domain::string_ref::iterator

using iterator = char const*;

The iterator type


Type alias system_error2::status_code_domain::string_ref::const_iterator

using const_iterator = char const*;

The const iterator type


Enumeration system_error2::status_code_domain::string_ref::_thunk_op

enum class _thunk_op
{
    copy,
    move,
    destruct
};

The operation occurring


Type alias system_error2::status_code_domain::string_ref::_thunk_spec

using _thunk_spec = void(*)(system_error2::status_code_domain::string_ref*, system_error2::status_code_domain::string_ref const*, system_error2::status_code_domain::string_ref::_thunk_op);

The prototype of the handler function. Copies can throw, moves and destructs cannot.


Constructor system_error2::status_code_domain::string_ref::string_ref

constexpr string_ref(char const* str, system_error2::status_code_domain::string_ref::size_type len = static_cast<size_type>(-1, void* state0 = nullptr, void* state1 = nullptr, void* state2 = nullptr, system_error2::status_code_domain::string_ref::_thunk_spec thunk = _checking_string_thunk) noexcept;

Construct from a C string literal


Constructor system_error2::status_code_domain::string_ref::string_ref

string_ref(system_error2::status_code_domain::string_ref const& o);

Copy construct the derived implementation.


Constructor system_error2::status_code_domain::string_ref::string_ref

string_ref(system_error2::status_code_domain::string_ref&& o) noexcept;

Move construct the derived implementation.


Function system_error2::status_code_domain::string_ref::operator=

system_error2::status_code_domain::string_ref& operator=(system_error2::status_code_domain::string_ref const& o);

Copy assignment


Function system_error2::status_code_domain::string_ref::operator=

system_error2::status_code_domain::string_ref& operator=(system_error2::status_code_domain::string_ref&& o) noexcept;

Move assignment


Destructor system_error2::status_code_domain::string_ref::~string_ref

~string_ref();

Destruction


Function system_error2::status_code_domain::string_ref::empty

bool empty() const noexcept;

Returns whether the reference is empty or not


Function system_error2::status_code_domain::string_ref::size

size_type size() const noexcept;

Returns the size of the string


Function system_error2::status_code_domain::string_ref::c_str

const_pointer c_str() const noexcept;

Returns a null terminated C string


Function system_error2::status_code_domain::string_ref::data

const_pointer data() const noexcept;

Returns a null terminated C string


Function system_error2::status_code_domain::string_ref::begin

iterator begin() noexcept;

Returns the beginning of the string


Function system_error2::status_code_domain::string_ref::begin

const_iterator begin() const noexcept;

Returns the beginning of the string


Function system_error2::status_code_domain::string_ref::cbegin

const_iterator cbegin() const noexcept;

Returns the beginning of the string


Function system_error2::status_code_domain::string_ref::end

iterator end() noexcept;

Returns the end of the string


Function system_error2::status_code_domain::string_ref::end

const_iterator end() const noexcept;

Returns the end of the string


Function system_error2::status_code_domain::string_ref::cend

const_iterator cend() const noexcept;

Returns the end of the string



Class system_error2::status_code_domain::atomic_refcounted_string_ref

class atomic_refcounted_string_ref
: public string_ref
{
public:
    explicit atomic_refcounted_string_ref(char const* str, system_error2::status_code_domain::string_ref::size_type len = static_cast<size_type>(-1, void* state1 = nullptr, void* state2 = nullptr) noexcept;
};

A reference counted, threadsafe reference to a message string.

Constructor system_error2::status_code_domain::atomic_refcounted_string_ref::atomic_refcounted_string_ref

explicit atomic_refcounted_string_ref(char const* str, system_error2::status_code_domain::string_ref::size_type len = static_cast<size_type>(-1, void* state1 = nullptr, void* state2 = nullptr) noexcept;

Construct from a C string literal allocated using malloc().



Constructor system_error2::status_code_domain::status_code_domain

constexpr status_code_domain(system_error2::status_code_domain::unique_id_type id) noexcept;

Use https://www.random.org/cgi-bin/randbyte?nbytes=8&format=h to get a random 64 bit id.

Do NOT make up your own value. Do NOT use zero.


Constructor system_error2::status_code_domain::status_code_domain

status_code_domain(system_error2::status_code_domain const&) = default;

No public copying at type erased level


Constructor system_error2::status_code_domain::status_code_domain

status_code_domain(system_error2::status_code_domain&&) = default;

No public moving at type erased level


Function system_error2::status_code_domain::operator=

system_error2::status_code_domain& operator=(system_error2::status_code_domain const&) = default;

No public assignment at type erased level


Function system_error2::status_code_domain::operator=

system_error2::status_code_domain& operator=(system_error2::status_code_domain&&) = default;

No public assignment at type erased level


Destructor system_error2::status_code_domain::~status_code_domain

~status_code_domain() = default;

No public destruction at type erased level


Function system_error2::status_code_domain::operator==

constexpr bool operator==(system_error2::status_code_domain const& o) const noexcept;

True if the unique ids match.


Function system_error2::status_code_domain::operator!=

constexpr bool operator!=(system_error2::status_code_domain const& o) const noexcept;

True if the unique ids do not match.


Function system_error2::status_code_domain::operator<

constexpr bool operator<(system_error2::status_code_domain const& o) const noexcept;

True if this unique is lower than the other’s unique id.


Function system_error2::status_code_domain::id

constexpr unique_id_type id() const noexcept;

Returns the unique id used to identify identical category instances.


Function system_error2::status_code_domain::name

virtual system_error2::status_code_domain::string_ref name() const noexcept = 0;

Name of this category.


Function system_error2::status_code_domain::_do_failure

virtual bool _do_failure(status_code<void> const& code) const noexcept = 0;

True if code means failure.


Function system_error2::status_code_domain::_do_equivalent

virtual bool _do_equivalent(status_code<void> const& code1, status_code<void> const& code2) const noexcept = 0;

True if code is (potentially non-transitively) equivalent to another code in another domain.


Function system_error2::status_code_domain::_generic_code

virtual system_error2::generic_code _generic_code(status_code<void> const& code) const noexcept = 0;

Returns the generic code closest to this code, if any.


Function system_error2::status_code_domain::_do_message

virtual system_error2::status_code_domain::string_ref _do_message(status_code<void> const& code) const noexcept = 0;

Return a reference to a string textually representing a code.


Function system_error2::status_code_domain::_do_throw_exception

virtual void _do_throw_exception(status_code<void> const& code) const = 0;

Throw a code as a C++ exception.