/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_HPP
#define SYSTEM_ERROR2_HPP
/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_ERROR_HPP
#define SYSTEM_ERROR2_ERROR_HPP
/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Jun 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_ERRORED_STATUS_CODE_HPP
#define SYSTEM_ERROR2_ERRORED_STATUS_CODE_HPP
/* Proposed SG14 status_code
(C) 2018 - 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: May 2020


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_HPP
#define SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_HPP
/* Proposed SG14 status_code
(C) 2018 - 2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_GENERIC_CODE_HPP
#define SYSTEM_ERROR2_GENERIC_CODE_HPP
/* Proposed SG14 status_code
(C) 2018 - 2022 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_STATUS_ERROR_HPP
#define SYSTEM_ERROR2_STATUS_ERROR_HPP
/* Proposed SG14 status_code
(C) 2018 - 2023 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_STATUS_CODE_HPP
#define SYSTEM_ERROR2_STATUS_CODE_HPP
/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_STATUS_CODE_DOMAIN_HPP
#define SYSTEM_ERROR2_STATUS_CODE_DOMAIN_HPP
/* Proposed SG14 status_code
(C) 2018 - 2021 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_CONFIG_HPP
#define SYSTEM_ERROR2_CONFIG_HPP
// < 0.1 each
#include <cassert>
#include <cstddef> // for size_t
#include <cstdlib> // for free
// 0.22
#include <type_traits>
// 0.29
#include <atomic>
// 0.28 (0.15 of which is exception_ptr)
#include <exception> // for std::exception
// <new> includes <exception>, <exception> includes <new>
#include <new>
// 0.01
#include <initializer_list>
#ifndef SYSTEM_ERROR2_HAVE_BIT_CAST
#ifdef __has_include
#if __has_include(<bit>) && (__cplusplus >= 202002L || _HAS_CXX20)
#define SYSTEM_ERROR2_HAVE_BIT_CAST 1
#endif
#elif __cplusplus >= 202002L
#define SYSTEM_ERROR2_HAVE_BIT_CAST 1
#endif
#ifndef SYSTEM_ERROR2_HAVE_BIT_CAST
#define SYSTEM_ERROR2_HAVE_BIT_CAST 0
#endif
#endif
#if SYSTEM_ERROR2_HAVE_BIT_CAST
#include <bit>
#if __cpp_lib_bit_cast < 201806L
#undef SYSTEM_ERROR2_HAVE_BIT_CAST
#define SYSTEM_ERROR2_HAVE_BIT_CAST 0
#endif
#endif
#if SYSTEM_ERROR2_USE_STD_ADDRESSOF
#include <memory> // for std::addressof
#define SYSTEM_ERROR2_ADDRESS_OF(...) std::addressof(__VA_ARGS__)
#else
#define SYSTEM_ERROR2_ADDRESS_OF(...) (&__VA_ARGS__)
#endif
#ifndef SYSTEM_ERROR2_CONSTEXPR14
#if 0L || __cplusplus >= 201400 || _MSC_VER >= 1910 /* VS2017 */
//! Defined to be `constexpr` when on C++ 14 or better compilers. Usually automatic, can be overriden.
#define SYSTEM_ERROR2_CONSTEXPR14 constexpr
#else
#define SYSTEM_ERROR2_CONSTEXPR14
#endif
#endif
#ifndef SYSTEM_ERROR2_CONSTEXPR20
#if 0L || __cplusplus >= 202000 || _HAS_CXX20
//! Defined to be `constexpr` when on C++ 20 or better compilers. Usually automatic, can be overriden.
#define SYSTEM_ERROR2_CONSTEXPR20 constexpr
#else
#define SYSTEM_ERROR2_CONSTEXPR20
#endif
#endif
#ifndef SYSTEM_ERROR2_NORETURN
#if 0L || (_HAS_CXX17 && _MSC_VER >= 1911 /* VS2017.3 */)
#define SYSTEM_ERROR2_NORETURN [[noreturn]]
#endif
#endif
#if !defined(SYSTEM_ERROR2_NORETURN)
#ifdef __has_cpp_attribute
#if __has_cpp_attribute(noreturn)
#define SYSTEM_ERROR2_NORETURN [[noreturn]]
#endif
#endif
#endif
#if !defined(SYSTEM_ERROR2_NORETURN)
#if defined(_MSC_VER)
#define SYSTEM_ERROR2_NORETURN __declspec(noreturn)
#elif defined(__GNUC__)
#define SYSTEM_ERROR2_NORETURN __attribute__((__noreturn__))
#else
#define SYSTEM_ERROR2_NORETURN
#endif
#endif
// GCCs before 7 don't grok [[noreturn]] virtual functions, and warn annoyingly
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 7
#undef SYSTEM_ERROR2_NORETURN
#define SYSTEM_ERROR2_NORETURN
#endif
#ifndef SYSTEM_ERROR2_NODISCARD
#if 0L || (_HAS_CXX17 && _MSC_VER >= 1911 /* VS2017.3 */)
#define SYSTEM_ERROR2_NODISCARD [[nodiscard]]
#endif
#endif
#ifndef SYSTEM_ERROR2_NODISCARD
#ifdef __has_cpp_attribute
#if __has_cpp_attribute(nodiscard)
#define SYSTEM_ERROR2_NODISCARD [[nodiscard]]
#endif
#elif defined(__clang__)
#define SYSTEM_ERROR2_NODISCARD __attribute__((warn_unused_result))
#elif defined(_MSC_VER)
// _Must_inspect_result_ expands into this
#define SYSTEM_ERROR2_NODISCARD __declspec( "SAL_name" "(" "\"_Must_inspect_result_\"" "," "\"\"" "," "\"2\"" ")") __declspec("SAL_begin") __declspec("SAL_post") __declspec("SAL_mustInspect") __declspec("SAL_post") __declspec("SAL_checkReturn") __declspec("SAL_end")
#endif
#endif
#ifndef SYSTEM_ERROR2_NODISCARD
#define SYSTEM_ERROR2_NODISCARD
#endif
#ifndef SYSTEM_ERROR2_TRIVIAL_ABI
#if 0L || (__clang_major__ >= 7 && !defined(__APPLE__))
//! Defined to be `[[clang::trivial_abi]]` when on a new enough clang compiler. Usually automatic, can be overriden.
#define SYSTEM_ERROR2_TRIVIAL_ABI [[clang::trivial_abi]]
#else
#define SYSTEM_ERROR2_TRIVIAL_ABI
#endif
#endif
#if defined(__cpp_concepts) && !defined(SYSTEM_ERROR2_DISABLE_CONCEPTS_SUPPORT)
#define SYSTEM_ERROR2_GLUE(x, y) x y
#define SYSTEM_ERROR2_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, count, ...) count
#define SYSTEM_ERROR2_EXPAND_ARGS(args) SYSTEM_ERROR2_RETURN_ARG_COUNT args
#define SYSTEM_ERROR2_COUNT_ARGS_MAX8(...) SYSTEM_ERROR2_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define SYSTEM_ERROR2_OVERLOAD_MACRO2(name, count) name##count
#define SYSTEM_ERROR2_OVERLOAD_MACRO1(name, count) SYSTEM_ERROR2_OVERLOAD_MACRO2(name, count)
#define SYSTEM_ERROR2_OVERLOAD_MACRO(name, count) SYSTEM_ERROR2_OVERLOAD_MACRO1(name, count)
#define SYSTEM_ERROR2_CALL_OVERLOAD(name, ...) SYSTEM_ERROR2_GLUE(SYSTEM_ERROR2_OVERLOAD_MACRO(name, SYSTEM_ERROR2_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__))
#define SYSTEM_ERROR2_TREQUIRES_EXPAND8(a, b, c, d, e, f, g, h) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND7(b, c, d, e, f, g, h)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND7(a, b, c, d, e, f, g) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND6(b, c, d, e, f, g)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND6(a, b, c, d, e, f) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND5(b, c, d, e, f)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND5(a, b, c, d, e) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND4(b, c, d, e)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND4(a, b, c, d) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND3(b, c, d)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND3(a, b, c) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND2(b, c)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND2(a, b) a &&SYSTEM_ERROR2_TREQUIRES_EXPAND1(b)
#define SYSTEM_ERROR2_TREQUIRES_EXPAND1(a) a
//! Expands into a && b && c && ...
#define SYSTEM_ERROR2_TREQUIRES(...) requires SYSTEM_ERROR2_CALL_OVERLOAD(SYSTEM_ERROR2_TREQUIRES_EXPAND, __VA_ARGS__)
#define SYSTEM_ERROR2_TEMPLATE(...) template <__VA_ARGS__>
#define SYSTEM_ERROR2_TEXPR(...) requires { (__VA_ARGS__); }
#define SYSTEM_ERROR2_TPRED(...) (__VA_ARGS__)
#if !defined(_MSC_VER) || _MSC_FULL_VER >= 192400000 // VS 2019 16.3 is broken here
#define SYSTEM_ERROR2_REQUIRES(...) requires(__VA_ARGS__)
#else
#define SYSTEM_ERROR2_REQUIRES(...)
#endif
#else
#define SYSTEM_ERROR2_TEMPLATE(...) template <__VA_ARGS__
#define SYSTEM_ERROR2_TREQUIRES(...) , __VA_ARGS__ >
#define SYSTEM_ERROR2_TEXPR(...) typename = decltype(__VA_ARGS__)
#ifdef _MSC_VER
// MSVC gives an error if every specialisation of a template is always ill-formed, so
// the more powerful SFINAE form below causes pukeage :(
#define SYSTEM_ERROR2_TPRED(...) typename = typename std::enable_if<(__VA_ARGS__)>::type
#else
#define SYSTEM_ERROR2_TPRED(...) typename std::enable_if<(__VA_ARGS__), bool>::type = true
#endif
#define SYSTEM_ERROR2_REQUIRES(...)
#endif
#ifndef SYSTEM_ERROR2_NAMESPACE
//! The system_error2 namespace name.
#define SYSTEM_ERROR2_NAMESPACE system_error2
//! Begins the system_error2 namespace.
#define SYSTEM_ERROR2_NAMESPACE_BEGIN namespace system_error2 {
//! Ends the system_error2 namespace.
#define SYSTEM_ERROR2_NAMESPACE_END }
#endif
//! Namespace for the library
SYSTEM_ERROR2_NAMESPACE_BEGIN
//! Namespace for user specialised traits
namespace traits
{
  /*! Specialise to true if you guarantee that a type is move bitcopying (i.e.
  its move constructor equals copying bits from old to new, old is left in a
  default constructed state, and calling the destructor on a default constructed
  instance is trivial). All trivially copyable types are move bitcopying by
  definition, and that is the unspecialised implementation.
  */
  template <class T> struct is_move_bitcopying
  {
    static constexpr bool value = std::is_trivially_copyable<T>::value;
  };
} // namespace traits
namespace detail
{
#if __cplusplus >= 201400 || _MSC_VER >= 1910 /* VS2017 */
  inline constexpr size_t cstrlen(const char *str)
  {
    const char *end = nullptr;
    for(end = str; *end != 0; ++end) // NOLINT
      ;
    return end - str;
  }
#else
  inline constexpr size_t cstrlen_(const char *str, size_t acc) { return (str[0] == 0) ? acc : cstrlen_(str + 1, acc + 1); }
  inline constexpr size_t cstrlen(const char *str) { return cstrlen_(str, 0); }
#endif
#if (__cplusplus >= 202002L || _MSVC_LANG >= 202002L) && __cpp_lib_remove_cvref >= 201711L
  template <class T> using remove_cvref = std::remove_cvref<T>;
#else
  template <class T> struct remove_cvref
  {
    using type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
  };
#endif
  /* A partially compliant implementation of C++20's std::bit_cast function contributed
  by Jesse Towner.

  Our bit_cast is only guaranteed to be constexpr when both the input and output
  arguments are either integrals or enums. However, this covers most use cases
  since the vast majority of status_codes have an underlying type that is either
  an integral or enum. We still attempt a constexpr union-based type pun for non-array
  input types, which some compilers accept. For array inputs, we fall back to
  non-constexpr memmove.
  */
  template <class T> using is_integral_or_enum = std::integral_constant<bool, std::is_integral<T>::value || std::is_enum<T>::value>;
  template <class To, class From> using is_static_castable = std::integral_constant<bool, is_integral_or_enum<To>::value && is_integral_or_enum<From>::value>;
  template <class To, class From>
  using is_union_castable = std::integral_constant<bool, !is_static_castable<To, From>::value && !std::is_array<To>::value && !std::is_array<From>::value>;
  template <class To, class From>
  using is_bit_castable =
  std::integral_constant<bool, sizeof(To) == sizeof(From) && traits::is_move_bitcopying<To>::value && traits::is_move_bitcopying<From>::value>;
  template <class To, class From> union bit_cast_union
  {
    From source;
    To target;
  };
#if SYSTEM_ERROR2_HAVE_BIT_CAST
  using std::bit_cast; // available for all trivially copyable types
  // For move bit copying types
  template <class To, class From>
  requires(is_bit_castable<To, From>::value //
           &&is_union_castable<To, From>::value //
           && (!std::is_trivially_copyable_v<From> //
               || !std::is_trivially_copyable_v<To>) ) //
  constexpr To bit_cast(const From &from) noexcept
  {
    return bit_cast_union<To, From>{from}.target;
  }
  template <class To, class From>
  requires(is_bit_castable<To, From>::value //
           && !is_union_castable<To, From>::value //
           && (!std::is_trivially_copyable_v<From> //
               || !std::is_trivially_copyable_v<To>) ) //
  To bit_cast(const From &from)
  noexcept
  {
    bit_cast_union<To, From> ret;
    memmove(&ret.source, &from, sizeof(ret.source));
    return ret.target;
  }
#else
  SYSTEM_ERROR2_TEMPLATE(class To, class From, int = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_bit_castable<To, From>::value //
                                              &&is_static_castable<To, From>::value //
                                              && !is_union_castable<To, From>::value))
  constexpr To bit_cast(const From &from) noexcept { return static_cast<To>(from); }
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
  SYSTEM_ERROR2_TEMPLATE(class To, class From, long = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_bit_castable<To, From>::value //
                                              && !is_static_castable<To, From>::value //
                                              && is_union_castable<To, From>::value))
  constexpr To bit_cast(const From &from) noexcept { return bit_cast_union<To, From>{from}.target; }
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
  SYSTEM_ERROR2_TEMPLATE(class To, class From, short = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_bit_castable<To, From>::value //
                                              && !is_static_castable<To, From>::value //
                                              && !is_union_castable<To, From>::value))
  To bit_cast(const From &from) noexcept
  {
    bit_cast_union<To, From> ret;
    memmove(&ret.source, &from, sizeof(ret.source));
    return ret.target;
  }
#endif
  /* erasure_cast performs a bit_cast with additional rules to handle types
  of differing sizes. For integral & enum types, it may perform a narrowing
  or widing conversion with static_cast if necessary, before doing the final
  conversion with bit_cast. When casting to or from non-integral, non-enum
  types it may insert the value into another object with extra padding bytes
  to satisfy bit_cast's preconditions that both types have the same size. */
  template <class To, class From>
  using is_erasure_castable = std::integral_constant<bool, traits::is_move_bitcopying<To>::value && traits::is_move_bitcopying<From>::value>;
  template <class T, bool = std::is_enum<T>::value> struct identity_or_underlying_type
  {
    using type = T;
  };
  template <class T> struct identity_or_underlying_type<T, true>
  {
    using type = typename std::underlying_type<T>::type;
  };
  template <class OfSize, class OfSign>
  using erasure_integer_type = typename std::conditional<std::is_signed<typename identity_or_underlying_type<OfSign>::type>::value,
                                                         typename std::make_signed<typename identity_or_underlying_type<OfSize>::type>::type,
                                                         typename std::make_unsigned<typename identity_or_underlying_type<OfSize>::type>::type>::type;
  template <class ErasedType, std::size_t N> struct padded_erasure_object
  {
    static_assert(traits::is_move_bitcopying<ErasedType>::value, "ErasedType must be TriviallyCopyable or MoveBitcopying");
    static_assert(alignof(ErasedType) <= sizeof(ErasedType), "ErasedType must not be over-aligned");
    ErasedType value;
    char padding[N];
    constexpr explicit padded_erasure_object(const ErasedType &v) noexcept
        : value(v)
        , padding{}
    {
    }
  };
  SYSTEM_ERROR2_TEMPLATE(class To, class From)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value && (sizeof(To) == sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(from); }
#if defined(_WIN32) || defined(__APPLE__) || __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN)
  // We can avoid the type pun on little endian architectures which can aid optimisation
  SYSTEM_ERROR2_TEMPLATE(class To, class From, long = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value &&is_static_castable<To, From>::value && (sizeof(To) < sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return static_cast<To>(bit_cast<erasure_integer_type<From, To>>(from)); }
  SYSTEM_ERROR2_TEMPLATE(class To, class From, int = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value &&is_static_castable<To, From>::value && (sizeof(To) > sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(static_cast<erasure_integer_type<To, From>>(from)); }
  SYSTEM_ERROR2_TEMPLATE(class To, class From, short = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value && !is_static_castable<To, From>::value && (sizeof(To) < sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return bit_cast<padded_erasure_object<To, sizeof(From) - sizeof(To)>>(from).value; }
  SYSTEM_ERROR2_TEMPLATE(class To, class From, char = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value && !is_static_castable<To, From>::value && (sizeof(To) > sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(padded_erasure_object<From, sizeof(To) - sizeof(From)>{from}); }
#else
  SYSTEM_ERROR2_TEMPLATE(class To, class From, short = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value && (sizeof(To) < sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return bit_cast<padded_erasure_object<To, sizeof(From) - sizeof(To)>>(from).value; }
  SYSTEM_ERROR2_TEMPLATE(class To, class From, char = 5)
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_erasure_castable<To, From>::value && (sizeof(To) > sizeof(From))))
  constexpr To erasure_cast(const From &from) noexcept { return bit_cast<To>(padded_erasure_object<From, sizeof(To) - sizeof(From)>{from}); }
#endif
} // namespace detail
SYSTEM_ERROR2_NAMESPACE_END
#ifndef SYSTEM_ERROR2_FATAL
#ifdef SYSTEM_ERROR2_NOT_POSIX
#error If SYSTEM_ERROR2_NOT_POSIX is defined, you must define your own SYSTEM_ERROR2_FATAL implementation!
#endif
#include <cstdlib> // for abort
#ifdef __APPLE__
#include <unistd.h> // for write
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
namespace detail
{
  namespace avoid_stdio_include
  {
#if !defined(__APPLE__) && !defined(_MSC_VER)
    extern "C" ptrdiff_t write(int, const void *, size_t);
#elif defined(_MSC_VER)
    extern ptrdiff_t write(int, const void *, size_t);
#if (defined(__x86_64__) || defined(_M_X64)) || (defined(__aarch64__) || defined(_M_ARM64)) || (defined(__arm__) || defined(_M_ARM))
#pragma comment(linker, "/alternatename:?write@avoid_stdio_include@detail@system_error2@@YA_JHPEBX_K@Z=write")
#elif defined(__x86__) || defined(_M_IX86) || defined(__i386__)
#pragma comment(linker, "/alternatename:?write@avoid_stdio_include@detail@system_error2@@YAHHPBXI@Z=_write")
#else
#error Unknown architecture
#endif
#endif
  } // namespace avoid_stdio_include
  inline void do_fatal_exit(const char *msg)
  {
    using namespace avoid_stdio_include;
    write(2 /*stderr*/, msg, cstrlen(msg));
    write(2 /*stderr*/, "\n", 1);
    abort();
  }
} // namespace detail
SYSTEM_ERROR2_NAMESPACE_END
//! Prints msg to stderr, and calls `std::terminate()`. Can be overriden via predefinition.
#define SYSTEM_ERROR2_FATAL(msg) ::SYSTEM_ERROR2_NAMESPACE::detail::do_fatal_exit(msg)
#endif
#endif
#include <cstring> // for strchr
SYSTEM_ERROR2_NAMESPACE_BEGIN
/*! 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.
*/
template <class DomainType> class status_code;
class _generic_code_domain;
//! The generic code is a status code with the generic code domain, which is that of `errc` (POSIX).
using generic_code = status_code<_generic_code_domain>;
namespace detail
{
  template <class StatusCode, class Allocator> class indirecting_domain;
  /* We are severely limited by needing to retain C++ 11 compatibility when doing
  constexpr string parsing. MSVC lets you throw exceptions within a constexpr
  evaluation context when exceptions are globally disabled, but won't let you
  divide by zero, even if never evaluated, ever in constexpr. GCC and clang won't
  let you throw exceptions, ever, if exceptions are globally disabled. So let's
  use the trick of divide by zero in constexpr on GCC and clang if and only if
  exceptions are globally disabled.
  */
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdiv-by-zero"
#endif
#if defined(__cpp_exceptions) || (defined(_MSC_VER) && !defined(__clang__))
#define SYSTEM_ERROR2_FAIL_CONSTEXPR(msg) throw msg
#else
#define SYSTEM_ERROR2_FAIL_CONSTEXPR(msg) ((void) msg, 1 / 0)
#endif
  constexpr inline unsigned long long parse_hex_byte(char c)
  {
    return ('0' <= c && c <= '9') ? (c - '0') :
           ('a' <= c && c <= 'f') ? (10 + c - 'a') :
           ('A' <= c && c <= 'F') ? (10 + c - 'A') :
                                    SYSTEM_ERROR2_FAIL_CONSTEXPR("Invalid character in UUID");
  }
  constexpr inline unsigned long long parse_uuid2(const char *s)
  {
    return ((parse_hex_byte(s[0]) << 0) | (parse_hex_byte(s[1]) << 4) | (parse_hex_byte(s[2]) << 8) | (parse_hex_byte(s[3]) << 12) |
            (parse_hex_byte(s[4]) << 16) | (parse_hex_byte(s[5]) << 20) | (parse_hex_byte(s[6]) << 24) | (parse_hex_byte(s[7]) << 28) |
            (parse_hex_byte(s[9]) << 32) | (parse_hex_byte(s[10]) << 36) | (parse_hex_byte(s[11]) << 40) | (parse_hex_byte(s[12]) << 44) |
            (parse_hex_byte(s[14]) << 48) | (parse_hex_byte(s[15]) << 52) | (parse_hex_byte(s[16]) << 56) | (parse_hex_byte(s[17]) << 60)) //
           ^ //
           ((parse_hex_byte(s[19]) << 0) | (parse_hex_byte(s[20]) << 4) | (parse_hex_byte(s[21]) << 8) | (parse_hex_byte(s[22]) << 12) |
            (parse_hex_byte(s[24]) << 16) | (parse_hex_byte(s[25]) << 20) | (parse_hex_byte(s[26]) << 24) | (parse_hex_byte(s[27]) << 28) |
            (parse_hex_byte(s[28]) << 32) | (parse_hex_byte(s[29]) << 36) | (parse_hex_byte(s[30]) << 40) | (parse_hex_byte(s[31]) << 44) |
            (parse_hex_byte(s[32]) << 48) | (parse_hex_byte(s[33]) << 52) | (parse_hex_byte(s[34]) << 56) | (parse_hex_byte(s[35]) << 60));
  }
  template <size_t N> constexpr inline unsigned long long parse_uuid_from_array(const char (&uuid)[N])
  {
    return (N == 37) ? parse_uuid2(uuid) : ((N == 39) ? parse_uuid2(uuid + 1) : SYSTEM_ERROR2_FAIL_CONSTEXPR("UUID does not have correct length"));
  }
  template <size_t N> constexpr inline unsigned long long parse_uuid_from_pointer(const char *uuid)
  {
    return (N == 36) ? parse_uuid2(uuid) : ((N == 38) ? parse_uuid2(uuid + 1) : SYSTEM_ERROR2_FAIL_CONSTEXPR("UUID does not have correct length"));
  }
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
  static constexpr unsigned long long test_uuid_parse = parse_uuid_from_array("430f1201-94fc-06c7-430f-120194fc06c7");
  // static constexpr unsigned long long test_uuid_parse2 = parse_uuid_from_array("x30f1201-94fc-06c7-430f-120194fc06c7");
} // namespace detail
/*! Abstract base class for a coding domain of a status code.
 */
class status_code_domain
{
  template <class DomainType> friend class status_code;
  template <class StatusCode, class Allocator> friend class indirecting_domain;
public:
  //! Type of the unique id for this domain.
  using unique_id_type = unsigned long long;
  /*! (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.
  */
  class string_ref
  {
  public:
    //! The value type
    using value_type = const char;
    //! The size type
    using size_type = size_t;
    //! The pointer type
    using pointer = const char *;
    //! The const pointer type
    using const_pointer = const char *;
    //! The iterator type
    using iterator = const char *;
    //! The const iterator type
    using const_iterator = const char *;
  protected:
    //! The operation occurring
    enum class _thunk_op
    {
      copy,
      move,
      destruct
    };
    //! The prototype of the handler function. Copies can throw, moves and destructs cannot.
    using _thunk_spec = void (*)(string_ref *dest, const string_ref *src, _thunk_op op);
#ifndef NDEBUG
  private:
    static void _checking_string_thunk(string_ref *dest, const string_ref *src, _thunk_op /*unused*/) noexcept
    {
      (void) dest;
      (void) src;
      assert(dest->_thunk == _checking_string_thunk); // NOLINT
      assert(src == nullptr || src->_thunk == _checking_string_thunk); // NOLINT
      // do nothing
    }
  protected:
#endif
    //! Pointers to beginning and end of character range
    pointer _begin{}, _end{};
    //! Three `void*` of state
    void *_state[3]{}; // at least the size of a shared_ptr
    //! Handler for when operations occur
    const _thunk_spec _thunk{nullptr};
    constexpr explicit string_ref(_thunk_spec thunk) noexcept
        : _thunk(thunk)
    {
    }
  public:
    //! Construct from a C string literal
    SYSTEM_ERROR2_CONSTEXPR14 explicit string_ref(const char *str, size_type len = static_cast<size_type>(-1), void *state0 = nullptr, void *state1 = nullptr,
                                                  void *state2 = nullptr,
#ifndef NDEBUG
                                                  _thunk_spec thunk = _checking_string_thunk
#else
                                                  _thunk_spec thunk = nullptr
#endif
                                                  ) noexcept
        : _begin(str)
        , _end((len == static_cast<size_type>(-1)) ? (str + detail::cstrlen(str)) : (str + len))
        , // NOLINT
        _state{state0, state1, state2}
        , _thunk(thunk)
    {
    }
    //! Copy construct the derived implementation.
    SYSTEM_ERROR2_CONSTEXPR20 string_ref(const string_ref &o)
        : _begin(o._begin)
        , _end(o._end)
        , _state{o._state[0], o._state[1], o._state[2]}
        , _thunk(o._thunk)
    {
      if(_thunk != nullptr)
      {
        _thunk(this, &o, _thunk_op::copy);
      }
    }
    //! Move construct the derived implementation.
    SYSTEM_ERROR2_CONSTEXPR20 string_ref(string_ref &&o) noexcept
        : _begin(o._begin)
        , _end(o._end)
        , _state{o._state[0], o._state[1], o._state[2]}
        , _thunk(o._thunk)
    {
      if(_thunk != nullptr)
      {
        _thunk(this, &o, _thunk_op::move);
      }
    }
    //! Copy assignment
    SYSTEM_ERROR2_CONSTEXPR20 string_ref &operator=(const string_ref &o)
    {
      if(this != &o)
      {
#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
        string_ref temp(static_cast<string_ref &&>(*this));
        this->~string_ref();
        try
        {
          new(this) string_ref(o); // may throw
        }
        catch(...)
        {
          new(this) string_ref(static_cast<string_ref &&>(temp));
          throw;
        }
#else
        this->~string_ref();
        new(this) string_ref(o);
#endif
      }
      return *this;
    }
    //! Move assignment
    SYSTEM_ERROR2_CONSTEXPR20 string_ref &operator=(string_ref &&o) noexcept
    {
      if(this != &o)
      {
        this->~string_ref();
        new(this) string_ref(static_cast<string_ref &&>(o));
      }
      return *this;
    }
    //! Destruction
    SYSTEM_ERROR2_CONSTEXPR20 ~string_ref()
    {
      if(_thunk != nullptr)
      {
        _thunk(this, nullptr, _thunk_op::destruct);
      }
      _begin = _end = nullptr;
    }
    //! Returns whether the reference is empty or not
    SYSTEM_ERROR2_NODISCARD constexpr bool empty() const noexcept { return _begin == _end; }
    //! Returns the size of the string
    constexpr size_type size() const noexcept { return _end - _begin; }
    //! Returns a null terminated C string
    constexpr const_pointer c_str() const noexcept { return _begin; }
    //! Returns a null terminated C string
    constexpr const_pointer data() const noexcept { return _begin; }
    //! Returns the beginning of the string
    SYSTEM_ERROR2_CONSTEXPR14 iterator begin() noexcept { return _begin; }
    //! Returns the beginning of the string
    SYSTEM_ERROR2_CONSTEXPR14 const_iterator begin() const noexcept { return _begin; }
    //! Returns the beginning of the string
    constexpr const_iterator cbegin() const noexcept { return _begin; }
    //! Returns the end of the string
    SYSTEM_ERROR2_CONSTEXPR14 iterator end() noexcept { return _end; }
    //! Returns the end of the string
    SYSTEM_ERROR2_CONSTEXPR14 const_iterator end() const noexcept { return _end; }
    //! Returns the end of the string
    constexpr const_iterator cend() const noexcept { return _end; }
  };
  /*! A reference counted, threadsafe reference to a message string.
   */
  class atomic_refcounted_string_ref : public string_ref
  {
    struct _allocated_msg
    {
      mutable std::atomic<unsigned> count{1};
    };
    _allocated_msg *&_msg() noexcept { return reinterpret_cast<_allocated_msg *&>(this->_state[0]); } // NOLINT
    const _allocated_msg *_msg() const noexcept { return reinterpret_cast<const _allocated_msg *>(this->_state[0]); } // NOLINT
    static SYSTEM_ERROR2_CONSTEXPR20 void _refcounted_string_thunk(string_ref *_dest, const string_ref *_src, _thunk_op op) noexcept
    {
      auto dest = static_cast<atomic_refcounted_string_ref *>(_dest); // NOLINT
      auto src = static_cast<const atomic_refcounted_string_ref *>(_src); // NOLINT
      (void) src;
      assert(dest->_thunk == _refcounted_string_thunk); // NOLINT
      assert(src == nullptr || src->_thunk == _refcounted_string_thunk); // NOLINT
      switch(op)
      {
      case _thunk_op::copy:
      {
        if(dest->_msg() != nullptr)
        {
          auto count = dest->_msg()->count.fetch_add(1, std::memory_order_relaxed);
          (void) count;
          assert(count != 0); // NOLINT
        }
        return;
      }
      case _thunk_op::move:
      {
        assert(src); // NOLINT
        auto msrc = const_cast<atomic_refcounted_string_ref *>(src); // NOLINT
        msrc->_begin = msrc->_end = nullptr;
        msrc->_state[0] = msrc->_state[1] = msrc->_state[2] = nullptr;
        return;
      }
      case _thunk_op::destruct:
      {
        if(dest->_msg() != nullptr)
        {
          auto count = dest->_msg()->count.fetch_sub(1, std::memory_order_release);
          if(count == 1)
          {
            std::atomic_thread_fence(std::memory_order_acquire);
            free((void *) dest->_begin); // NOLINT
            delete dest->_msg(); // NOLINT
          }
        }
      }
      }
    }
  public:
    //! Construct from a C string literal allocated using `malloc()`.
    explicit atomic_refcounted_string_ref(const char *str, size_type len = static_cast<size_type>(-1), void *state1 = nullptr, void *state2 = nullptr) noexcept
        : string_ref(str, len, new(std::nothrow) _allocated_msg, state1, state2, _refcounted_string_thunk)
    {
      if(_msg() == nullptr)
      {
        free((void *) this->_begin); // NOLINT
        _msg() = nullptr; // disabled
        this->_begin = "failed to get message from system";
        this->_end = strchr(this->_begin, 0);
        return;
      }
    }
  };
private:
  unique_id_type _id;
protected:
  /*! Use [https://www.random.org/cgi-bin/randbyte?nbytes=8&format=h](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.
  */
  constexpr explicit status_code_domain(unique_id_type id) noexcept
      : _id(id)
  {
  }
  /*! UUID constructor, where input is constexpr parsed into a `unique_id_type`.
   */
  template <size_t N>
  constexpr explicit status_code_domain(const char (&uuid)[N]) noexcept
      : _id(detail::parse_uuid_from_array<N>(uuid))
  {
  }
  template <size_t N> struct _uuid_size
  {
  };
  //! Alternative UUID constructor
  template <size_t N>
  constexpr explicit status_code_domain(const char *uuid, _uuid_size<N> /*unused*/) noexcept
      : _id(detail::parse_uuid_from_pointer<N>(uuid))
  {
  }
  //! No public copying at type erased level
  status_code_domain(const status_code_domain &) = default;
  //! No public moving at type erased level
  status_code_domain(status_code_domain &&) = default;
  //! No public assignment at type erased level
  status_code_domain &operator=(const status_code_domain &) = default;
  //! No public assignment at type erased level
  status_code_domain &operator=(status_code_domain &&) = default;
  //! No public destruction at type erased level
  ~status_code_domain() = default;
public:
  //! True if the unique ids match.
  constexpr bool operator==(const status_code_domain &o) const noexcept { return _id == o._id; }
  //! True if the unique ids do not match.
  constexpr bool operator!=(const status_code_domain &o) const noexcept { return _id != o._id; }
  //! True if this unique is lower than the other's unique id.
  constexpr bool operator<(const status_code_domain &o) const noexcept { return _id < o._id; }
  //! Returns the unique id used to identify identical category instances.
  constexpr unique_id_type id() const noexcept { return _id; }
  //! Name of this category.
  SYSTEM_ERROR2_CONSTEXPR20 virtual string_ref name() const noexcept = 0;
  //! Information about the payload of the code for this domain
  struct payload_info_t
  {
    size_t payload_size{0}; //!< The payload size in bytes
    size_t total_size{0}; //!< The total status code size in bytes (includes domain pointer and mixins state)
    size_t total_alignment{1}; //!< The total status code alignment in bytes
    payload_info_t() = default;
    constexpr payload_info_t(size_t _payload_size, size_t _total_size, size_t _total_alignment)
        : payload_size(_payload_size)
        , total_size(_total_size)
        , total_alignment(_total_alignment)
    {
    }
  };
  //! Information about this domain's payload
  SYSTEM_ERROR2_CONSTEXPR20 virtual payload_info_t payload_info() const noexcept = 0;
protected:
  //! True if code means failure.
  SYSTEM_ERROR2_CONSTEXPR20 virtual bool _do_failure(const status_code<void> &code) const noexcept = 0;
  //! True if code is (potentially non-transitively) equivalent to another code in another domain.
  SYSTEM_ERROR2_CONSTEXPR20 virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept = 0;
  //! Returns the generic code closest to this code, if any.
  SYSTEM_ERROR2_CONSTEXPR20 virtual generic_code _generic_code(const status_code<void> &code) const noexcept = 0;
  //! Return a reference to a string textually representing a code.
  SYSTEM_ERROR2_CONSTEXPR20 virtual string_ref _do_message(const status_code<void> &code) const noexcept = 0;
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  //! Throw a code as a C++ exception.
  SYSTEM_ERROR2_NORETURN SYSTEM_ERROR2_CONSTEXPR20 virtual void _do_throw_exception(const status_code<void> &code) const = 0;
#else
  // Keep a vtable slot for binary compatibility
  SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> & /*code*/) const { abort(); }
#endif
  // For a `status_code<erased<T>>` only, copy from `src` to `dst`. Default implementation uses `memcpy()`. You should return false here if your payload is not
  // trivially copyable or would not fit.
  virtual bool _do_erased_copy(status_code<void> &dst, const status_code<void> &src, payload_info_t dstinfo) const
  {
    // Note that dst may not have its domain set
    const auto srcinfo = payload_info();
    if(dstinfo.total_size < srcinfo.total_size)
    {
      return false;
    }
    const auto tocopy = (dstinfo.total_size > srcinfo.total_size) ? srcinfo.total_size : dstinfo.total_size;
    memcpy(&dst, &src, tocopy);
    return true;
  } // NOLINT
  // For a `status_code<erased<T>>` only, destroy the erased value type. Default implementation does nothing.
  SYSTEM_ERROR2_CONSTEXPR20 virtual void _do_erased_destroy(status_code<void> &code, payload_info_t info) const noexcept // NOLINT
  {
    (void) code;
    (void) info;
  }
};
SYSTEM_ERROR2_NAMESPACE_END
#endif
#if (__cplusplus >= 201700 || _HAS_CXX17) && !defined(SYSTEM_ERROR2_DISABLE_STD_IN_PLACE)
// 0.26
#include <utility> // for in_place
SYSTEM_ERROR2_NAMESPACE_BEGIN
using in_place_t = std::in_place_t;
using std::in_place;
SYSTEM_ERROR2_NAMESPACE_END
#else
SYSTEM_ERROR2_NAMESPACE_BEGIN
//! Aliases `std::in_place_t` if on C++ 17 or later, else defined locally.
struct in_place_t
{
  explicit in_place_t() = default;
};
//! Aliases `std::in_place` if on C++ 17 or later, else defined locally.
constexpr in_place_t in_place{};
SYSTEM_ERROR2_NAMESPACE_END
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
//! Namespace for user injected mixins
namespace mixins
{
  template <class Base, class T> struct mixin : public Base
  {
    using Base::Base;
  };
} // namespace mixins
namespace detail
{
  SYSTEM_ERROR2_TEMPLATE(class ErasedType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(traits::is_move_bitcopying<ErasedType>::value))
  struct erased
  {
    using value_type = ErasedType;
  };
} // namespace detail
/*! The tag type used to specialise erased editions of `status_code<D>`.
Available only if `ErasedType` satisfies `traits::is_move_bitcopying<ErasedType>::value`.
*/
template <class ErasedType> //
using status_code_erased_tag_type = detail::erased<ErasedType>;
/*! Specialise this template to quickly wrap a third party enumeration into a
custom status code domain.

Use like this:

```c++
SYSTEM_ERROR2_NAMESPACE_BEGIN
template <> struct quick_status_code_from_enum<AnotherCode> : quick_status_code_from_enum_defaults<AnotherCode>
{
  // Text name of the enum
  static constexpr const auto domain_name = "Another Code";
  // Unique UUID for the enum. PLEASE use https://www.random.org/cgi-bin/randbyte?nbytes=16&format=h
  static constexpr const auto domain_uuid = "{be201f65-3962-dd0e-1266-a72e63776a42}";
  // Map of each enum value to its text string, and list of semantically equivalent errc's
  static const std::initializer_list<mapping> &value_mappings()
  {
    static const std::initializer_list<mapping<AnotherCode>> v = {
    // Format is: { enum value, "string representation", { list of errc mappings ... } }
    {AnotherCode::success1, "Success 1", {errc::success}},        //
    {AnotherCode::goaway, "Go away", {errc::permission_denied}},  //
    {AnotherCode::success2, "Success 2", {errc::success}},        //
    {AnotherCode::error2, "Error 2", {}},                         //
    };
    return v;
  }
  // Completely optional definition of mixin for the status code synthesised from `Enum`. It can be omitted.
  template <class Base> struct mixin : Base
  {
    using Base::Base;
    constexpr int custom_method() const { return 42; }
  };
};
SYSTEM_ERROR2_NAMESPACE_END
```

Note that if the `errc` mapping contains `errc::success`, then
the enumeration value is considered to be a successful value.
Otherwise it is considered to be a failure value.

The first value in the `errc` mapping is the one chosen as the
`generic_code` conversion. Other values are used during equivalence
comparisons.
*/
template <class Enum> struct quick_status_code_from_enum;
namespace detail
{
  template <class T> struct is_status_code
  {
    static constexpr bool value = false;
  };
  template <class T> struct is_status_code<status_code<T>>
  {
    static constexpr bool value = true;
  };
  template <class T> struct is_erased_status_code
  {
    static constexpr bool value = false;
  };
  template <class T> struct is_erased_status_code<status_code<detail::erased<T>>>
  {
    static constexpr bool value = true;
  };
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 8
  // From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf
  namespace impl
  {
    template <typename... Ts> struct make_void
    {
      using type = void;
    };
    template <typename... Ts> using void_t = typename make_void<Ts...>::type;
    template <class...> struct types
    {
      using type = types;
    };
    template <template <class...> class T, class types, class = void> struct test_apply
    {
      using type = void;
    };
    template <template <class...> class T, class... Ts> struct test_apply<T, types<Ts...>, void_t<T<Ts...>>>
    {
      using type = T<Ts...>;
    };
  } // namespace impl
  template <template <class...> class T, class... Ts> using test_apply = impl::test_apply<T, impl::types<Ts...>>;
  template <class T, class... Args> using get_make_status_code_result = decltype(make_status_code(std::declval<T>(), std::declval<Args>()...));
  template <class... Args> using safe_get_make_status_code_result = test_apply<get_make_status_code_result, Args...>;
#else
  // ICE avoidance form for GCCs before 8. Note this form doesn't prevent recursive make_status_code ADL instantation,
  // so in certain corner cases this will break. On the other hand, more useful than an ICE.
  namespace impl
  {
    template <typename... Ts> struct make_void
    {
      using type = void;
    };
    template <typename... Ts> using void_t = typename make_void<Ts...>::type;
    template <class...> struct types
    {
      using type = types;
    };
    template <typename Types, typename = void> struct make_status_code_rettype
    {
      using type = void;
    };
    template <typename... Args> using get_make_status_code_result = decltype(make_status_code(std::declval<Args>()...));
    template <typename... Args> struct make_status_code_rettype<types<Args...>, void_t<get_make_status_code_result<Args...>>>
    {
      using type = get_make_status_code_result<Args...>;
    };
  } // namespace impl
  template <class... Args> struct safe_get_make_status_code_result
  {
    using type = typename impl::make_status_code_rettype<impl::types<Args...>>::type;
  };
#endif
} // namespace detail
//! Trait returning true if the type is a status code.
template <class T> struct is_status_code
{
  static constexpr bool value =
  detail::is_status_code<typename std::decay<T>::type>::value || detail::is_erased_status_code<typename std::decay<T>::type>::value;
};
/*! A type erased lightweight status code reflecting empty, success, or failure.
Differs from `status_code<erased<>>` by being always available irrespective of
the domain's value type, but cannot be copied, moved, nor destructed. Thus one
always passes this around by const lvalue reference.
*/
template <> class SYSTEM_ERROR2_TRIVIAL_ABI status_code<void>
{
  template <class T> friend class status_code;
public:
  //! The type of the domain.
  using domain_type = void;
  //! The type of the status code.
  using value_type = void;
  //! The type of a reference to a message string.
  using string_ref = typename status_code_domain::string_ref;
protected:
  const status_code_domain *_domain{nullptr};
protected:
  //! No default construction at type erased level
  status_code() = default;
  //! No public copying at type erased level
  status_code(const status_code &) = default;
  //! No public moving at type erased level
  status_code(status_code &&) = default;
  //! No public assignment at type erased level
  status_code &operator=(const status_code &) = default;
  //! No public assignment at type erased level
  status_code &operator=(status_code &&) = default;
  //! No public destruction at type erased level
  ~status_code() = default;
  //! Used to construct a non-empty type erased status code
  constexpr explicit status_code(const status_code_domain *v) noexcept
      : _domain(v)
  {
  }
  // Used to work around triggering a ubsan failure. Do NOT remove!
  constexpr const status_code_domain *_domain_ptr() const noexcept { return _domain; }
public:
  //! Return the status code domain.
  constexpr const status_code_domain &domain() const noexcept { return *_domain; }
  //! True if the status code is empty.
  SYSTEM_ERROR2_NODISCARD constexpr bool empty() const noexcept { return _domain == nullptr; }
  //! Return a reference to a string textually representing a code.
  SYSTEM_ERROR2_CONSTEXPR20 string_ref message() const noexcept
  {
    // Avoid MSVC's buggy ternary operator for expensive to destruct things
    if(_domain != nullptr)
    {
      return _domain->_do_message(*this);
    }
    return string_ref("(empty)");
  }
  //! True if code means success.
  SYSTEM_ERROR2_CONSTEXPR20 bool success() const noexcept { return (_domain != nullptr) ? !_domain->_do_failure(*this) : false; }
  //! True if code means failure.
  SYSTEM_ERROR2_CONSTEXPR20 bool failure() const noexcept { return (_domain != nullptr) ? _domain->_do_failure(*this) : false; }
  /*! True if code is strictly (and potentially non-transitively) semantically equivalent to another code in another domain.
  Note that usually non-semantic i.e. pure value comparison is used when the other status code has the same domain.
  As `equivalent()` will try mapping to generic code, this usually captures when two codes have the same semantic
  meaning in `equivalent()`.
  */
  template <class T> SYSTEM_ERROR2_CONSTEXPR14 bool strictly_equivalent(const status_code<T> &o) const noexcept
  {
    if(_domain && o._domain)
    {
      return _domain->_do_equivalent(*this, o);
    }
    // If we are both empty, we are equivalent
    if(!_domain && !o._domain)
    {
      return true; // NOLINT
    }
    // Otherwise not equivalent
    return false;
  }
  /*! True if code is equivalent, by any means, to another code in another domain (guaranteed transitive).
  Firstly `strictly_equivalent()` is run in both directions. If neither succeeds, each domain is asked
  for the equivalent generic code and those are compared.
  */
  template <class T> SYSTEM_ERROR2_CONSTEXPR14 inline bool equivalent(const status_code<T> &o) const noexcept;
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  //! Throw a code as a C++ exception.
  SYSTEM_ERROR2_NORETURN void throw_exception() const
  {
    _domain->_do_throw_exception(*this);
    abort(); // suppress buggy GCC warning
  }
#endif
};
namespace detail
{
  template <class DomainType> struct get_domain_value_type
  {
    using domain_type = DomainType;
    using value_type = typename domain_type::value_type;
  };
  template <class ErasedType> struct get_domain_value_type<erased<ErasedType>>
  {
    using domain_type = status_code_domain;
    using value_type = ErasedType;
  };
  template <class DomainType> class SYSTEM_ERROR2_TRIVIAL_ABI status_code_storage : public status_code<void>
  {
    static_assert(!std::is_void<DomainType>::value, "status_code_storage<void> should never occur!");
    using _base = status_code<void>;
  public:
    //! The type of the domain.
    using domain_type = typename get_domain_value_type<DomainType>::domain_type;
    //! The type of the status code.
    using value_type = typename get_domain_value_type<DomainType>::value_type;
    //! The type of a reference to a message string.
    using string_ref = typename domain_type::string_ref;
#ifndef NDEBUG
    static_assert(std::is_move_constructible<value_type>::value || std::is_copy_constructible<value_type>::value,
                  "DomainType::value_type is neither move nor copy constructible!");
    static_assert(!std::is_default_constructible<value_type>::value || std::is_nothrow_default_constructible<value_type>::value,
                  "DomainType::value_type is not nothrow default constructible!");
    static_assert(!std::is_move_constructible<value_type>::value || std::is_nothrow_move_constructible<value_type>::value,
                  "DomainType::value_type is not nothrow move constructible!");
    static_assert(std::is_nothrow_destructible<value_type>::value, "DomainType::value_type is not nothrow destructible!");
#endif
    // Replace the type erased implementations with type aware implementations for better codegen
    //! Return the status code domain.
    constexpr const domain_type &domain() const noexcept { return *static_cast<const domain_type *>(this->_domain); }
    //! Reset the code to empty.
    SYSTEM_ERROR2_CONSTEXPR14 void clear() noexcept
    {
      this->_value.~value_type();
      this->_domain = nullptr;
      new(std::addressof(this->_value)) value_type();
    }
#if __cplusplus >= 201400 || _MSC_VER >= 1910 /* VS2017 */
    //! Return a reference to the `value_type`.
    constexpr value_type &value() & noexcept { return this->_value; }
    //! Return a reference to the `value_type`.
    constexpr value_type &&value() && noexcept { return static_cast<value_type &&>(this->_value); }
#endif
    //! Return a reference to the `value_type`.
    constexpr const value_type &value() const & noexcept { return this->_value; }
    //! Return a reference to the `value_type`.
    constexpr const value_type &&value() const && noexcept { return static_cast<const value_type &&>(this->_value); }
  protected:
    status_code_storage() = default;
    status_code_storage(const status_code_storage &) = default;
    SYSTEM_ERROR2_CONSTEXPR14 status_code_storage(status_code_storage &&o) noexcept
        : _base(static_cast<status_code_storage &&>(o))
        , _value(static_cast<status_code_storage &&>(o)._value)
    {
      o._domain = nullptr;
    }
    status_code_storage &operator=(const status_code_storage &) = default;
    SYSTEM_ERROR2_CONSTEXPR14 status_code_storage &operator=(status_code_storage &&o) noexcept
    {
      this->~status_code_storage();
      new(this) status_code_storage(static_cast<status_code_storage &&>(o));
      return *this;
    }
    ~status_code_storage() = default;
    value_type _value{};
    struct _value_type_constructor
    {
    };
    template <class... Args>
    constexpr status_code_storage(_value_type_constructor /*unused*/, const status_code_domain *v, Args &&...args)
        : _base(v)
        , _value(static_cast<Args &&>(args)...)
    {
    }
  };
  template <class DomainType> struct has_stateful_mixin
  {
    static constexpr bool value = (sizeof(status_code_storage<DomainType>) != sizeof(mixins::mixin<status_code_storage<DomainType>, DomainType>));
  };
  template <class ToDomain, class FromDomain> struct domain_value_type_erasure_is_safe
  {
    using to_value_type = typename get_domain_value_type<ToDomain>::value_type;
    using from_value_type = typename get_domain_value_type<FromDomain>::value_type;
    static constexpr bool value = traits::is_move_bitcopying<to_value_type>::value //
                                  && traits::is_move_bitcopying<from_value_type>::value //
                                  && sizeof(status_code_storage<FromDomain>) <= sizeof(status_code_storage<ToDomain>) //
                                  && !has_stateful_mixin<FromDomain>::value;
  };
  template <class ToDomain> struct domain_value_type_erasure_is_safe<ToDomain, void>
  {
    static constexpr bool value = false;
  };
} // namespace detail
namespace traits
{
  //! Determines whether the mixin contained in `StatusCode` contains non-static member variables.
  template <class StatusCode> using has_stateful_mixin = detail::has_stateful_mixin<typename detail::remove_cvref<StatusCode>::type::value_type>;
  //! Determines whether the status code `From` can be type erased into the status code `To`.
  template <class To, class From>
  using is_type_erasable_to =
  detail::domain_value_type_erasure_is_safe<typename detail::remove_cvref<To>::type::domain_type, typename detail::remove_cvref<From>::type::domain_type>;
} // namespace traits
/*! A lightweight, typed, status code reflecting empty, success, or failure.
This is the main workhorse of the system_error2 library. Its characteristics reflect the value type
set by its domain type, so if that value type is move-only or trivial, so is this.

An ADL discovered helper function `make_status_code(T, Args...)` is looked up by one of the constructors.
If it is found, and it generates a status code compatible with this status code, implicit construction
is made available.

You may mix in custom member functions and member function overrides by injecting a specialisation of
`mixins::mixin<Base, YourDomainType>`. Your mixin must inherit from `Base`. Your mixin can carry state,
but if it does, it will no longer be possible to construct erased status codes from such unerased status
codes.
*/
template <class DomainType> class SYSTEM_ERROR2_TRIVIAL_ABI status_code : public mixins::mixin<detail::status_code_storage<DomainType>, DomainType>
{
  template <class T> friend class status_code;
  using _base = mixins::mixin<detail::status_code_storage<DomainType>, DomainType>;
public:
  //! The type of the domain.
  using domain_type = DomainType;
  //! The type of the status code.
  using value_type = typename domain_type::value_type;
  //! The type of a reference to a message string.
  using string_ref = typename domain_type::string_ref;
protected:
  using _base::_base;
public:
  //! Default construction to empty
  status_code() = default;
  //! Copy constructor
  status_code(const status_code &) = default;
  //! Move constructor
  status_code(status_code &&) = default; // NOLINT
  //! Copy assignment
  status_code &operator=(const status_code &) = default;
  //! Move assignment
  status_code &operator=(status_code &&) = default; // NOLINT
  ~status_code() = default;
  //! Return a copy of the code.
  SYSTEM_ERROR2_CONSTEXPR14 status_code clone() const { return *this; }
  /***** KEEP THESE IN SYNC WITH ERRORED_STATUS_CODE *****/
  //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`.
  SYSTEM_ERROR2_TEMPLATE(
  class T, class... Args, //
  class MakeStatusCodeResult =
  typename detail::safe_get_make_status_code_result<T, Args...>::type) // Safe ADL lookup of make_status_code(), returns void if not found
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(!std::is_same<typename std::decay<T>::type, status_code>::value // not copy/move of self
                                              && !std::is_same<typename std::decay<T>::type, in_place_t>::value // not in_place_t
                                              && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
                                              && std::is_constructible<status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
  constexpr status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT
      : status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
  {
  }
  //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type.
  SYSTEM_ERROR2_TEMPLATE(class Enum, //
                         class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type) // Enumeration has been activated
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(std::is_constructible<status_code, QuickStatusCodeType>::value)) // Its status code is compatible
  constexpr status_code(Enum &&v) noexcept(std::is_nothrow_constructible<status_code, QuickStatusCodeType>::value) // NOLINT
      : status_code(QuickStatusCodeType(static_cast<Enum &&>(v)))
  {
  }
  //! Explicit in-place construction. Disables if `domain_type::get()` is not a valid expression.
  template <class... Args>
  constexpr explicit status_code(in_place_t /*unused */, Args &&...args) noexcept(std::is_nothrow_constructible<value_type, Args &&...>::value)
      : _base(typename _base::_value_type_constructor{}, &domain_type::get(), static_cast<Args &&>(args)...)
  {
  }
  //! Explicit in-place construction from initialiser list. Disables if `domain_type::get()` is not a valid expression.
  template <class T, class... Args>
  constexpr explicit status_code(in_place_t /*unused */, std::initializer_list<T> il,
                                 Args &&...args) noexcept(std::is_nothrow_constructible<value_type, std::initializer_list<T>, Args &&...>::value)
      : _base(typename _base::_value_type_constructor{}, &domain_type::get(), il, static_cast<Args &&>(args)...)
  {
  }
  //! Explicit copy construction from a `value_type`. Disables if `domain_type::get()` is not a valid expression.
  constexpr explicit status_code(const value_type &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value)
      : _base(typename _base::_value_type_constructor{}, &domain_type::get(), v)
  {
  }
  //! Explicit move construction from a `value_type`. Disables if `domain_type::get()` is not a valid expression.
  constexpr explicit status_code(value_type &&v) noexcept(std::is_nothrow_move_constructible<value_type>::value)
      : _base(typename _base::_value_type_constructor{}, &domain_type::get(), static_cast<value_type &&>(v))
  {
  }
  /*! Explicit construction from an erased status code. Available only if
  `value_type` is trivially copyable or move bitcopying, and `sizeof(status_code) <= sizeof(status_code<erased<>>)`.
  Does not check if domains are equal.
  */
  SYSTEM_ERROR2_TEMPLATE(class ErasedType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<domain_type, detail::erased<ErasedType>>::value))
  constexpr explicit status_code(const status_code<detail::erased<ErasedType>> &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value)
      : status_code(detail::erasure_cast<value_type>(v.value()))
  {
#if __cplusplus >= 201400
    assert(v.domain() == this->domain());
#endif
  }
  //! Return a reference to a string textually representing a code.
  SYSTEM_ERROR2_CONSTEXPR20 string_ref message() const noexcept
  {
    // Avoid MSVC's buggy ternary operator for expensive to destruct things
    if(this->_domain != nullptr)
    {
      return string_ref(this->domain()._do_message(*this));
    }
    return string_ref("(empty)");
  }
};
namespace traits
{
  template <class DomainType> struct is_move_bitcopying<status_code<DomainType>>
  {
    static constexpr bool value = is_move_bitcopying<typename DomainType::value_type>::value;
  };
} // namespace traits
/*! Type erased, move-only status_code, unlike `status_code<void>` which cannot be moved nor destroyed. Available
only if `erased<>` is available, which is when the domain's type is trivially
copyable or is move relocatable, and if the size of the domain's typed error code is less than or equal to
this erased error code. Copy construction is disabled, but if you want a copy call `.clone()`.

An ADL discovered helper function `make_status_code(T, Args...)` is looked up by one of the constructors.
If it is found, and it generates a status code compatible with this status code, implicit construction
is made available.
*/
template <class ErasedType>
class SYSTEM_ERROR2_TRIVIAL_ABI status_code<detail::erased<ErasedType>>
    : public mixins::mixin<detail::status_code_storage<detail::erased<ErasedType>>, detail::erased<ErasedType>>
{
  template <class T> friend class status_code;
  using _base = mixins::mixin<detail::status_code_storage<detail::erased<ErasedType>>, detail::erased<ErasedType>>;
public:
  //! The type of the domain (void, as it is erased).
  using domain_type = void;
  //! The type of the erased status code.
  using value_type = ErasedType;
  //! The type of a reference to a message string.
  using string_ref = typename _base::string_ref;
public:
  //! Default construction to empty
  status_code() = default;
  //! Copy constructor
  status_code(const status_code &) = delete;
  //! Move constructor
  status_code(status_code &&) = default; // NOLINT
  //! Copy assignment
  status_code &operator=(const status_code &) = delete;
  //! Move assignment
  status_code &operator=(status_code &&) = default; // NOLINT
  SYSTEM_ERROR2_CONSTEXPR20 ~status_code()
  {
    if(nullptr != this->_domain)
    {
      status_code_domain::payload_info_t info{sizeof(value_type), sizeof(status_code), alignof(status_code)};
      this->_domain->_do_erased_destroy(*this, info);
    }
  }
  //! Return a copy of the erased code by asking the domain to perform the erased copy.
  SYSTEM_ERROR2_CONSTEXPR20 status_code clone() const
  {
    if(nullptr == this->_domain)
    {
      return {};
    }
    status_code x;
    if(!this->_domain->_do_erased_copy(x, *this, this->_domain->payload_info()))
    {
      abort(); // should not be possible
    }
    return x;
  }
  /***** KEEP THESE IN SYNC WITH ERRORED_STATUS_CODE *****/
  //! Implicit copy construction from any other status code if its value type is trivially copyable, it would fit into our storage, and it is not an erased
  //! status code.
  SYSTEM_ERROR2_TEMPLATE(class DomainType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<detail::erased<ErasedType>, DomainType>::value),
                          SYSTEM_ERROR2_TPRED(!detail::is_erased_status_code<status_code<typename std::decay<DomainType>::type>>::value))
  constexpr status_code(const status_code<DomainType> &v) noexcept // NOLINT
      : _base(typename _base::_value_type_constructor{}, v._domain_ptr(), detail::erasure_cast<value_type>(v.value()))
  {
  }
  //! Implicit move construction from any other status code if its value type is trivially copyable or move bitcopying and it would fit into our storage
  SYSTEM_ERROR2_TEMPLATE(class DomainType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<detail::erased<ErasedType>, DomainType>::value))
  SYSTEM_ERROR2_CONSTEXPR14 status_code(status_code<DomainType> &&v) noexcept // NOLINT
      : _base(typename _base::_value_type_constructor{}, v._domain_ptr(), detail::erasure_cast<value_type>(v.value()))
  {
    alignas(alignof(typename DomainType::value_type)) char buffer[sizeof(typename DomainType::value_type)];
    new(buffer) typename DomainType::value_type(static_cast<status_code<DomainType> &&>(v).value());
    // deliberately do not destruct value moved into buffer
    (void) buffer;
    v._domain = nullptr;
  }
  //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`.
  SYSTEM_ERROR2_TEMPLATE(
  class T, class... Args, //
  class MakeStatusCodeResult =
  typename detail::safe_get_make_status_code_result<T, Args...>::type) // Safe ADL lookup of make_status_code(), returns void if not found
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(!std::is_same<typename std::decay<T>::type, status_code>::value // not copy/move of self
                                              && !std::is_same<typename std::decay<T>::type, value_type>::value // not copy/move of value type
                                              && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
                                              && std::is_constructible<status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
  constexpr status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT
      : status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
  {
  }
  //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type.
  SYSTEM_ERROR2_TEMPLATE(class Enum, //
                         class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type) // Enumeration has been activated
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(std::is_constructible<status_code, QuickStatusCodeType>::value)) // Its status code is compatible
  constexpr status_code(Enum &&v) noexcept(std::is_nothrow_constructible<status_code, QuickStatusCodeType>::value) // NOLINT
      : status_code(QuickStatusCodeType(static_cast<Enum &&>(v)))
  {
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  //! Explicit copy construction from an unknown status code. Note that this will throw an exception if its value type is not trivially copyable or would not
  //! fit into our storage or the source domain's `_do_erased_copy()` refused the copy.
  explicit SYSTEM_ERROR2_CONSTEXPR14 status_code(const status_code<void> &v) // NOLINT
      : _base(typename _base::_value_type_constructor{}, v._domain_ptr(), value_type{})
  {
    status_code_domain::payload_info_t info{sizeof(value_type), sizeof(status_code), alignof(status_code)};
    if(this->_domain->_do_erased_copy(*this, v, info))
    {
      return;
    }
    struct _ final : public std::exception
    {
      virtual const char *what() const noexcept override { return "status_code: source domain's erased copy function returned failure or refusal"; }
    };
    throw _{};
  }
#endif
  //! Tagged copy construction from an unknown status code. Note that this will be empty if its value type is not trivially copyable or would not fit into our
  //! storage or the source domain's `_do_erased_copy()` refused the copy.
  SYSTEM_ERROR2_CONSTEXPR20 status_code(std::nothrow_t, const status_code<void> &v) noexcept // NOLINT
      : _base(typename _base::_value_type_constructor{}, v._domain_ptr(), value_type{})
  {
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
    try
#endif
    {
      status_code_domain::payload_info_t info{sizeof(value_type), sizeof(status_code), alignof(status_code)};
      if(this->_domain->_do_erased_copy(*this, v, info))
      {
        return;
      }
      this->_domain = nullptr;
    }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
    catch(...)
    {
      this->_domain = nullptr;
    }
#endif
  }
  /**** By rights ought to be removed in any formal standard ****/
  //! Reset the code to empty.
  SYSTEM_ERROR2_CONSTEXPR14 void clear() noexcept { *this = status_code(); }
  //! Return the erased `value_type` by value.
  constexpr value_type value() const noexcept { return this->_value; }
};
/*! An erased type specialisation of `status_code<D>`.
Available only if `ErasedType` satisfies `traits::is_move_bitcopying<ErasedType>::value`.
*/
template <class ErasedType> using erased_status_code = status_code<detail::erased<ErasedType>>;
namespace traits
{
  template <class ErasedType> struct is_move_bitcopying<status_code<detail::erased<ErasedType>>>
  {
    static constexpr bool value = true;
  };
} // namespace traits
SYSTEM_ERROR2_NAMESPACE_END
#endif
#include <exception> // for std::exception
SYSTEM_ERROR2_NAMESPACE_BEGIN
/*! Exception type representing a thrown status_code
 */
template <class DomainType> class status_error;
/*! The erased type edition of status_error.
 */
template <> class status_error<void> : public std::exception
{
protected:
  //! Constructs an instance. Not publicly available.
  status_error() = default;
  //! Copy constructor. Not publicly available
  status_error(const status_error &) = default;
  //! Move constructor. Not publicly available
  status_error(status_error &&) = default;
  //! Copy assignment. Not publicly available
  status_error &operator=(const status_error &) = default;
  //! Move assignment. Not publicly available
  status_error &operator=(status_error &&) = default;
  //! Destructor. Not publicly available.
  ~status_error() override = default;
  virtual const status_code<void> &_do_code() const noexcept = 0;
public:
  //! The type of the status domain
  using domain_type = void;
  //! The type of the status code
  using status_code_type = status_code<void>;
public:
  //! The erased status code which generated this exception instance.
  const status_code<void> &code() const noexcept { return _do_code(); }
};
/*! Exception type representing a thrown status_code
 */
template <class DomainType> class status_error : public status_error<void>
{
  status_code<DomainType> _code;
  typename DomainType::string_ref _msgref;
  virtual const status_code<void> &_do_code() const noexcept override final { return _code; }
public:
  //! The type of the status domain
  using domain_type = DomainType;
  //! The type of the status code
  using status_code_type = status_code<DomainType>;
  //! Constructs an instance
  explicit status_error(status_code<DomainType> code)
      : _code(static_cast<status_code<DomainType> &&>(code))
      , _msgref(_code.message())
  {
  }
  //! Return an explanatory string
  virtual const char *what() const noexcept override { return _msgref.c_str(); } // NOLINT
  //! Returns a reference to the code
  const status_code_type &code() const & { return _code; }
  //! Returns a reference to the code
  status_code_type &code() & { return _code; }
  //! Returns a reference to the code
  const status_code_type &&code() const && { return _code; }
  //! Returns a reference to the code
  status_code_type &&code() && { return _code; }
};
/*! Exception type representing a thrown erased status_code
 */
template <class ErasedType> class status_error<detail::erased<ErasedType>> : public status_error<void>
{
  status_code<detail::erased<ErasedType>> _code;
  typename status_code_domain::string_ref _msgref;
  virtual const status_code<detail::erased<ErasedType>> &_do_code() const noexcept override final { return _code; }
public:
  //! The type of the status domain
  using domain_type = void;
  //! The type of the status code
  using status_code_type = status_code<detail::erased<ErasedType>>;
  //! Constructs an instance
  explicit status_error(status_code<detail::erased<ErasedType>> code)
      : _code(static_cast<status_code<detail::erased<ErasedType>> &&>(code))
      , _msgref(_code.message())
  {
  }
  //! Return an explanatory string
  virtual const char *what() const noexcept override { return _msgref.c_str(); } // NOLINT
  //! Returns a reference to the code
  const status_code_type &code() const & { return _code; }
  //! Returns a reference to the code
  status_code_type &code() & { return _code; }
  //! Returns a reference to the code
  const status_code_type &&code() const && { return _code; }
  //! Returns a reference to the code
  status_code_type &&code() && { return _code; }
};
SYSTEM_ERROR2_NAMESPACE_END
#endif
#include <cerrno> // for error constants
SYSTEM_ERROR2_NAMESPACE_BEGIN
//! The generic error coding (POSIX)
enum class errc : int
{
  success = 0,
  unknown = -1,
  address_family_not_supported = EAFNOSUPPORT,
  address_in_use = EADDRINUSE,
  address_not_available = EADDRNOTAVAIL,
  already_connected = EISCONN,
  argument_list_too_long = E2BIG,
  argument_out_of_domain = EDOM,
  bad_address = EFAULT,
  bad_file_descriptor = EBADF,
  bad_message = EBADMSG,
  broken_pipe = EPIPE,
  connection_aborted = ECONNABORTED,
  connection_already_in_progress = EALREADY,
  connection_refused = ECONNREFUSED,
  connection_reset = ECONNRESET,
  cross_device_link = EXDEV,
  destination_address_required = EDESTADDRREQ,
  device_or_resource_busy = EBUSY,
  directory_not_empty = ENOTEMPTY,
  executable_format_error = ENOEXEC,
  file_exists = EEXIST,
  file_too_large = EFBIG,
  filename_too_long = ENAMETOOLONG,
  function_not_supported = ENOSYS,
  host_unreachable = EHOSTUNREACH,
  identifier_removed = EIDRM,
  illegal_byte_sequence = EILSEQ,
  inappropriate_io_control_operation = ENOTTY,
  interrupted = EINTR,
  invalid_argument = EINVAL,
  invalid_seek = ESPIPE,
  io_error = EIO,
  is_a_directory = EISDIR,
  message_size = EMSGSIZE,
  network_down = ENETDOWN,
  network_reset = ENETRESET,
  network_unreachable = ENETUNREACH,
  no_buffer_space = ENOBUFS,
  no_child_process = ECHILD,
  no_link = ENOLINK,
  no_lock_available = ENOLCK,
  no_message = ENOMSG,
  no_protocol_option = ENOPROTOOPT,
  no_space_on_device = ENOSPC,
  no_stream_resources = ENOSR,
  no_such_device_or_address = ENXIO,
  no_such_device = ENODEV,
  no_such_file_or_directory = ENOENT,
  no_such_process = ESRCH,
  not_a_directory = ENOTDIR,
  not_a_socket = ENOTSOCK,
  not_a_stream = ENOSTR,
  not_connected = ENOTCONN,
  not_enough_memory = ENOMEM,
  not_supported = ENOTSUP,
  operation_canceled = ECANCELED,
  operation_in_progress = EINPROGRESS,
  operation_not_permitted = EPERM,
  operation_not_supported = EOPNOTSUPP,
  operation_would_block = EWOULDBLOCK,
  owner_dead = EOWNERDEAD,
  permission_denied = EACCES,
  protocol_error = EPROTO,
  protocol_not_supported = EPROTONOSUPPORT,
  read_only_file_system = EROFS,
  resource_deadlock_would_occur = EDEADLK,
  resource_unavailable_try_again = EAGAIN,
  result_out_of_range = ERANGE,
  state_not_recoverable = ENOTRECOVERABLE,
  stream_timeout = ETIME,
  text_file_busy = ETXTBSY,
  timed_out = ETIMEDOUT,
  too_many_files_open_in_system = ENFILE,
  too_many_files_open = EMFILE,
  too_many_links = EMLINK,
  too_many_symbolic_link_levels = ELOOP,
  value_too_large = EOVERFLOW,
  wrong_protocol_type = EPROTOTYPE
};
namespace detail
{
  SYSTEM_ERROR2_CONSTEXPR14 inline const char *generic_code_message(errc code) noexcept
  {
    switch(code)
    {
    case errc::success:
      return "Success";
    case errc::address_family_not_supported:
      return "Address family not supported by protocol";
    case errc::address_in_use:
      return "Address already in use";
    case errc::address_not_available:
      return "Cannot assign requested address";
    case errc::already_connected:
      return "Transport endpoint is already connected";
    case errc::argument_list_too_long:
      return "Argument list too long";
    case errc::argument_out_of_domain:
      return "Numerical argument out of domain";
    case errc::bad_address:
      return "Bad address";
    case errc::bad_file_descriptor:
      return "Bad file descriptor";
    case errc::bad_message:
      return "Bad message";
    case errc::broken_pipe:
      return "Broken pipe";
    case errc::connection_aborted:
      return "Software caused connection abort";
    case errc::connection_already_in_progress:
      return "Operation already in progress";
    case errc::connection_refused:
      return "Connection refused";
    case errc::connection_reset:
      return "Connection reset by peer";
    case errc::cross_device_link:
      return "Invalid cross-device link";
    case errc::destination_address_required:
      return "Destination address required";
    case errc::device_or_resource_busy:
      return "Device or resource busy";
    case errc::directory_not_empty:
      return "Directory not empty";
    case errc::executable_format_error:
      return "Exec format error";
    case errc::file_exists:
      return "File exists";
    case errc::file_too_large:
      return "File too large";
    case errc::filename_too_long:
      return "File name too long";
    case errc::function_not_supported:
      return "Function not implemented";
    case errc::host_unreachable:
      return "No route to host";
    case errc::identifier_removed:
      return "Identifier removed";
    case errc::illegal_byte_sequence:
      return "Invalid or incomplete multibyte or wide character";
    case errc::inappropriate_io_control_operation:
      return "Inappropriate ioctl for device";
    case errc::interrupted:
      return "Interrupted system call";
    case errc::invalid_argument:
      return "Invalid argument";
    case errc::invalid_seek:
      return "Illegal seek";
    case errc::io_error:
      return "Input/output error";
    case errc::is_a_directory:
      return "Is a directory";
    case errc::message_size:
      return "Message too long";
    case errc::network_down:
      return "Network is down";
    case errc::network_reset:
      return "Network dropped connection on reset";
    case errc::network_unreachable:
      return "Network is unreachable";
    case errc::no_buffer_space:
      return "No buffer space available";
    case errc::no_child_process:
      return "No child processes";
    case errc::no_link:
      return "Link has been severed";
    case errc::no_lock_available:
      return "No locks available";
    case errc::no_message:
      return "No message of desired type";
    case errc::no_protocol_option:
      return "Protocol not available";
    case errc::no_space_on_device:
      return "No space left on device";
    case errc::no_stream_resources:
      return "Out of streams resources";
    case errc::no_such_device_or_address:
      return "No such device or address";
    case errc::no_such_device:
      return "No such device";
    case errc::no_such_file_or_directory:
      return "No such file or directory";
    case errc::no_such_process:
      return "No such process";
    case errc::not_a_directory:
      return "Not a directory";
    case errc::not_a_socket:
      return "Socket operation on non-socket";
    case errc::not_a_stream:
      return "Device not a stream";
    case errc::not_connected:
      return "Transport endpoint is not connected";
    case errc::not_enough_memory:
      return "Cannot allocate memory";
#if ENOTSUP != EOPNOTSUPP
    case errc::not_supported:
      return "Operation not supported";
#endif
    case errc::operation_canceled:
      return "Operation canceled";
    case errc::operation_in_progress:
      return "Operation now in progress";
    case errc::operation_not_permitted:
      return "Operation not permitted";
    case errc::operation_not_supported:
      return "Operation not supported";
#if EAGAIN != EWOULDBLOCK
    case errc::operation_would_block:
      return "Resource temporarily unavailable";
#endif
    case errc::owner_dead:
      return "Owner died";
    case errc::permission_denied:
      return "Permission denied";
    case errc::protocol_error:
      return "Protocol error";
    case errc::protocol_not_supported:
      return "Protocol not supported";
    case errc::read_only_file_system:
      return "Read-only file system";
    case errc::resource_deadlock_would_occur:
      return "Resource deadlock avoided";
    case errc::resource_unavailable_try_again:
      return "Resource temporarily unavailable";
    case errc::result_out_of_range:
      return "Numerical result out of range";
    case errc::state_not_recoverable:
      return "State not recoverable";
    case errc::stream_timeout:
      return "Timer expired";
    case errc::text_file_busy:
      return "Text file busy";
    case errc::timed_out:
      return "Connection timed out";
    case errc::too_many_files_open_in_system:
      return "Too many open files in system";
    case errc::too_many_files_open:
      return "Too many open files";
    case errc::too_many_links:
      return "Too many links";
    case errc::too_many_symbolic_link_levels:
      return "Too many levels of symbolic links";
    case errc::value_too_large:
      return "Value too large for defined data type";
    case errc::wrong_protocol_type:
      return "Protocol wrong type for socket";
    default:
      return "unknown";
    }
  }
} // namespace detail
/*! The implementation of the domain for generic status codes, those mapped by `errc` (POSIX).
 */
class _generic_code_domain : public status_code_domain
{
  template <class> friend class status_code;
  template <class StatusCode, class Allocator> friend class detail::indirecting_domain;
  using _base = status_code_domain;
public:
  //! The value type of the generic code, which is an `errc` as per POSIX.
  using value_type = errc;
  using string_ref = _base::string_ref;
public:
  //! Default constructor
  constexpr explicit _generic_code_domain(typename _base::unique_id_type id = 0x746d6354f4f733e9) noexcept
      : _base(id)
  {
  }
  _generic_code_domain(const _generic_code_domain &) = default;
  _generic_code_domain(_generic_code_domain &&) = default;
  _generic_code_domain &operator=(const _generic_code_domain &) = default;
  _generic_code_domain &operator=(_generic_code_domain &&) = default;
  ~_generic_code_domain() = default;
  //! Constexpr singleton getter. Returns the constexpr generic_code_domain variable.
  static inline constexpr const _generic_code_domain &get();
  virtual _base::string_ref name() const noexcept override { return string_ref("generic domain"); } // NOLINT
  virtual payload_info_t payload_info() const noexcept override
  {
    return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
            (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
  }
protected:
  virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    return static_cast<const generic_code &>(code).value() != errc::success; // NOLINT
  }
  virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT
  {
    assert(code1.domain() == *this); // NOLINT
    const auto &c1 = static_cast<const generic_code &>(code1); // NOLINT
    if(code2.domain() == *this)
    {
      const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT
      return c1.value() == c2.value();
    }
    return false;
  }
  virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    return static_cast<const generic_code &>(code); // NOLINT
  }
  virtual _base::string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    const auto &c = static_cast<const generic_code &>(code); // NOLINT
    return string_ref(detail::generic_code_message(c.value()));
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    const auto &c = static_cast<const generic_code &>(code); // NOLINT
    throw status_error<_generic_code_domain>(c);
  }
#endif
};
//! A specialisation of `status_error` for the generic code domain.
using generic_error = status_error<_generic_code_domain>;
//! A constexpr source variable for the generic code domain, which is that of `errc` (POSIX). Returned by `_generic_code_domain::get()`.
constexpr _generic_code_domain generic_code_domain;
inline constexpr const _generic_code_domain &_generic_code_domain::get()
{
  return generic_code_domain;
}
// Enable implicit construction of generic_code from errc
SYSTEM_ERROR2_CONSTEXPR14 inline generic_code make_status_code(errc c) noexcept
{
  return generic_code(in_place, c);
}
/*************************************************************************************************************/
template <class T> inline SYSTEM_ERROR2_CONSTEXPR14 bool status_code<void>::equivalent(const status_code<T> &o) const noexcept
{
  if(_domain && o._domain)
  {
    if(_domain->_do_equivalent(*this, o))
    {
      return true;
    }
    if(o._domain->_do_equivalent(o, *this))
    {
      return true;
    }
    generic_code c1 = o._domain->_generic_code(o);
    if(c1.value() != errc::unknown && _domain->_do_equivalent(*this, c1))
    {
      return true;
    }
    generic_code c2 = _domain->_generic_code(*this);
    if(c2.value() != errc::unknown && o._domain->_do_equivalent(o, c2))
    {
      return true;
    }
  }
  // If we are both empty, we are equivalent, otherwise not equivalent
  return (!_domain && !o._domain);
}
//! True if the status code's are semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2>
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept
{
  return a.equivalent(b);
}
//! True if the status code's are not semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2>
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept
{
  return !a.equivalent(b);
}
//! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const T &b)
{
  return a.equivalent(make_status_code(b));
}
//! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const T &a, const status_code<DomainType1> &b)
{
  return b.equivalent(make_status_code(a));
}
//! True if the status code's are not semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const T &b)
{
  return !a.equivalent(make_status_code(b));
}
//! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const T &a, const status_code<DomainType1> &b)
{
  return !b.equivalent(make_status_code(a));
}
//! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`.
template <class DomainType1, class T, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const T &b)
{
  return a.equivalent(QuickStatusCodeType(b));
}
//! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`.
template <class T, class DomainType1, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const T &a, const status_code<DomainType1> &b)
{
  return b.equivalent(QuickStatusCodeType(a));
}
//! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`.
template <class DomainType1, class T, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const T &b)
{
  return !a.equivalent(QuickStatusCodeType(b));
}
//! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`.
template <class T, class DomainType1, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const T &a, const status_code<DomainType1> &b)
{
  return !b.equivalent(QuickStatusCodeType(a));
}
SYSTEM_ERROR2_NAMESPACE_END
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
template <class Enum> class _quick_status_code_from_enum_domain;
//! A status code wrapping `Enum` generated from `quick_status_code_from_enum`.
template <class Enum> using quick_status_code_from_enum_code = status_code<_quick_status_code_from_enum_domain<Enum>>;
//! Defaults for an implementation of `quick_status_code_from_enum<Enum>`
template <class Enum> struct quick_status_code_from_enum_defaults
{
  //! The type of the resulting code
  using code_type = quick_status_code_from_enum_code<Enum>;
  //! Used within `quick_status_code_from_enum` to define a mapping of enumeration value with its status code
  struct mapping
  {
    //! The enumeration type
    using enumeration_type = Enum;
    //! The value being mapped
    const Enum value;
    //! A string representation for this enumeration value
    const char *message;
    //! A list of `errc` equivalents for this enumeration value
    const std::initializer_list<errc> code_mappings;
  };
  //! Used within `quick_status_code_from_enum` to define mixins for the status code wrapping `Enum`
  template <class Base> struct mixin : Base
  {
    using Base::Base;
  };
};
/*! The implementation of the domain for status codes wrapping `Enum` generated from `quick_status_code_from_enum`.
 */
template <class Enum> class _quick_status_code_from_enum_domain : public status_code_domain
{
  template <class DomainType> friend class status_code;
  template <class StatusCode, class Allocator> friend class detail::indirecting_domain;
  using _base = status_code_domain;
  using _src = quick_status_code_from_enum<Enum>;
public:
  //! The value type of the quick status code from enum
  using value_type = Enum;
  using _base::string_ref;
  constexpr _quick_status_code_from_enum_domain()
      : status_code_domain(_src::domain_uuid, _uuid_size<detail::cstrlen(_src::domain_uuid)>())
  {
  }
  _quick_status_code_from_enum_domain(const _quick_status_code_from_enum_domain &) = default;
  _quick_status_code_from_enum_domain(_quick_status_code_from_enum_domain &&) = default;
  _quick_status_code_from_enum_domain &operator=(const _quick_status_code_from_enum_domain &) = default;
  _quick_status_code_from_enum_domain &operator=(_quick_status_code_from_enum_domain &&) = default;
  ~_quick_status_code_from_enum_domain() = default;
#if __cplusplus < 201402L && !defined(_MSC_VER)
  static inline const _quick_status_code_from_enum_domain &get()
  {
    static _quick_status_code_from_enum_domain v;
    return v;
  }
#else
  static inline constexpr const _quick_status_code_from_enum_domain &get();
#endif
  virtual string_ref name() const noexcept override { return string_ref(_src::domain_name); }
  virtual payload_info_t payload_info() const noexcept override
  {
    return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
            (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
  }
protected:
  // Not sure if a hash table is worth it here, most enumerations won't be long enough to be worth it
  // Also, until C++ 20's consteval, the hash table would get emitted into the binary, bloating it
  static SYSTEM_ERROR2_CONSTEXPR14 const typename _src::mapping *_find_mapping(value_type v) noexcept
  {
    for(const auto &i : _src::value_mappings())
    {
      if(i.value == v)
      {
        return &i;
      }
    }
    return nullptr;
  }
  virtual bool _do_failure(const status_code<void> &code) const noexcept override
  {
    assert(code.domain() == *this); // NOLINT
    // If `errc::success` is in the generic code mapping, it is not a failure
    const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value());
    assert(mapping != nullptr);
    if(mapping != nullptr)
    {
      for(errc ec : mapping->code_mappings)
      {
        if(ec == errc::success)
        {
          return false;
        }
      }
    }
    return true;
  }
  virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override
  {
    assert(code1.domain() == *this); // NOLINT
    const auto &c1 = static_cast<const quick_status_code_from_enum_code<value_type> &>(code1); // NOLINT
    if(code2.domain() == *this)
    {
      const auto &c2 = static_cast<const quick_status_code_from_enum_code<value_type> &>(code2); // NOLINT
      return c1.value() == c2.value();
    }
    if(code2.domain() == generic_code_domain)
    {
      const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT
      const auto *mapping = _find_mapping(c1.value());
      assert(mapping != nullptr);
      if(mapping != nullptr)
      {
        for(errc ec : mapping->code_mappings)
        {
          if(ec == c2.value())
          {
            return true;
          }
        }
      }
    }
    return false;
  }
  virtual generic_code _generic_code(const status_code<void> &code) const noexcept override
  {
    assert(code.domain() == *this); // NOLINT
    const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value());
    assert(mapping != nullptr);
    if(mapping != nullptr)
    {
      if(mapping->code_mappings.size() > 0)
      {
        return *mapping->code_mappings.begin();
      }
    }
    return errc::unknown;
  }
  virtual string_ref _do_message(const status_code<void> &code) const noexcept override
  {
    assert(code.domain() == *this); // NOLINT
    const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value());
    assert(mapping != nullptr);
    if(mapping != nullptr)
    {
      return string_ref(mapping->message);
    }
    return string_ref("unknown");
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override
  {
    assert(code.domain() == *this); // NOLINT
    const auto &c = static_cast<const quick_status_code_from_enum_code<value_type> &>(code); // NOLINT
    throw status_error<_quick_status_code_from_enum_domain>(c);
  }
#endif
};
#if __cplusplus >= 201402L || defined(_MSC_VER)
template <class Enum> constexpr _quick_status_code_from_enum_domain<Enum> quick_status_code_from_enum_domain = {};
template <class Enum> inline constexpr const _quick_status_code_from_enum_domain<Enum> &_quick_status_code_from_enum_domain<Enum>::get()
{
  return quick_status_code_from_enum_domain<Enum>;
}
#endif
namespace mixins
{
  template <class Base, class Enum>
  struct mixin<Base, _quick_status_code_from_enum_domain<Enum>> : public quick_status_code_from_enum<Enum>::template mixin<Base>
  {
    using quick_status_code_from_enum<Enum>::template mixin<Base>::mixin;
  };
} // namespace mixins
SYSTEM_ERROR2_NAMESPACE_END
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
/*! A `status_code` which is always a failure. The closest equivalent to
`std::error_code`, except it cannot be modified, and is templated.

Differences from `status_code`:

- Never successful (this contract is checked on construction, if fails then it
terminates the process).
- Is immutable.
*/
template <class DomainType> class errored_status_code : public status_code<DomainType>
{
  using _base = status_code<DomainType>;
  using _base::clear;
  using _base::success;
  void _check()
  {
    if(_base::success())
    {
      std::terminate();
    }
  }
public:
  //! The type of the domain.
  using typename _base::domain_type;
  //! The type of the error code.
  using typename _base::value_type;
  //! The type of a reference to a message string.
  using typename _base::string_ref;
  //! Default constructor.
  errored_status_code() = default;
  //! Copy constructor.
  errored_status_code(const errored_status_code &) = default;
  //! Move constructor.
  errored_status_code(errored_status_code &&) = default; // NOLINT
  //! Copy assignment.
  errored_status_code &operator=(const errored_status_code &) = default;
  //! Move assignment.
  errored_status_code &operator=(errored_status_code &&) = default; // NOLINT
  ~errored_status_code() = default;
  //! Explicitly construct from any similarly erased status code
  explicit errored_status_code(const _base &o) noexcept(std::is_nothrow_copy_constructible<_base>::value)
      : _base(o)
  {
    _check();
  }
  //! Explicitly construct from any similarly erased status code
  explicit errored_status_code(_base &&o) noexcept(std::is_nothrow_move_constructible<_base>::value)
      : _base(static_cast<_base &&>(o))
  {
    _check();
  }
  /***** KEEP THESE IN SYNC WITH STATUS_CODE *****/
  //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`.
  SYSTEM_ERROR2_TEMPLATE(
  class T, class... Args, //
  class MakeStatusCodeResult =
  typename detail::safe_get_make_status_code_result<T, Args...>::type) // Safe ADL lookup of make_status_code(), returns void if not found
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(!std::is_same<typename std::decay<T>::type, errored_status_code>::value // not copy/move of self
                                              && !std::is_same<typename std::decay<T>::type, in_place_t>::value // not in_place_t
                                              && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
                                              && std::is_constructible<errored_status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
  errored_status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT
      : errored_status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
  {
    _check();
  }
  //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type.
  SYSTEM_ERROR2_TEMPLATE(class Enum, //
                         class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type) // Enumeration has been activated
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(std::is_constructible<errored_status_code, QuickStatusCodeType>::value)) // Its status code is compatible
  errored_status_code(Enum &&v) noexcept(std::is_nothrow_constructible<errored_status_code, QuickStatusCodeType>::value) // NOLINT
      : errored_status_code(QuickStatusCodeType(static_cast<Enum &&>(v)))
  {
    _check();
  }
  //! Explicit in-place construction.
  template <class... Args>
  explicit errored_status_code(in_place_t _, Args &&...args) noexcept(std::is_nothrow_constructible<value_type, Args &&...>::value)
      : _base(_, static_cast<Args &&>(args)...)
  {
    _check();
  }
  //! Explicit in-place construction from initialiser list.
  template <class T, class... Args>
  explicit errored_status_code(in_place_t _, std::initializer_list<T> il,
                               Args &&...args) noexcept(std::is_nothrow_constructible<value_type, std::initializer_list<T>, Args &&...>::value)
      : _base(_, il, static_cast<Args &&>(args)...)
  {
    _check();
  }
  //! Explicit copy construction from a `value_type`.
  explicit errored_status_code(const value_type &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value)
      : _base(v)
  {
    _check();
  }
  //! Explicit move construction from a `value_type`.
  explicit errored_status_code(value_type &&v) noexcept(std::is_nothrow_move_constructible<value_type>::value)
      : _base(static_cast<value_type &&>(v))
  {
    _check();
  }
  /*! Explicit construction from an erased status code. Available only if
  `value_type` is trivially copyable or move bitcopying, and `sizeof(status_code) <= sizeof(status_code<erased<>>)`.
  Does not check if domains are equal.
  */
  SYSTEM_ERROR2_TEMPLATE(class ErasedType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<domain_type, detail::erased<ErasedType>>::value))
  explicit errored_status_code(const status_code<detail::erased<ErasedType>> &v) noexcept(std::is_nothrow_copy_constructible<value_type>::value)
      : errored_status_code(detail::erasure_cast<value_type>(v.value())) // NOLINT
  {
    assert(v.domain() == this->domain()); // NOLINT
    _check();
  }
  //! Always false (including at compile time), as errored status codes are never successful.
  constexpr bool success() const noexcept { return false; }
  //! Return a const reference to the `value_type`.
  constexpr const value_type &value() const &noexcept { return this->_value; }
};
namespace traits
{
  template <class DomainType> struct is_move_bitcopying<errored_status_code<DomainType>>
  {
    static constexpr bool value = is_move_bitcopying<typename DomainType::value_type>::value;
  };
} // namespace traits
template <class ErasedType> class errored_status_code<detail::erased<ErasedType>> : public status_code<detail::erased<ErasedType>>
{
  using _base = status_code<detail::erased<ErasedType>>;
  using _base::success;
  void _check()
  {
    if(_base::success())
    {
      std::terminate();
    }
  }
public:
  using domain_type = typename _base::domain_type;
  using value_type = typename _base::value_type;
  using string_ref = typename _base::string_ref;
  //! Default construction to empty
  errored_status_code() = default;
  //! Copy constructor
  errored_status_code(const errored_status_code &) = default;
  //! Move constructor
  errored_status_code(errored_status_code &&) = default; // NOLINT
                                                          //! Copy assignment
  errored_status_code &operator=(const errored_status_code &) = default;
  //! Move assignment
  errored_status_code &operator=(errored_status_code &&) = default; // NOLINT
  ~errored_status_code() = default;
  //! Explicitly construct from any similarly erased status code
  explicit errored_status_code(const _base &o) noexcept(std::is_nothrow_copy_constructible<_base>::value)
      : _base(o)
  {
    _check();
  }
  //! Explicitly construct from any similarly erased status code
  explicit errored_status_code(_base &&o) noexcept(std::is_nothrow_move_constructible<_base>::value)
      : _base(static_cast<_base &&>(o))
  {
    _check();
  }
  /***** KEEP THESE IN SYNC WITH STATUS_CODE *****/
  //! Implicit copy construction from any other status code if its value type is trivially copyable, it would fit into our storage, and it is not an erased
  //! status code.
  SYSTEM_ERROR2_TEMPLATE(class DomainType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<detail::erased<ErasedType>, DomainType>::value),
                          SYSTEM_ERROR2_TPRED(!detail::is_erased_status_code<status_code<typename std::decay<DomainType>::type>>::value))
  errored_status_code(const status_code<DomainType> &v) noexcept
      : _base(v) // NOLINT
  {
    _check();
  }
  //! Implicit copy construction from any other status code if its value type is trivially copyable and it would fit into our storage, and it is not an erased
  //! status code.
  SYSTEM_ERROR2_TEMPLATE(class DomainType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<detail::erased<ErasedType>, DomainType>::value),
                          SYSTEM_ERROR2_TPRED(!detail::is_erased_status_code<status_code<typename std::decay<DomainType>::type>>::value))
  errored_status_code(const errored_status_code<DomainType> &v) noexcept
      : _base(static_cast<const status_code<DomainType> &>(v)) // NOLINT
  {
    _check();
  }
  //! Implicit move construction from any other status code if its value type is trivially copyable or move bitcopying and it would fit into our storage
  SYSTEM_ERROR2_TEMPLATE(class DomainType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<detail::erased<ErasedType>, DomainType>::value))
  errored_status_code(status_code<DomainType> &&v) noexcept
      : _base(static_cast<status_code<DomainType> &&>(v)) // NOLINT
  {
    _check();
  }
  //! Implicit move construction from any other status code if its value type is trivially copyable or move bitcopying and it would fit into our storage
  SYSTEM_ERROR2_TEMPLATE(class DomainType) //
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(detail::domain_value_type_erasure_is_safe<detail::erased<ErasedType>, DomainType>::value))
  errored_status_code(errored_status_code<DomainType> &&v) noexcept
      : _base(static_cast<status_code<DomainType> &&>(v)) // NOLINT
  {
    _check();
  }
  //! Implicit construction from any type where an ADL discovered `make_status_code(T, Args ...)` returns a `status_code`.
  SYSTEM_ERROR2_TEMPLATE(
  class T, class... Args, //
  class MakeStatusCodeResult =
  typename detail::safe_get_make_status_code_result<T, Args...>::type) // Safe ADL lookup of make_status_code(), returns void if not found
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(!std::is_same<typename std::decay<T>::type, errored_status_code>::value // not copy/move of self
                                              && !std::is_same<typename std::decay<T>::type, value_type>::value // not copy/move of value type
                                              && is_status_code<MakeStatusCodeResult>::value // ADL makes a status code
                                              && std::is_constructible<errored_status_code, MakeStatusCodeResult>::value)) // ADLed status code is compatible
  errored_status_code(T &&v, Args &&...args) noexcept(noexcept(make_status_code(std::declval<T>(), std::declval<Args>()...))) // NOLINT
      : errored_status_code(make_status_code(static_cast<T &&>(v), static_cast<Args &&>(args)...))
  {
    _check();
  }
  //! Implicit construction from any `quick_status_code_from_enum<Enum>` enumerated type.
  SYSTEM_ERROR2_TEMPLATE(class Enum, //
                         class QuickStatusCodeType = typename quick_status_code_from_enum<Enum>::code_type) // Enumeration has been activated
  SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(std::is_constructible<errored_status_code, QuickStatusCodeType>::value)) // Its status code is compatible
  errored_status_code(Enum &&v) noexcept(std::is_nothrow_constructible<errored_status_code, QuickStatusCodeType>::value) // NOLINT
      : errored_status_code(QuickStatusCodeType(static_cast<Enum &&>(v)))
  {
    _check();
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  //! Explicit copy construction from an unknown status code. Note that this will be empty if its value type is not trivially copyable or would not fit into our
  //! storage or the source domain's `_do_erased_copy()` refused the copy.
  explicit errored_status_code(const status_code<void> &v) // NOLINT
      : _base(v)
  {
    _check();
  }
#endif
  //! Always false (including at compile time), as errored status codes are never successful.
  constexpr bool success() const noexcept { return false; }
  //! Return the erased `value_type` by value.
  constexpr value_type value() const noexcept { return this->_value; }
};
/*! An erased type specialisation of `errored_status_code<D>`.
Available only if `ErasedType` satisfies `traits::is_move_bitcopying<ErasedType>::value`.
*/
template <class ErasedType> using erased_errored_status_code = errored_status_code<detail::erased<ErasedType>>;
namespace traits
{
  template <class ErasedType> struct is_move_bitcopying<errored_status_code<detail::erased<ErasedType>>>
  {
    static constexpr bool value = true;
  };
} // namespace traits
//! True if the status code's are semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2>
inline bool operator==(const errored_status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept
{
  return a.equivalent(static_cast<const status_code<DomainType2> &>(b));
}
//! True if the status code's are semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2> inline bool operator==(const status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept
{
  return a.equivalent(static_cast<const status_code<DomainType2> &>(b));
}
//! True if the status code's are semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2> inline bool operator==(const errored_status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept
{
  return static_cast<const status_code<DomainType1> &>(a).equivalent(b);
}
//! True if the status code's are not semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2>
inline bool operator!=(const errored_status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept
{
  return !a.equivalent(static_cast<const status_code<DomainType2> &>(b));
}
//! True if the status code's are not semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2> inline bool operator!=(const status_code<DomainType1> &a, const errored_status_code<DomainType2> &b) noexcept
{
  return !a.equivalent(static_cast<const status_code<DomainType2> &>(b));
}
//! True if the status code's are not semantically equal via `equivalent()`.
template <class DomainType1, class DomainType2> inline bool operator!=(const errored_status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept
{
  return !static_cast<const status_code<DomainType1> &>(a).equivalent(b);
}
//! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
inline bool operator==(const errored_status_code<DomainType1> &a, const T &b)
{
  return a.equivalent(make_status_code(b));
}
//! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
inline bool operator==(const T &a, const errored_status_code<DomainType1> &b)
{
  return b.equivalent(make_status_code(a));
}
//! True if the status code's are not semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
inline bool operator!=(const errored_status_code<DomainType1> &a, const T &b)
{
  return !a.equivalent(make_status_code(b));
}
//! True if the status code's are semantically equal via `equivalent()` to `make_status_code(T)`.
SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1, //
                       class MakeStatusCodeResult =
                       typename detail::safe_get_make_status_code_result<const T &>::type) // Safe ADL lookup of make_status_code(), returns void if not found
SYSTEM_ERROR2_TREQUIRES(SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value)) // ADL makes a status code
inline bool operator!=(const T &a, const errored_status_code<DomainType1> &b)
{
  return !b.equivalent(make_status_code(a));
}
//! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`.
template <class DomainType1, class T, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
inline bool operator==(const errored_status_code<DomainType1> &a, const T &b)
{
  return a.equivalent(QuickStatusCodeType(b));
}
//! True if the status code's are semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`.
template <class T, class DomainType1, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
inline bool operator==(const T &a, const errored_status_code<DomainType1> &b)
{
  return b.equivalent(QuickStatusCodeType(a));
}
//! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(b)`.
template <class DomainType1, class T, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
inline bool operator!=(const errored_status_code<DomainType1> &a, const T &b)
{
  return !a.equivalent(QuickStatusCodeType(b));
}
//! True if the status code's are not semantically equal via `equivalent()` to `quick_status_code_from_enum<T>::code_type(a)`.
template <class T, class DomainType1, //
          class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type // Enumeration has been activated
          >
inline bool operator!=(const T &a, const errored_status_code<DomainType1> &b)
{
  return !b.equivalent(QuickStatusCodeType(a));
}
namespace detail
{
  template <class T> struct is_errored_status_code
  {
    static constexpr bool value = false;
  };
  template <class T> struct is_errored_status_code<errored_status_code<T>>
  {
    static constexpr bool value = true;
  };
  template <class T> struct is_erased_errored_status_code
  {
    static constexpr bool value = false;
  };
  template <class T> struct is_erased_errored_status_code<errored_status_code<erased<T>>>
  {
    static constexpr bool value = true;
  };
} // namespace detail
//! Trait returning true if the type is an errored status code.
template <class T> struct is_errored_status_code
{
  static constexpr bool value =
  detail::is_errored_status_code<typename std::decay<T>::type>::value || detail::is_erased_errored_status_code<typename std::decay<T>::type>::value;
};
SYSTEM_ERROR2_NAMESPACE_END
#endif
/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_SYSTEM_CODE_HPP
#define SYSTEM_ERROR2_SYSTEM_CODE_HPP
#ifndef SYSTEM_ERROR2_NOT_POSIX
/* Proposed SG14 status_code
(C) 2018-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_POSIX_CODE_HPP
#define SYSTEM_ERROR2_POSIX_CODE_HPP
#ifdef SYSTEM_ERROR2_NOT_POSIX
#error <posix_code.hpp> is not includable when SYSTEM_ERROR2_NOT_POSIX is defined!
#endif
#include <cstring> // for strchr and strerror_r
SYSTEM_ERROR2_NAMESPACE_BEGIN
// Fix for issue #48 Issue compiling on arm-none-eabi (newlib) with GNU extensions off
#ifdef __APPLE__
#include <cstring>
#elif !defined(_MSC_VER)
namespace detail
{
  namespace avoid_string_include
  {
#if defined(__GLIBC__) && !defined(__UCLIBC__)
    // This returns int for non-glibc strerror_r, but glibc's is particularly weird so we retain it
    extern "C" char *strerror_r(int errnum, char *buf, size_t buflen);
#else
    extern "C" int strerror_r(int errnum, char *buf, size_t buflen);
#endif
  } // namespace avoid_string_include
} // namespace detail
#endif
class _posix_code_domain;
//! A POSIX error code, those returned by `errno`.
using posix_code = status_code<_posix_code_domain>;
//! A specialisation of `status_error` for the POSIX error code domain.
using posix_error = status_error<_posix_code_domain>;
namespace mixins
{
  template <class Base> struct mixin<Base, _posix_code_domain> : public Base
  {
    using Base::Base;
    //! Returns a `posix_code` for the current value of `errno`.
    static posix_code current() noexcept;
  };
} // namespace mixins
/*! The implementation of the domain for POSIX error codes, those returned by `errno`.
 */
class _posix_code_domain : public status_code_domain
{
  template <class DomainType> friend class status_code;
  template <class StatusCode, class Allocator> friend class detail::indirecting_domain;
  using _base = status_code_domain;
  static _base::string_ref _make_string_ref(int c) noexcept
  {
    char buffer[1024] = "";
#ifdef _WIN32
    strerror_s(buffer, sizeof(buffer), c);
#elif defined(__GLIBC__) && !defined(__UCLIBC__) // handle glibc's weird strerror_r()
    char *s = detail::avoid_string_include::strerror_r(c, buffer, sizeof(buffer)); // NOLINT
    if(s != nullptr)
    {
      strncpy(buffer, s, sizeof(buffer) - 1); // NOLINT
      buffer[1023] = 0;
    }
#elif !defined(__APPLE__)
    detail::avoid_string_include::strerror_r(c, buffer, sizeof(buffer));
#else
    strerror_r(c, buffer, sizeof(buffer));
#endif
    size_t length = strlen(buffer); // NOLINT
    auto *p = static_cast<char *>(malloc(length + 1)); // NOLINT
    if(p == nullptr)
    {
      return _base::string_ref("failed to get message from system");
    }
    memcpy(p, buffer, length + 1); // NOLINT
    return _base::atomic_refcounted_string_ref(p, length);
  }
public:
  //! The value type of the POSIX code, which is an `int`
  using value_type = int;
  using _base::string_ref;
  //! Default constructor
  constexpr explicit _posix_code_domain(typename _base::unique_id_type id = 0xa59a56fe5f310933) noexcept
      : _base(id)
  {
  }
  _posix_code_domain(const _posix_code_domain &) = default;
  _posix_code_domain(_posix_code_domain &&) = default;
  _posix_code_domain &operator=(const _posix_code_domain &) = default;
  _posix_code_domain &operator=(_posix_code_domain &&) = default;
  ~_posix_code_domain() = default;
  //! Constexpr singleton getter. Returns constexpr posix_code_domain variable.
  static inline constexpr const _posix_code_domain &get();
  virtual string_ref name() const noexcept override { return string_ref("posix domain"); } // NOLINT
  virtual payload_info_t payload_info() const noexcept override
  {
    return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
            (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
  }
protected:
  virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    return static_cast<const posix_code &>(code).value() != 0; // NOLINT
  }
  virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT
  {
    assert(code1.domain() == *this); // NOLINT
    const auto &c1 = static_cast<const posix_code &>(code1); // NOLINT
    if(code2.domain() == *this)
    {
      const auto &c2 = static_cast<const posix_code &>(code2); // NOLINT
      return c1.value() == c2.value();
    }
    if(code2.domain() == generic_code_domain)
    {
      const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT
      if(static_cast<int>(c2.value()) == c1.value())
      {
        return true;
      }
    }
    return false;
  }
  virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    const auto &c = static_cast<const posix_code &>(code); // NOLINT
    return generic_code(static_cast<errc>(c.value()));
  }
  virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    const auto &c = static_cast<const posix_code &>(code); // NOLINT
    return _make_string_ref(c.value());
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT
  {
    assert(code.domain() == *this); // NOLINT
    const auto &c = static_cast<const posix_code &>(code); // NOLINT
    throw status_error<_posix_code_domain>(c);
  }
#endif
};
//! A constexpr source variable for the POSIX code domain, which is that of `errno`. Returned by `_posix_code_domain::get()`.
constexpr _posix_code_domain posix_code_domain;
inline constexpr const _posix_code_domain &_posix_code_domain::get()
{
  return posix_code_domain;
}
namespace mixins
{
  template <class Base> inline posix_code mixin<Base, _posix_code_domain>::current() noexcept
  {
    return posix_code(errno);
  }
} // namespace mixins
SYSTEM_ERROR2_NAMESPACE_END
#endif
#else
#endif
#if defined(_WIN32) || 0L
/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_NT_CODE_HPP
#define SYSTEM_ERROR2_NT_CODE_HPP
#if !defined(_WIN32) && !0L
#error This file should only be included on Windows
#endif
/* Proposed SG14 status_code
(C) 2018 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
File Created: Feb 2018


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License in the accompanying file
Licence.txt or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Distributed under the Boost Software License, Version 1.0.
(See accompanying file Licence.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef SYSTEM_ERROR2_WIN32_CODE_HPP
#define SYSTEM_ERROR2_WIN32_CODE_HPP
#if !defined(_WIN32) && !0L
#error This file should only be included on Windows
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
//! \exclude
namespace win32
{
  // A Win32 DWORD
  using DWORD = unsigned long;
  // Used to retrieve the current Win32 error code
  extern DWORD __stdcall GetLastError();
  // Used to retrieve a locale-specific message string for some error code
  extern DWORD __stdcall FormatMessageW(DWORD dwFlags, const void *lpSource, DWORD dwMessageId, DWORD dwLanguageId, wchar_t *lpBuffer, DWORD nSize,
                                        void /*va_list*/ *Arguments);
  // Converts UTF-16 message string to UTF-8
  extern int __stdcall WideCharToMultiByte(unsigned int CodePage, DWORD dwFlags, const wchar_t *lpWideCharStr, int cchWideChar, char *lpMultiByteStr,
                                           int cbMultiByte, const char *lpDefaultChar, int *lpUsedDefaultChar);
#pragma comment(lib, "kernel32.lib")
#if (defined(__x86_64__) || defined(_M_X64)) || (defined(__aarch64__) || defined(_M_ARM64))
#pragma comment(linker, "/alternatename:?GetLastError@win32@system_error2@@YAKXZ=GetLastError")
#pragma comment(linker, "/alternatename:?FormatMessageW@win32@system_error2@@YAKKPEBXKKPEA_WKPEAX@Z=FormatMessageW")
#pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@system_error2@@YAHIKPEB_WHPEADHPEBDPEAH@Z=WideCharToMultiByte")
#elif defined(__x86__) || defined(_M_IX86) || defined(__i386__)
#pragma comment(linker, "/alternatename:?GetLastError@win32@system_error2@@YGKXZ=_GetLastError@0")
#pragma comment(linker, "/alternatename:?FormatMessageW@win32@system_error2@@YGKKPBXKKPA_WKPAX@Z=_FormatMessageW@28")
#pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@system_error2@@YGHIKPB_WHPADHPBDPAH@Z=_WideCharToMultiByte@32")
#elif defined(__arm__) || defined(_M_ARM)
#pragma comment(linker, "/alternatename:?GetLastError@win32@system_error2@@YAKXZ=GetLastError")
#pragma comment(linker, "/alternatename:?FormatMessageW@win32@system_error2@@YAKKPBXKKPA_WKPAX@Z=FormatMessageW")
#pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@system_error2@@YAHIKPB_WHPADHPBDPAH@Z=WideCharToMultiByte")
#else
#error Unknown architecture
#endif
} // namespace win32
class _win32_code_domain;
class _com_code_domain;
//! (Windows only) A Win32 error code, those returned by `GetLastError()`.
using win32_code = status_code<_win32_code_domain>;
//! (Windows only) A specialisation of `status_error` for the Win32 error code domain.
using win32_error = status_error<_win32_code_domain>;
namespace mixins
{
  template <class Base> struct mixin<Base, _win32_code_domain> : public Base
  {
    using Base::Base;
    //! Returns a `win32_code` for the current value of `GetLastError()`.
    static inline win32_code current() noexcept;
  };
} // namespace mixins
/*! (Windows only) The implementation of the domain for Win32 error codes, those returned by `GetLastError()`.
 */
class _win32_code_domain : public status_code_domain
{
  template <class DomainType> friend class status_code;
  template <class StatusCode, class Allocator> friend class detail::indirecting_domain;
  friend class _com_code_domain;
  using _base = status_code_domain;
  static int _win32_code_to_errno(win32::DWORD c)
  {
    switch(c)
    {
    case 0:
      return 0;
case 0x1: return ENOSYS;
case 0x2: return ENOENT;
case 0x3: return ENOENT;
case 0x4: return EMFILE;
case 0x5: return EACCES;
case 0x6: return EINVAL;
case 0x8: return ENOMEM;
case 0xc: return EACCES;
case 0xe: return ENOMEM;
case 0xf: return ENODEV;
case 0x10: return EACCES;
case 0x11: return EXDEV;
case 0x13: return EACCES;
case 0x14: return ENODEV;
case 0x15: return EAGAIN;
case 0x19: return EIO;
case 0x1d: return EIO;
case 0x1e: return EIO;
case 0x20: return EACCES;
case 0x21: return ENOLCK;
case 0x27: return ENOSPC;
case 0x37: return ENODEV;
case 0x50: return EEXIST;
case 0x52: return EACCES;
case 0x57: return EINVAL;
case 0x6e: return EIO;
case 0x6f: return ENAMETOOLONG;
case 0x70: return ENOSPC;
case 0x7b: return EINVAL;
case 0x83: return EINVAL;
case 0x8e: return EBUSY;
case 0x91: return ENOTEMPTY;
case 0xaa: return EBUSY;
case 0xb7: return EEXIST;
case 0xd4: return ENOLCK;
case 0x10b: return EINVAL;
case 0x3e3: return ECANCELED;
case 0x3e6: return EACCES;
case 0x3f3: return EIO;
case 0x3f4: return EIO;
case 0x3f5: return EIO;
case 0x4d5: return EAGAIN;
case 0x961: return EBUSY;
case 0x964: return EBUSY;
case 0x2714: return EINTR;
case 0x2719: return EBADF;
case 0x271d: return EACCES;
case 0x271e: return EFAULT;
case 0x2726: return EINVAL;
case 0x2728: return EMFILE;
case 0x2733: return EWOULDBLOCK;
case 0x2734: return EINPROGRESS;
case 0x2735: return EALREADY;
case 0x2736: return ENOTSOCK;
case 0x2737: return EDESTADDRREQ;
case 0x2738: return EMSGSIZE;
case 0x2739: return EPROTOTYPE;
case 0x273a: return ENOPROTOOPT;
case 0x273b: return EPROTONOSUPPORT;
case 0x273d: return EOPNOTSUPP;
case 0x273f: return EAFNOSUPPORT;
case 0x2740: return EADDRINUSE;
case 0x2741: return EADDRNOTAVAIL;
case 0x2742: return ENETDOWN;
case 0x2743: return ENETUNREACH;
case 0x2744: return ENETRESET;
case 0x2745: return ECONNABORTED;
case 0x2746: return ECONNRESET;
case 0x2747: return ENOBUFS;
case 0x2748: return EISCONN;
case 0x2749: return ENOTCONN;
case 0x274c: return ETIMEDOUT;
case 0x274d: return ECONNREFUSED;
case 0x274f: return ENAMETOOLONG;
case 0x2751: return EHOSTUNREACH;
    }
    return -1;
  }
  //! Construct from a Win32 error code
  static _base::string_ref _make_string_ref(win32::DWORD c) noexcept
  {
    wchar_t buffer[32768];
    win32::DWORD wlen =
    win32::FormatMessageW(0x00001000 /*FORMAT_MESSAGE_FROM_SYSTEM*/ | 0x00000200 /*FORMAT_MESSAGE_IGNORE_INSERTS*/, nullptr, c, 0, buffer, 32768, nullptr);
    size_t allocation = wlen + (wlen >> 1);
    win32::DWORD bytes;
    if(wlen == 0)
    {
      return _base::string_ref("failed to get message from system");
    }
    for(;;)
    {
      auto *p = static_cast<char *>(malloc(allocation)); // NOLINT
      if(p == nullptr)
      {
        return _base::string_ref("failed to get message from system");
      }
      bytes = win32::WideCharToMultiByte(65001 /*CP_UTF8*/, 0, buffer, (int) (wlen + 1), p, (int) allocation, nullptr, nullptr);
      if(bytes != 0)
      {
        char *end = strchr(p, 0);
        while(end[-1] == 10 || end[-1] == 13)
        {
          --end;
        }
        *end = 0; // NOLINT
        return _base::atomic_refcounted_string_ref(p, end - p);
      }
      free(p); // NOLINT
      if(win32::GetLastError() == 0x7a /*ERROR_INSUFFICIENT_BUFFER*/)
      {
        allocation += allocation >> 2;
        continue;
      }
      return _base::string_ref("failed to get message from system");
    }
  }
public:
  //! The value type of the win32 code, which is a `win32::DWORD`
  using value_type = win32::DWORD;
  using _base::string_ref;
public:
  //! Default constructor
  constexpr explicit _win32_code_domain(typename _base::unique_id_type id = 0x8cd18ee72d680f1b) noexcept
      : _base(id)
  {
  }
  _win32_code_domain(const _win32_code_domain &) = default;
  _win32_code_domain(_win32_code_domain &&) = default;
  _win32_code_domain &operator=(const _win32_code_domain &) = default;
  _win32_code_domain &operator=(_win32_code_domain &&) = default;
  ~_win32_code_domain() = default;
  //! Constexpr singleton getter. Returns the constexpr win32_code_domain variable.
  static inline constexpr const _win32_code_domain &get();
  virtual string_ref name() const noexcept override { return string_ref("win32 domain"); } // NOLINT
  virtual payload_info_t payload_info() const noexcept override
  {
    return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
            (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
  }
protected:
  virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this);
    return static_cast<const win32_code &>(code).value() != 0; // NOLINT
  }
  virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT
  {
    assert(code1.domain() == *this);
    const auto &c1 = static_cast<const win32_code &>(code1); // NOLINT
    if(code2.domain() == *this)
    {
      const auto &c2 = static_cast<const win32_code &>(code2); // NOLINT
      return c1.value() == c2.value();
    }
    if(code2.domain() == generic_code_domain)
    {
      const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT
      if(static_cast<int>(c2.value()) == _win32_code_to_errno(c1.value()))
      {
        return true;
      }
    }
    return false;
  }
  virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this);
    const auto &c = static_cast<const win32_code &>(code); // NOLINT
    return generic_code(static_cast<errc>(_win32_code_to_errno(c.value())));
  }
  virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this);
    const auto &c = static_cast<const win32_code &>(code); // NOLINT
    return _make_string_ref(c.value());
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT
  {
    assert(code.domain() == *this);
    const auto &c = static_cast<const win32_code &>(code); // NOLINT
    throw status_error<_win32_code_domain>(c);
  }
#endif
};
//! (Windows only) A constexpr source variable for the win32 code domain, which is that of `GetLastError()` (Windows). Returned by `_win32_code_domain::get()`.
constexpr _win32_code_domain win32_code_domain;
inline constexpr const _win32_code_domain &_win32_code_domain::get()
{
  return win32_code_domain;
}
namespace mixins
{
  template <class Base> inline win32_code mixin<Base, _win32_code_domain>::current() noexcept
  {
    return win32_code(win32::GetLastError());
  }
} // namespace mixins
SYSTEM_ERROR2_NAMESPACE_END
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
//! \exclude
namespace win32
{
  // A Win32 NTSTATUS
  using NTSTATUS = long;
  // A Win32 HMODULE
  using HMODULE = void *;
  // Used to retrieve where the NTDLL DLL is mapped into memory
  extern HMODULE __stdcall GetModuleHandleW(const wchar_t *lpModuleName);
#pragma comment(lib, "kernel32.lib")
#if (defined(__x86_64__) || defined(_M_X64)) || (defined(__aarch64__) || defined(_M_ARM64))
#pragma comment(linker, "/alternatename:?GetModuleHandleW@win32@system_error2@@YAPEAXPEB_W@Z=GetModuleHandleW")
#elif defined(__x86__) || defined(_M_IX86) || defined(__i386__)
#pragma comment(linker, "/alternatename:?GetModuleHandleW@win32@system_error2@@YGPAXPB_W@Z=_GetModuleHandleW@4")
#elif defined(__arm__) || defined(_M_ARM)
#pragma comment(linker, "/alternatename:?GetModuleHandleW@win32@system_error2@@YAPAXPB_W@Z=GetModuleHandleW")
#else
#error Unknown architecture
#endif
} // namespace win32
class _nt_code_domain;
//! (Windows only) A NT error code, those returned by NT kernel functions.
using nt_code = status_code<_nt_code_domain>;
//! (Windows only) A specialisation of `status_error` for the NT error code domain.
using nt_error = status_error<_nt_code_domain>;
/*! (Windows only) The implementation of the domain for NT error codes, those returned by NT kernel functions.
 */
class _nt_code_domain : public status_code_domain
{
  template <class DomainType> friend class status_code;
  template <class StatusCode, class Allocator> friend class detail::indirecting_domain;
  friend class _com_code_domain;
  using _base = status_code_domain;
  static int _nt_code_to_errno(win32::NTSTATUS c)
  {
    if(c >= 0)
    {
      return 0; // success
    }
    switch(static_cast<unsigned>(c))
    {
case 0x80000002: return EACCES;
case 0x8000000f: return EAGAIN;
case 0x80000010: return EAGAIN;
case 0x80000011: return EBUSY;
case 0xc0000002: return ENOSYS;
case 0xc0000005: return EACCES;
case 0xc0000008: return EINVAL;
case 0xc000000e: return ENOENT;
case 0xc000000f: return ENOENT;
case 0xc0000010: return ENOSYS;
case 0xc0000013: return EAGAIN;
case 0xc0000017: return ENOMEM;
case 0xc000001c: return ENOSYS;
case 0xc000001e: return EACCES;
case 0xc000001f: return EACCES;
case 0xc0000021: return EACCES;
case 0xc0000022: return EACCES;
case 0xc0000024: return EINVAL;
case 0xc0000033: return EINVAL;
case 0xc0000034: return ENOENT;
case 0xc0000035: return EEXIST;
case 0xc0000037: return EINVAL;
case 0xc000003a: return ENOENT;
case 0xc0000040: return ENOMEM;
case 0xc0000041: return EACCES;
case 0xc0000042: return EINVAL;
case 0xc0000043: return EACCES;
case 0xc000004b: return EACCES;
case 0xc0000054: return ENOLCK;
case 0xc0000055: return ENOLCK;
case 0xc0000056: return EACCES;
case 0xc000007f: return ENOSPC;
case 0xc0000087: return ENOMEM;
case 0xc0000097: return ENOMEM;
case 0xc000009b: return ENOENT;
case 0xc000009e: return EAGAIN;
case 0xc00000a2: return EACCES;
case 0xc00000a3: return EAGAIN;
case 0xc00000af: return ENOSYS;
case 0xc00000ba: return EACCES;
case 0xc00000c0: return ENODEV;
case 0xc00000d4: return EXDEV;
case 0xc00000d5: return EACCES;
case 0xc00000fb: return ENOENT;
case 0xc0000101: return ENOTEMPTY;
case 0xc0000103: return EINVAL;
case 0xc0000107: return EBUSY;
case 0xc0000108: return EBUSY;
case 0xc000010a: return EACCES;
case 0xc000011f: return EMFILE;
case 0xc0000120: return ECANCELED;
case 0xc0000121: return EACCES;
case 0xc0000123: return EACCES;
case 0xc0000128: return EINVAL;
case 0xc0000189: return EACCES;
case 0xc00001ad: return ENOMEM;
case 0xc000022d: return EAGAIN;
case 0xc0000235: return EINVAL;
case 0xc000026e: return EAGAIN;
case 0xc000028a: return EACCES;
case 0xc000028b: return EACCES;
case 0xc000028d: return EACCES;
case 0xc000028e: return EACCES;
case 0xc000028f: return EACCES;
case 0xc0000290: return EACCES;
case 0xc000029c: return ENOSYS;
case 0xc00002c5: return EACCES;
case 0xc00002d3: return EAGAIN;
case 0xc00002ea: return EACCES;
case 0xc00002f0: return ENOENT;
case 0xc0000373: return ENOMEM;
case 0xc0000416: return ENOMEM;
case 0xc0000433: return EBUSY;
case 0xc0000434: return EBUSY;
case 0xc0000455: return EINVAL;
case 0xc0000467: return EACCES;
case 0xc0000491: return ENOENT;
case 0xc0000495: return EAGAIN;
case 0xc0000503: return EAGAIN;
case 0xc0000507: return EBUSY;
case 0xc0000512: return EACCES;
case 0xc000070a: return EINVAL;
case 0xc000070b: return EINVAL;
case 0xc000070c: return EINVAL;
case 0xc000070d: return EINVAL;
case 0xc000070e: return EINVAL;
case 0xc000070f: return EINVAL;
case 0xc0000710: return ENOSYS;
case 0xc0000711: return ENOSYS;
case 0xc0000716: return EINVAL;
case 0xc000071b: return ENOSYS;
case 0xc000071d: return ENOSYS;
case 0xc000071e: return ENOSYS;
case 0xc000071f: return ENOSYS;
case 0xc0000720: return ENOSYS;
case 0xc0000721: return ENOSYS;
case 0xc000080f: return EAGAIN;
case 0xc000a203: return EACCES;
    }
    return -1;
  }
  static win32::DWORD _nt_code_to_win32_code(win32::NTSTATUS c) // NOLINT
  {
    if(c >= 0)
    {
      return 0; // success
    }
    switch(static_cast<unsigned>(c))
    {
case 0x80000002: return 0x3e6;
case 0x80000005: return 0xea;
case 0x80000006: return 0x12;
case 0x80000007: return 0x2a3;
case 0x8000000a: return 0x2a4;
case 0x8000000b: return 0x56f;
case 0x8000000c: return 0x2a8;
case 0x8000000d: return 0x12b;
case 0x8000000e: return 0x1c;
case 0x8000000f: return 0x15;
case 0x80000010: return 0x15;
case 0x80000011: return 0xaa;
case 0x80000012: return 0x103;
case 0x80000013: return 0xfe;
case 0x80000014: return 0xff;
case 0x80000015: return 0xff;
case 0x80000016: return 0x456;
case 0x80000017: return 0x2a5;
case 0x80000018: return 0x2a6;
case 0x8000001a: return 0x103;
case 0x8000001b: return 0x44d;
case 0x8000001c: return 0x456;
case 0x8000001d: return 0x457;
case 0x8000001e: return 0x44c;
case 0x8000001f: return 0x44e;
case 0x80000020: return 0x2a7;
case 0x80000021: return 0x44f;
case 0x80000022: return 0x450;
case 0x80000023: return 0x702;
case 0x80000024: return 0x713;
case 0x80000025: return 0x962;
case 0x80000026: return 0x2aa;
case 0x80000027: return 0x10f4;
case 0x80000028: return 0x2ab;
case 0x80000029: return 0x2ac;
case 0x8000002a: return 0x2ad;
case 0x8000002b: return 0x2ae;
case 0x8000002c: return 0x2af;
case 0x8000002d: return 0x2a9;
case 0x8000002e: return 0x321;
case 0x8000002f: return 0x324;
case 0x80000030: return 0xab;
case 0x80000032: return 0xeb;
case 0x80000288: return 0x48d;
case 0x80000289: return 0x48e;
case 0x80000803: return 0x1abb;
case 0x8000a127: return 0x3bdf;
case 0x8000cf00: return 0x16e;
case 0x8000cf04: return 0x16d;
case 0x8000cf05: return 0x176;
case 0x80130001: return 0x13c5;
case 0x80130002: return 0x13c6;
case 0x80130003: return 0x13c7;
case 0x80130004: return 0x13c8;
case 0x80130005: return 0x13c9;
case 0x80190009: return 0x19e5;
case 0x80190029: return 0x1aa0;
case 0x80190031: return 0x1aa2;
case 0x80190041: return 0x1ab3;
case 0x80190042: return 0x1ab4;
case 0x801c0001: return 0x7a;
case 0xc0000001: return 0x1f;
case 0xc0000002: return 0x1;
case 0xc0000003: return 0x57;
case 0xc0000004: return 0x18;
case 0xc0000005: return 0x3e6;
case 0xc0000006: return 0x3e7;
case 0xc0000007: return 0x5ae;
case 0xc0000008: return 0x6;
case 0xc0000009: return 0x3e9;
case 0xc000000a: return 0xc1;
case 0xc000000b: return 0x57;
case 0xc000000c: return 0x21d;
case 0xc000000d: return 0x57;
case 0xc000000e: return 0x2;
case 0xc000000f: return 0x2;
case 0xc0000010: return 0x1;
case 0xc0000011: return 0x26;
case 0xc0000012: return 0x22;
case 0xc0000013: return 0x15;
case 0xc0000014: return 0x6f9;
case 0xc0000015: return 0x1b;
case 0xc0000016: return 0xea;
case 0xc0000017: return 0x8;
case 0xc0000018: return 0x1e7;
case 0xc0000019: return 0x1e7;
case 0xc000001a: return 0x57;
case 0xc000001b: return 0x57;
case 0xc000001c: return 0x1;
case 0xc000001e: return 0x5;
case 0xc000001f: return 0x5;
case 0xc0000020: return 0xc1;
case 0xc0000021: return 0x5;
case 0xc0000022: return 0x5;
case 0xc0000023: return 0x7a;
case 0xc0000024: return 0x6;
case 0xc0000027: return 0x21e;
case 0xc0000028: return 0x21f;
case 0xc0000029: return 0x220;
case 0xc000002a: return 0x9e;
case 0xc000002c: return 0x1e7;
case 0xc000002d: return 0x1e7;
case 0xc000002e: return 0x221;
case 0xc000002f: return 0x222;
case 0xc0000030: return 0x57;
case 0xc0000031: return 0x223;
case 0xc0000032: return 0x571;
case 0xc0000033: return 0x7b;
case 0xc0000034: return 0x2;
case 0xc0000035: return 0xb7;
case 0xc0000036: return 0x72a;
case 0xc0000037: return 0x6;
case 0xc0000038: return 0x224;
case 0xc0000039: return 0xa1;
case 0xc000003a: return 0x3;
case 0xc000003b: return 0xa1;
case 0xc000003c: return 0x45d;
case 0xc000003d: return 0x45d;
case 0xc000003e: return 0x17;
case 0xc000003f: return 0x17;
case 0xc0000040: return 0x8;
case 0xc0000041: return 0x5;
case 0xc0000042: return 0x6;
case 0xc0000043: return 0x20;
case 0xc0000044: return 0x718;
case 0xc0000045: return 0x57;
case 0xc0000046: return 0x120;
case 0xc0000047: return 0x12a;
case 0xc0000048: return 0x57;
case 0xc0000049: return 0x57;
case 0xc000004a: return 0x9c;
case 0xc000004b: return 0x5;
case 0xc000004c: return 0x57;
case 0xc000004d: return 0x57;
case 0xc000004e: return 0x57;
case 0xc000004f: return 0x11a;
case 0xc0000050: return 0xff;
case 0xc0000051: return 0x570;
case 0xc0000052: return 0x570;
case 0xc0000053: return 0x570;
case 0xc0000054: return 0x21;
case 0xc0000055: return 0x21;
case 0xc0000056: return 0x5;
case 0xc0000057: return 0x32;
case 0xc0000058: return 0x519;
case 0xc0000059: return 0x51a;
case 0xc000005a: return 0x51b;
case 0xc000005b: return 0x51c;
case 0xc000005c: return 0x51d;
case 0xc000005d: return 0x51e;
case 0xc000005e: return 0x51f;
case 0xc000005f: return 0x520;
case 0xc0000060: return 0x521;
case 0xc0000061: return 0x522;
case 0xc0000062: return 0x523;
case 0xc0000063: return 0x524;
case 0xc0000064: return 0x525;
case 0xc0000065: return 0x526;
case 0xc0000066: return 0x527;
case 0xc0000067: return 0x528;
case 0xc0000068: return 0x529;
case 0xc0000069: return 0x52a;
case 0xc000006a: return 0x56;
case 0xc000006b: return 0x52c;
case 0xc000006c: return 0x52d;
case 0xc000006d: return 0x52e;
case 0xc000006e: return 0x52f;
case 0xc000006f: return 0x530;
case 0xc0000070: return 0x531;
case 0xc0000071: return 0x532;
case 0xc0000072: return 0x533;
case 0xc0000073: return 0x534;
case 0xc0000074: return 0x535;
case 0xc0000075: return 0x536;
case 0xc0000076: return 0x537;
case 0xc0000077: return 0x538;
case 0xc0000078: return 0x539;
case 0xc0000079: return 0x53a;
case 0xc000007a: return 0x7f;
case 0xc000007b: return 0xc1;
case 0xc000007c: return 0x3f0;
case 0xc000007d: return 0x53c;
case 0xc000007e: return 0x9e;
case 0xc000007f: return 0x70;
case 0xc0000080: return 0x53d;
case 0xc0000081: return 0x53e;
case 0xc0000082: return 0x44;
case 0xc0000083: return 0x103;
case 0xc0000084: return 0x53f;
case 0xc0000085: return 0x103;
case 0xc0000086: return 0x9a;
case 0xc0000087: return 0xe;
case 0xc0000088: return 0x1e7;
case 0xc0000089: return 0x714;
case 0xc000008a: return 0x715;
case 0xc000008b: return 0x716;
case 0xc0000095: return 0x216;
case 0xc0000097: return 0x8;
case 0xc0000098: return 0x3ee;
case 0xc0000099: return 0x540;
case 0xc000009a: return 0x5aa;
case 0xc000009b: return 0x3;
case 0xc000009c: return 0x17;
case 0xc000009d: return 0x48f;
case 0xc000009e: return 0x15;
case 0xc000009f: return 0x1e7;
case 0xc00000a0: return 0x1e7;
case 0xc00000a1: return 0x5ad;
case 0xc00000a2: return 0x13;
case 0xc00000a3: return 0x15;
case 0xc00000a4: return 0x541;
case 0xc00000a5: return 0x542;
case 0xc00000a6: return 0x543;
case 0xc00000a7: return 0x544;
case 0xc00000a8: return 0x545;
case 0xc00000a9: return 0x57;
case 0xc00000aa: return 0x225;
case 0xc00000ab: return 0xe7;
case 0xc00000ac: return 0xe7;
case 0xc00000ad: return 0xe6;
case 0xc00000ae: return 0xe7;
case 0xc00000af: return 0x1;
case 0xc00000b0: return 0xe9;
case 0xc00000b1: return 0xe8;
case 0xc00000b2: return 0x217;
case 0xc00000b3: return 0x218;
case 0xc00000b4: return 0xe6;
case 0xc00000b5: return 0x79;
case 0xc00000b6: return 0x26;
case 0xc00000b7: return 0x226;
case 0xc00000b8: return 0x227;
case 0xc00000b9: return 0x228;
case 0xc00000ba: return 0x5;
case 0xc00000bb: return 0x32;
case 0xc00000bc: return 0x33;
case 0xc00000bd: return 0x34;
case 0xc00000be: return 0x35;
case 0xc00000bf: return 0x36;
case 0xc00000c0: return 0x37;
case 0xc00000c1: return 0x38;
case 0xc00000c2: return 0x39;
case 0xc00000c3: return 0x3a;
case 0xc00000c4: return 0x3b;
case 0xc00000c5: return 0x3c;
case 0xc00000c6: return 0x3d;
case 0xc00000c7: return 0x3e;
case 0xc00000c8: return 0x3f;
case 0xc00000c9: return 0x40;
case 0xc00000ca: return 0x41;
case 0xc00000cb: return 0x42;
case 0xc00000cc: return 0x43;
case 0xc00000cd: return 0x44;
case 0xc00000ce: return 0x45;
case 0xc00000cf: return 0x46;
case 0xc00000d0: return 0x47;
case 0xc00000d1: return 0x48;
case 0xc00000d2: return 0x58;
case 0xc00000d3: return 0x229;
case 0xc00000d4: return 0x11;
case 0xc00000d5: return 0x5;
case 0xc00000d6: return 0xf0;
case 0xc00000d7: return 0x546;
case 0xc00000d8: return 0x22a;
case 0xc00000d9: return 0xe8;
case 0xc00000da: return 0x547;
case 0xc00000db: return 0x22b;
case 0xc00000dc: return 0x548;
case 0xc00000dd: return 0x549;
case 0xc00000de: return 0x54a;
case 0xc00000df: return 0x54b;
case 0xc00000e0: return 0x54c;
case 0xc00000e1: return 0x54d;
case 0xc00000e2: return 0x12c;
case 0xc00000e3: return 0x12d;
case 0xc00000e4: return 0x54e;
case 0xc00000e5: return 0x54f;
case 0xc00000e6: return 0x550;
case 0xc00000e7: return 0x551;
case 0xc00000e8: return 0x6f8;
case 0xc00000e9: return 0x45d;
case 0xc00000ea: return 0x22c;
case 0xc00000eb: return 0x22d;
case 0xc00000ec: return 0x22e;
case 0xc00000ed: return 0x552;
case 0xc00000ee: return 0x553;
case 0xc00000ef: return 0x57;
case 0xc00000f0: return 0x57;
case 0xc00000f1: return 0x57;
case 0xc00000f2: return 0x57;
case 0xc00000f3: return 0x57;
case 0xc00000f4: return 0x57;
case 0xc00000f5: return 0x57;
case 0xc00000f6: return 0x57;
case 0xc00000f7: return 0x57;
case 0xc00000f8: return 0x57;
case 0xc00000f9: return 0x57;
case 0xc00000fa: return 0x57;
case 0xc00000fb: return 0x3;
case 0xc00000fc: return 0x420;
case 0xc00000fd: return 0x3e9;
case 0xc00000fe: return 0x554;
case 0xc00000ff: return 0x22f;
case 0xc0000100: return 0xcb;
case 0xc0000101: return 0x91;
case 0xc0000102: return 0x570;
case 0xc0000103: return 0x10b;
case 0xc0000104: return 0x555;
case 0xc0000105: return 0x556;
case 0xc0000106: return 0xce;
case 0xc0000107: return 0x961;
case 0xc0000108: return 0x964;
case 0xc000010a: return 0x5;
case 0xc000010b: return 0x557;
case 0xc000010c: return 0x230;
case 0xc000010d: return 0x558;
case 0xc000010e: return 0x420;
case 0xc000010f: return 0x21a;
case 0xc0000110: return 0x21a;
case 0xc0000111: return 0x21a;
case 0xc0000112: return 0x21a;
case 0xc0000113: return 0x21a;
case 0xc0000114: return 0x21a;
case 0xc0000115: return 0x21a;
case 0xc0000116: return 0x21a;
case 0xc0000117: return 0x5a4;
case 0xc0000118: return 0x231;
case 0xc0000119: return 0x233;
case 0xc000011a: return 0x234;
case 0xc000011b: return 0xc1;
case 0xc000011c: return 0x559;
case 0xc000011d: return 0x55a;
case 0xc000011e: return 0x3ee;
case 0xc000011f: return 0x4;
case 0xc0000120: return 0x3e3;
case 0xc0000121: return 0x5;
case 0xc0000122: return 0x4ba;
case 0xc0000123: return 0x5;
case 0xc0000124: return 0x55b;
case 0xc0000125: return 0x55c;
case 0xc0000126: return 0x55d;
case 0xc0000127: return 0x55e;
case 0xc0000128: return 0x6;
case 0xc0000129: return 0x235;
case 0xc000012a: return 0x236;
case 0xc000012b: return 0x55f;
case 0xc000012c: return 0x237;
case 0xc000012d: return 0x5af;
case 0xc000012e: return 0xc1;
case 0xc000012f: return 0xc1;
case 0xc0000130: return 0xc1;
case 0xc0000131: return 0xc1;
case 0xc0000132: return 0x238;
case 0xc0000133: return 0x576;
case 0xc0000134: return 0x239;
case 0xc0000135: return 0x7e;
case 0xc0000136: return 0x23a;
case 0xc0000137: return 0x23b;
case 0xc0000138: return 0xb6;
case 0xc0000139: return 0x7f;
case 0xc000013a: return 0x23c;
case 0xc000013b: return 0x40;
case 0xc000013c: return 0x40;
case 0xc000013d: return 0x33;
case 0xc000013e: return 0x3b;
case 0xc000013f: return 0x3b;
case 0xc0000140: return 0x3b;
case 0xc0000141: return 0x3b;
case 0xc0000142: return 0x45a;
case 0xc0000143: return 0x23d;
case 0xc0000144: return 0x23e;
case 0xc0000145: return 0x23f;
case 0xc0000146: return 0x240;
case 0xc0000147: return 0x242;
case 0xc0000148: return 0x7c;
case 0xc0000149: return 0x56;
case 0xc000014a: return 0x243;
case 0xc000014b: return 0x6d;
case 0xc000014c: return 0x3f1;
case 0xc000014d: return 0x3f8;
case 0xc000014e: return 0x244;
case 0xc000014f: return 0x3ed;
case 0xc0000150: return 0x45e;
case 0xc0000151: return 0x560;
case 0xc0000152: return 0x561;
case 0xc0000153: return 0x562;
case 0xc0000154: return 0x563;
case 0xc0000155: return 0x564;
case 0xc0000156: return 0x565;
case 0xc0000157: return 0x566;
case 0xc0000158: return 0x567;
case 0xc0000159: return 0x3ef;
case 0xc000015a: return 0x568;
case 0xc000015b: return 0x569;
case 0xc000015c: return 0x3f9;
case 0xc000015d: return 0x56a;
case 0xc000015e: return 0x245;
case 0xc000015f: return 0x45d;
case 0xc0000160: return 0x4db;
case 0xc0000161: return 0x246;
case 0xc0000162: return 0x459;
case 0xc0000163: return 0x247;
case 0xc0000164: return 0x248;
case 0xc0000165: return 0x462;
case 0xc0000166: return 0x463;
case 0xc0000167: return 0x464;
case 0xc0000168: return 0x465;
case 0xc0000169: return 0x466;
case 0xc000016a: return 0x467;
case 0xc000016b: return 0x468;
case 0xc000016c: return 0x45f;
case 0xc000016d: return 0x45d;
case 0xc000016e: return 0x249;
case 0xc0000172: return 0x451;
case 0xc0000173: return 0x452;
case 0xc0000174: return 0x453;
case 0xc0000175: return 0x454;
case 0xc0000176: return 0x455;
case 0xc0000177: return 0x469;
case 0xc0000178: return 0x458;
case 0xc000017a: return 0x56b;
case 0xc000017b: return 0x56c;
case 0xc000017c: return 0x3fa;
case 0xc000017d: return 0x3fb;
case 0xc000017e: return 0x56d;
case 0xc000017f: return 0x56e;
case 0xc0000180: return 0x3fc;
case 0xc0000181: return 0x3fd;
case 0xc0000182: return 0x57;
case 0xc0000183: return 0x45d;
case 0xc0000184: return 0x16;
case 0xc0000185: return 0x45d;
case 0xc0000186: return 0x45d;
case 0xc0000187: return 0x24a;
case 0xc0000188: return 0x5de;
case 0xc0000189: return 0x13;
case 0xc000018a: return 0x6fa;
case 0xc000018b: return 0x6fb;
case 0xc000018c: return 0x6fc;
case 0xc000018d: return 0x6fd;
case 0xc000018e: return 0x5dc;
case 0xc000018f: return 0x5dd;
case 0xc0000190: return 0x6fe;
case 0xc0000191: return 0x24b;
case 0xc0000192: return 0x700;
case 0xc0000193: return 0x701;
case 0xc0000194: return 0x46b;
case 0xc0000195: return 0x4c3;
case 0xc0000196: return 0x4c4;
case 0xc0000197: return 0x5df;
case 0xc0000198: return 0x70f;
case 0xc0000199: return 0x710;
case 0xc000019a: return 0x711;
case 0xc000019b: return 0x712;
case 0xc000019c: return 0x24c;
case 0xc000019d: return 0x420;
case 0xc000019e: return 0x130;
case 0xc000019f: return 0x131;
case 0xc00001a0: return 0x132;
case 0xc00001a1: return 0x133;
case 0xc00001a2: return 0x325;
case 0xc00001a3: return 0x134;
case 0xc00001a4: return 0x135;
case 0xc00001a5: return 0x136;
case 0xc00001a6: return 0x137;
case 0xc00001a7: return 0x139;
case 0xc00001a8: return 0x1abb;
case 0xc00001a9: return 0x32;
case 0xc00001aa: return 0x3d54;
case 0xc00001ab: return 0x329;
case 0xc00001ac: return 0x678;
case 0xc00001ad: return 0x8;
case 0xc00001ae: return 0x2f7;
case 0xc00001af: return 0x32d;
case 0xc0000201: return 0x41;
case 0xc0000202: return 0x572;
case 0xc0000203: return 0x3b;
case 0xc0000204: return 0x717;
case 0xc0000205: return 0x46a;
case 0xc0000206: return 0x6f8;
case 0xc0000207: return 0x4be;
case 0xc0000208: return 0x4be;
case 0xc0000209: return 0x44;
case 0xc000020a: return 0x34;
case 0xc000020b: return 0x40;
case 0xc000020c: return 0x40;
case 0xc000020d: return 0x40;
case 0xc000020e: return 0x44;
case 0xc000020f: return 0x3b;
case 0xc0000210: return 0x3b;
case 0xc0000211: return 0x3b;
case 0xc0000212: return 0x3b;
case 0xc0000213: return 0x3b;
case 0xc0000214: return 0x3b;
case 0xc0000215: return 0x3b;
case 0xc0000216: return 0x32;
case 0xc0000217: return 0x32;
case 0xc0000218: return 0x24d;
case 0xc0000219: return 0x24e;
case 0xc000021a: return 0x24f;
case 0xc000021b: return 0x250;
case 0xc000021c: return 0x17e6;
case 0xc000021d: return 0x251;
case 0xc000021e: return 0x252;
case 0xc000021f: return 0x253;
case 0xc0000220: return 0x46c;
case 0xc0000221: return 0xc1;
case 0xc0000222: return 0x254;
case 0xc0000223: return 0x255;
case 0xc0000224: return 0x773;
case 0xc0000225: return 0x490;
case 0xc0000226: return 0x256;
case 0xc0000227: return 0x4ff;
case 0xc0000228: return 0x257;
case 0xc0000229: return 0x57;
case 0xc000022a: return 0x1392;
case 0xc000022b: return 0x1392;
case 0xc000022c: return 0x258;
case 0xc000022d: return 0x4d5;
case 0xc000022e: return 0x259;
case 0xc000022f: return 0x25a;
case 0xc0000230: return 0x492;
case 0xc0000231: return 0x25b;
case 0xc0000232: return 0x25c;
case 0xc0000233: return 0x774;
case 0xc0000234: return 0x775;
case 0xc0000235: return 0x6;
case 0xc0000236: return 0x4c9;
case 0xc0000237: return 0x4ca;
case 0xc0000238: return 0x4cb;
case 0xc0000239: return 0x4cc;
case 0xc000023a: return 0x4cd;
case 0xc000023b: return 0x4ce;
case 0xc000023c: return 0x4cf;
case 0xc000023d: return 0x4d0;
case 0xc000023e: return 0x4d1;
case 0xc000023f: return 0x4d2;
case 0xc0000240: return 0x4d3;
case 0xc0000241: return 0x4d4;
case 0xc0000242: return 0x25d;
case 0xc0000243: return 0x4c8;
case 0xc0000244: return 0x25e;
case 0xc0000245: return 0x25f;
case 0xc0000246: return 0x4d6;
case 0xc0000247: return 0x4d7;
case 0xc0000248: return 0x4d8;
case 0xc0000249: return 0xc1;
case 0xc0000250: return 0x260;
case 0xc0000251: return 0x261;
case 0xc0000252: return 0x262;
case 0xc0000253: return 0x4d4;
case 0xc0000254: return 0x263;
case 0xc0000255: return 0x264;
case 0xc0000256: return 0x265;
case 0xc0000257: return 0x4d0;
case 0xc0000258: return 0x266;
case 0xc0000259: return 0x573;
case 0xc000025a: return 0x267;
case 0xc000025b: return 0x268;
case 0xc000025c: return 0x269;
case 0xc000025e: return 0x422;
case 0xc000025f: return 0x26a;
case 0xc0000260: return 0x26b;
case 0xc0000261: return 0x26c;
case 0xc0000262: return 0xb6;
case 0xc0000263: return 0x7f;
case 0xc0000264: return 0x120;
case 0xc0000265: return 0x476;
case 0xc0000266: return 0x26d;
case 0xc0000267: return 0x10fe;
case 0xc0000268: return 0x26e;
case 0xc0000269: return 0x26f;
case 0xc000026a: return 0x1b8e;
case 0xc000026b: return 0x270;
case 0xc000026c: return 0x7d1;
case 0xc000026d: return 0x4b1;
case 0xc000026e: return 0x15;
case 0xc000026f: return 0x21c;
case 0xc0000270: return 0x21c;
case 0xc0000271: return 0x271;
case 0xc0000272: return 0x491;
case 0xc0000273: return 0x272;
case 0xc0000275: return 0x1126;
case 0xc0000276: return 0x1129;
case 0xc0000277: return 0x112a;
case 0xc0000278: return 0x1128;
case 0xc0000279: return 0x780;
case 0xc000027a: return 0x291;
case 0xc000027b: return 0x54f;
case 0xc000027c: return 0x54f;
case 0xc0000280: return 0x781;
case 0xc0000281: return 0xa1;
case 0xc0000282: return 0x273;
case 0xc0000283: return 0x488;
case 0xc0000284: return 0x489;
case 0xc0000285: return 0x48a;
case 0xc0000286: return 0x48b;
case 0xc0000287: return 0x48c;
case 0xc000028a: return 0x5;
case 0xc000028b: return 0x5;
case 0xc000028c: return 0x284;
case 0xc000028d: return 0x5;
case 0xc000028e: return 0x5;
case 0xc000028f: return 0x5;
case 0xc0000290: return 0x5;
case 0xc0000291: return 0x1777;
case 0xc0000292: return 0x1778;
case 0xc0000293: return 0x1772;
case 0xc0000295: return 0x1068;
case 0xc0000296: return 0x1069;
case 0xc0000297: return 0x106a;
case 0xc0000298: return 0x106b;
case 0xc0000299: return 0x201a;
case 0xc000029a: return 0x201b;
case 0xc000029b: return 0x201c;
case 0xc000029c: return 0x1;
case 0xc000029d: return 0x10ff;
case 0xc000029e: return 0x1100;
case 0xc000029f: return 0x494;
case 0xc00002a0: return 0x274;
case 0xc00002a1: return 0x200a;
case 0xc00002a2: return 0x200b;
case 0xc00002a3: return 0x200c;
case 0xc00002a4: return 0x200d;
case 0xc00002a5: return 0x200e;
case 0xc00002a6: return 0x200f;
case 0xc00002a7: return 0x2010;
case 0xc00002a8: return 0x2011;
case 0xc00002a9: return 0x2012;
case 0xc00002aa: return 0x2013;
case 0xc00002ab: return 0x2014;
case 0xc00002ac: return 0x2015;
case 0xc00002ad: return 0x2016;
case 0xc00002ae: return 0x2017;
case 0xc00002af: return 0x2018;
case 0xc00002b0: return 0x2019;
case 0xc00002b1: return 0x211e;
case 0xc00002b2: return 0x1127;
case 0xc00002b3: return 0x275;
case 0xc00002b4: return 0x276;
case 0xc00002b5: return 0x277;
case 0xc00002b6: return 0x651;
case 0xc00002b7: return 0x49a;
case 0xc00002b8: return 0x49b;
case 0xc00002b9: return 0x278;
case 0xc00002ba: return 0x2047;
case 0xc00002c1: return 0x2024;
case 0xc00002c2: return 0x279;
case 0xc00002c3: return 0x575;
case 0xc00002c4: return 0x27a;
case 0xc00002c5: return 0x3e6;
case 0xc00002c6: return 0x1075;
case 0xc00002c7: return 0x1076;
case 0xc00002c8: return 0x27b;
case 0xc00002c9: return 0x4ed;
case 0xc00002ca: return 0x10e8;
case 0xc00002cb: return 0x2138;
case 0xc00002cc: return 0x4e3;
case 0xc00002cd: return 0x2139;
case 0xc00002ce: return 0x27c;
case 0xc00002cf: return 0x49d;
case 0xc00002d0: return 0x213a;
case 0xc00002d1: return 0x27d;
case 0xc00002d2: return 0x27e;
case 0xc00002d3: return 0x15;
case 0xc00002d4: return 0x2141;
case 0xc00002d5: return 0x2142;
case 0xc00002d6: return 0x2143;
case 0xc00002d7: return 0x2144;
case 0xc00002d8: return 0x2145;
case 0xc00002d9: return 0x2146;
case 0xc00002da: return 0x2147;
case 0xc00002db: return 0x2148;
case 0xc00002dc: return 0x2149;
case 0xc00002dd: return 0x32;
case 0xc00002de: return 0x27f;
case 0xc00002df: return 0x2151;
case 0xc00002e0: return 0x2152;
case 0xc00002e1: return 0x2153;
case 0xc00002e2: return 0x2154;
case 0xc00002e3: return 0x215d;
case 0xc00002e4: return 0x2163;
case 0xc00002e5: return 0x2164;
case 0xc00002e6: return 0x2165;
case 0xc00002e7: return 0x216d;
case 0xc00002e8: return 0x280;
case 0xc00002e9: return 0x577;
case 0xc00002ea: return 0x52;
case 0xc00002eb: return 0x281;
case 0xc00002ec: return 0x2171;
case 0xc00002ed: return 0x2172;
case 0xc00002f0: return 0x2;
case 0xc00002fe: return 0x45b;
case 0xc00002ff: return 0x4e7;
case 0xc0000300: return 0x4e6;
case 0xc0000301: return 0x106f;
case 0xc0000302: return 0x1074;
case 0xc0000303: return 0x106e;
case 0xc0000304: return 0x12e;
case 0xc000030c: return 0x792;
case 0xc000030d: return 0x793;
case 0xc0000320: return 0x4ef;
case 0xc0000321: return 0x4f0;
case 0xc0000350: return 0x4e8;
case 0xc0000352: return 0x177d;
case 0xc0000353: return 0x282;
case 0xc0000354: return 0x504;
case 0xc0000355: return 0x283;
case 0xc0000357: return 0x217c;
case 0xc0000358: return 0x2182;
case 0xc0000359: return 0xc1;
case 0xc000035a: return 0xc1;
case 0xc000035c: return 0x572;
case 0xc000035d: return 0x4eb;
case 0xc000035f: return 0x286;
case 0xc0000361: return 0x4ec;
case 0xc0000362: return 0x4ec;
case 0xc0000363: return 0x4ec;
case 0xc0000364: return 0x4ec;
case 0xc0000365: return 0x287;
case 0xc0000366: return 0x288;
case 0xc0000368: return 0x289;
case 0xc0000369: return 0x28a;
case 0xc000036a: return 0x28b;
case 0xc000036b: return 0x4fb;
case 0xc000036c: return 0x4fb;
case 0xc000036d: return 0x28c;
case 0xc000036e: return 0x28d;
case 0xc000036f: return 0x4fc;
case 0xc0000371: return 0x21ac;
case 0xc0000372: return 0x312;
case 0xc0000373: return 0x8;
case 0xc0000374: return 0x54f;
case 0xc0000388: return 0x4f1;
case 0xc000038e: return 0x28e;
case 0xc0000401: return 0x78c;
case 0xc0000402: return 0x78d;
case 0xc0000403: return 0x78e;
case 0xc0000404: return 0x217b;
case 0xc0000405: return 0x219d;
case 0xc0000406: return 0x219f;
case 0xc0000407: return 0x28f;
case 0xc0000408: return 0x52e;
case 0xc0000409: return 0x502;
case 0xc0000410: return 0x503;
case 0xc0000411: return 0x290;
case 0xc0000412: return 0x505;
case 0xc0000413: return 0x78f;
case 0xc0000414: return 0x506;
case 0xc0000416: return 0x8;
case 0xc0000417: return 0x508;
case 0xc0000418: return 0x791;
case 0xc0000419: return 0x215b;
case 0xc000041a: return 0x21ba;
case 0xc000041b: return 0x21bb;
case 0xc000041c: return 0x21bc;
case 0xc000041d: return 0x2c9;
case 0xc0000420: return 0x29c;
case 0xc0000421: return 0x219;
case 0xc0000423: return 0x300;
case 0xc0000424: return 0x4fb;
case 0xc0000425: return 0x3fa;
case 0xc0000426: return 0x301;
case 0xc0000427: return 0x299;
case 0xc0000428: return 0x241;
case 0xc0000429: return 0x307;
case 0xc000042a: return 0x308;
case 0xc000042b: return 0x50c;
case 0xc000042c: return 0x2e4;
case 0xc0000432: return 0x509;
case 0xc0000433: return 0xaa;
case 0xc0000434: return 0xaa;
case 0xc0000435: return 0x4c8;
case 0xc0000441: return 0x1781;
case 0xc0000442: return 0x1782;
case 0xc0000443: return 0x1783;
case 0xc0000444: return 0x1784;
case 0xc0000445: return 0x1785;
case 0xc0000446: return 0x513;
case 0xc0000450: return 0x50b;
case 0xc0000451: return 0x3b92;
case 0xc0000452: return 0x3bc3;
case 0xc0000453: return 0x5bb;
case 0xc0000454: return 0x5be;
case 0xc0000455: return 0x6;
case 0xc0000456: return 0x57;
case 0xc0000457: return 0x57;
case 0xc0000458: return 0x57;
case 0xc0000459: return 0xbea;
case 0xc0000460: return 0x138;
case 0xc0000461: return 0x13a;
case 0xc0000462: return 0x3cfc;
case 0xc0000463: return 0x13c;
case 0xc0000464: return 0x141;
case 0xc0000465: return 0x13b;
case 0xc0000466: return 0x40;
case 0xc0000467: return 0x20;
case 0xc0000468: return 0x142;
case 0xc0000469: return 0x3d00;
case 0xc000046a: return 0x151;
case 0xc000046b: return 0x152;
case 0xc000046c: return 0x153;
case 0xc000046d: return 0x156;
case 0xc000046e: return 0x157;
case 0xc000046f: return 0x158;
case 0xc0000470: return 0x143;
case 0xc0000471: return 0x144;
case 0xc0000472: return 0x146;
case 0xc0000473: return 0x14b;
case 0xc0000474: return 0x147;
case 0xc0000475: return 0x148;
case 0xc0000476: return 0x149;
case 0xc0000477: return 0x14a;
case 0xc0000478: return 0x14c;
case 0xc0000479: return 0x14d;
case 0xc000047a: return 0x14e;
case 0xc000047b: return 0x14f;
case 0xc000047c: return 0x150;
case 0xc000047d: return 0x5b4;
case 0xc000047e: return 0x3d07;
case 0xc000047f: return 0x3d08;
case 0xc0000480: return 0x40;
case 0xc0000481: return 0x7e;
case 0xc0000482: return 0x7e;
case 0xc0000483: return 0x1e3;
case 0xc0000486: return 0x159;
case 0xc0000487: return 0x1f;
case 0xc0000488: return 0x15a;
case 0xc0000489: return 0x3d0f;
case 0xc000048a: return 0x32a;
case 0xc000048b: return 0x32c;
case 0xc000048c: return 0x15b;
case 0xc000048d: return 0x15c;
case 0xc000048e: return 0x162;
case 0xc000048f: return 0x15d;
case 0xc0000490: return 0x491;
case 0xc0000491: return 0x2;
case 0xc0000492: return 0x490;
case 0xc0000493: return 0x492;
case 0xc0000494: return 0x307;
case 0xc0000495: return 0x15;
case 0xc0000496: return 0x163;
case 0xc0000497: return 0x3d5a;
case 0xc0000499: return 0x167;
case 0xc000049a: return 0x168;
case 0xc000049b: return 0x12e;
case 0xc000049c: return 0x169;
case 0xc000049d: return 0x16f;
case 0xc000049e: return 0x170;
case 0xc000049f: return 0x49f;
case 0xc00004a0: return 0x4a0;
case 0xc00004a1: return 0x18f;
case 0xc0000500: return 0x60e;
case 0xc0000501: return 0x60f;
case 0xc0000502: return 0x610;
case 0xc0000503: return 0x15;
case 0xc0000504: return 0x13f;
case 0xc0000505: return 0x140;
case 0xc0000506: return 0x5bf;
case 0xc0000507: return 0xaa;
case 0xc0000508: return 0x5e0;
case 0xc0000509: return 0x5e1;
case 0xc000050b: return 0x112b;
case 0xc000050e: return 0x115c;
case 0xc000050f: return 0x10d3;
case 0xc0000510: return 0x4df;
case 0xc0000511: return 0x32e;
case 0xc0000512: return 0x5;
case 0xc0000513: return 0x180;
case 0xc0000514: return 0x115d;
case 0xc0000602: return 0x675;
case 0xc0000604: return 0x677;
case 0xc0000606: return 0x679;
case 0xc000060a: return 0x67c;
case 0xc000060b: return 0x67d;
case 0xc0000700: return 0x54f;
case 0xc0000701: return 0x54f;
case 0xc0000702: return 0x57;
case 0xc0000703: return 0x54f;
case 0xc0000704: return 0x32;
case 0xc0000705: return 0x57;
case 0xc0000706: return 0x57;
case 0xc0000707: return 0x32;
case 0xc0000708: return 0x54f;
case 0xc0000709: return 0x30b;
case 0xc000070a: return 0x6;
case 0xc000070b: return 0x6;
case 0xc000070c: return 0x6;
case 0xc000070d: return 0x6;
case 0xc000070e: return 0x6;
case 0xc000070f: return 0x6;
case 0xc0000710: return 0x1;
case 0xc0000711: return 0x1;
case 0xc0000712: return 0x50d;
case 0xc0000713: return 0x310;
case 0xc0000714: return 0x52e;
case 0xc0000715: return 0x5b7;
case 0xc0000716: return 0x7b;
case 0xc0000717: return 0x459;
case 0xc0000718: return 0x54f;
case 0xc0000719: return 0x54f;
case 0xc000071a: return 0x54f;
case 0xc000071b: return 0x1;
case 0xc000071c: return 0x57;
case 0xc000071d: return 0x1;
case 0xc000071e: return 0x1;
case 0xc000071f: return 0x1;
case 0xc0000720: return 0x1;
case 0xc0000721: return 0x1;
case 0xc0000722: return 0x72b;
case 0xc0000723: return 0x1f;
case 0xc0000724: return 0x1f;
case 0xc0000725: return 0x1f;
case 0xc0000726: return 0x1f;
case 0xc0000800: return 0x30c;
case 0xc0000801: return 0x21a4;
case 0xc0000802: return 0x50f;
case 0xc0000804: return 0x510;
case 0xc0000805: return 0x1ac1;
case 0xc0000806: return 0x1ac3;
case 0xc0000808: return 0x319;
case 0xc0000809: return 0x31a;
case 0xc000080a: return 0x31b;
case 0xc000080b: return 0x31c;
case 0xc000080c: return 0x31d;
case 0xc000080d: return 0x31e;
case 0xc000080e: return 0x31f;
case 0xc000080f: return 0x4d5;
case 0xc0000810: return 0x328;
case 0xc0000811: return 0x54f;
case 0xc0000901: return 0xdc;
case 0xc0000902: return 0xdd;
case 0xc0000903: return 0xde;
case 0xc0000904: return 0xdf;
case 0xc0000905: return 0xe0;
case 0xc0000906: return 0xe1;
case 0xc0000907: return 0xe2;
case 0xc0000908: return 0x317;
case 0xc0000909: return 0x322;
case 0xc0000910: return 0x326;
case 0xc0009898: return 0x29e;
case 0xc000a002: return 0x17;
case 0xc000a003: return 0x139f;
case 0xc000a004: return 0x154;
case 0xc000a005: return 0x155;
case 0xc000a006: return 0x32b;
case 0xc000a007: return 0x32;
case 0xc000a010: return 0xea;
case 0xc000a011: return 0xea;
case 0xc000a012: return 0x4d0;
case 0xc000a013: return 0x32;
case 0xc000a014: return 0x4d1;
case 0xc000a080: return 0x314;
case 0xc000a081: return 0x315;
case 0xc000a082: return 0x316;
case 0xc000a083: return 0x5b9;
case 0xc000a084: return 0x5ba;
case 0xc000a085: return 0x5bc;
case 0xc000a086: return 0x5bd;
case 0xc000a087: return 0x21bd;
case 0xc000a088: return 0x21be;
case 0xc000a089: return 0x21c6;
case 0xc000a100: return 0x3bc4;
case 0xc000a101: return 0x3bc5;
case 0xc000a121: return 0x3bd9;
case 0xc000a122: return 0x3bda;
case 0xc000a123: return 0x3bdb;
case 0xc000a124: return 0x3bdc;
case 0xc000a125: return 0x3bdd;
case 0xc000a126: return 0x3bde;
case 0xc000a141: return 0x3c28;
case 0xc000a142: return 0x3c29;
case 0xc000a143: return 0x3c2a;
case 0xc000a145: return 0x3c2b;
case 0xc000a146: return 0x3c2c;
case 0xc000a200: return 0x109a;
case 0xc000a201: return 0x109c;
case 0xc000a202: return 0x109d;
case 0xc000a203: return 0x5;
case 0xc000a281: return 0x1130;
case 0xc000a282: return 0x1131;
case 0xc000a283: return 0x1132;
case 0xc000a284: return 0x1133;
case 0xc000a285: return 0x1134;
case 0xc000a2a1: return 0x1158;
case 0xc000a2a2: return 0x1159;
case 0xc000a2a3: return 0x115a;
case 0xc000a2a4: return 0x115b;
case 0xc000ce01: return 0x171;
case 0xc000ce02: return 0x172;
case 0xc000ce03: return 0x173;
case 0xc000ce04: return 0x174;
case 0xc000ce05: return 0x181;
case 0xc000cf00: return 0x166;
case 0xc000cf01: return 0x16a;
case 0xc000cf02: return 0x16b;
case 0xc000cf03: return 0x16c;
case 0xc000cf06: return 0x177;
case 0xc000cf07: return 0x178;
case 0xc000cf08: return 0x179;
case 0xc000cf09: return 0x17a;
case 0xc000cf0a: return 0x17b;
case 0xc000cf0b: return 0x17c;
case 0xc000cf0c: return 0x17d;
case 0xc000cf0d: return 0x17e;
case 0xc000cf0e: return 0x17f;
case 0xc000cf0f: return 0x182;
case 0xc000cf10: return 0x183;
case 0xc000cf11: return 0x184;
case 0xc000cf12: return 0x185;
case 0xc000cf13: return 0x186;
case 0xc000cf14: return 0x187;
case 0xc000cf15: return 0x188;
case 0xc000cf16: return 0x189;
case 0xc000cf17: return 0x18a;
case 0xc000cf18: return 0x18b;
case 0xc000cf19: return 0x18c;
case 0xc000cf1a: return 0x18d;
case 0xc000cf1b: return 0x18e;
    }
    return static_cast<win32::DWORD>(-1);
  }
  //! Construct from a NT error code
  static _base::string_ref _make_string_ref(win32::NTSTATUS c) noexcept
  {
    wchar_t buffer[32768];
    static win32::HMODULE ntdll = win32::GetModuleHandleW(L"NTDLL.DLL");
    win32::DWORD wlen =
    win32::FormatMessageW(0x00000800 /*FORMAT_MESSAGE_FROM_HMODULE*/ | 0x00001000 /*FORMAT_MESSAGE_FROM_SYSTEM*/ | 0x00000200 /*FORMAT_MESSAGE_IGNORE_INSERTS*/,
                          ntdll, c, (1 << 10) /*MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)*/, buffer, 32768, nullptr);
    size_t allocation = wlen + (wlen >> 1);
    win32::DWORD bytes;
    if(wlen == 0)
    {
      return _base::string_ref("failed to get message from system");
    }
    for(;;)
    {
      auto *p = static_cast<char *>(malloc(allocation)); // NOLINT
      if(p == nullptr)
      {
        return _base::string_ref("failed to get message from system");
      }
      bytes = win32::WideCharToMultiByte(65001 /*CP_UTF8*/, 0, buffer, (int) (wlen + 1), p, (int) allocation, nullptr, nullptr);
      if(bytes != 0)
      {
        char *end = strchr(p, 0);
        while(end[-1] == 10 || end[-1] == 13)
        {
          --end;
        }
        *end = 0; // NOLINT
        return _base::atomic_refcounted_string_ref(p, end - p);
      }
      free(p); // NOLINT
      if(win32::GetLastError() == 0x7a /*ERROR_INSUFFICIENT_BUFFER*/)
      {
        allocation += allocation >> 2;
        continue;
      }
      return _base::string_ref("failed to get message from system");
    }
  }
public:
  //! The value type of the NT code, which is a `win32::NTSTATUS`
  using value_type = win32::NTSTATUS;
  using _base::string_ref;
public:
  //! Default constructor
  constexpr explicit _nt_code_domain(typename _base::unique_id_type id = 0x93f3b4487e4af25b) noexcept
      : _base(id)
  {
  }
  _nt_code_domain(const _nt_code_domain &) = default;
  _nt_code_domain(_nt_code_domain &&) = default;
  _nt_code_domain &operator=(const _nt_code_domain &) = default;
  _nt_code_domain &operator=(_nt_code_domain &&) = default;
  ~_nt_code_domain() = default;
  //! Constexpr singleton getter. Returns the constexpr nt_code_domain variable.
  static inline constexpr const _nt_code_domain &get();
  virtual string_ref name() const noexcept override { return string_ref("NT domain"); } // NOLINT
  virtual payload_info_t payload_info() const noexcept override
  {
    return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
            (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
  }
protected:
  virtual bool _do_failure(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this);
    return static_cast<const nt_code &>(code).value() < 0; // NOLINT
  }
  virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override // NOLINT
  {
    assert(code1.domain() == *this);
    const auto &c1 = static_cast<const nt_code &>(code1); // NOLINT
    if(code2.domain() == *this)
    {
      const auto &c2 = static_cast<const nt_code &>(code2); // NOLINT
      return c1.value() == c2.value();
    }
    if(code2.domain() == generic_code_domain)
    {
      const auto &c2 = static_cast<const generic_code &>(code2); // NOLINT
      if(static_cast<int>(c2.value()) == _nt_code_to_errno(c1.value()))
      {
        return true;
      }
    }
    if(code2.domain() == win32_code_domain)
    {
      const auto &c2 = static_cast<const win32_code &>(code2); // NOLINT
      if(c2.value() == _nt_code_to_win32_code(c1.value()))
      {
        return true;
      }
    }
    return false;
  }
  virtual generic_code _generic_code(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this);
    const auto &c = static_cast<const nt_code &>(code); // NOLINT
    return generic_code(static_cast<errc>(_nt_code_to_errno(c.value())));
  }
  virtual string_ref _do_message(const status_code<void> &code) const noexcept override // NOLINT
  {
    assert(code.domain() == *this);
    const auto &c = static_cast<const nt_code &>(code); // NOLINT
    return _make_string_ref(c.value());
  }
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || 0L
  SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override // NOLINT
  {
    assert(code.domain() == *this);
    const auto &c = static_cast<const nt_code &>(code); // NOLINT
    throw status_error<_nt_code_domain>(c);
  }
#endif
};
//! (Windows only) A constexpr source variable for the NT code domain, which is that of NT kernel functions. Returned by `_nt_code_domain::get()`.
constexpr _nt_code_domain nt_code_domain;
inline constexpr const _nt_code_domain &_nt_code_domain::get()
{
  return nt_code_domain;
}
SYSTEM_ERROR2_NAMESPACE_END
#endif
// NOT "com_code.hpp"
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
/*! An erased-mutable status code suitably large for all the system codes
which can be returned on this system.

For Windows, these might be:

    - `com_code` (`HRESULT`)  [you need to include "com_code.hpp" explicitly for this]
    - `nt_code` (`LONG`)
    - `win32_code` (`DWORD`)

For POSIX, `posix_code` is possible.

You are guaranteed that `system_code` can be transported by the compiler
in exactly two CPU registers.
*/
using system_code = erased_status_code<intptr_t>;
#ifndef NDEBUG
static_assert(sizeof(system_code) == 2 * sizeof(void *), "system_code is not exactly two pointers in size!");
static_assert(traits::is_move_bitcopying<system_code>::value, "system_code is not move bitcopying!");
#endif
SYSTEM_ERROR2_NAMESPACE_END
#endif
SYSTEM_ERROR2_NAMESPACE_BEGIN
/*! An errored `system_code` which is always a failure. The closest equivalent to
`std::error_code`, except it cannot be null and cannot be modified.

This refines `system_code` into an `error` object meeting the requirements of
[P0709 Zero-overhead deterministic exceptions](https://wg21.link/P0709).

Differences from `system_code`:

- Always a failure (this is checked at construction, and if not the case,
the program is terminated as this is a logic error)
- No default construction.
- No empty state possible.
- Is immutable.

As with `system_code`, it remains guaranteed to be two CPU registers in size,
and move bitcopying.
*/
using error = erased_errored_status_code<system_code::value_type>;
#ifndef NDEBUG
static_assert(sizeof(error) == 2 * sizeof(void *), "error is not exactly two pointers in size!");
static_assert(traits::is_move_bitcopying<error>::value, "error is not move bitcopying!");
#endif
SYSTEM_ERROR2_NAMESPACE_END
#endif
#endif
