#include <iostream>
#include <type_traits>
#include <map>
template <typename E>
struct enum_traits
{
static const char* const name;
static const std::map<E, std::string> mapping;
};
template <typename E>
struct ECategory_impl : std::error_category
{
static_assert(std::is_enum<E>::value, "!");
const char* name() const noexcept override
{
return enum_traits<E>::name;
}
std::string message(int c) const override
{
const auto& Map = enum_traits<E>::mapping;
E code = static_cast<E>(c);
auto itr = Map.find(code);
if (itr != Map.end())
{
return itr->second;
}
else
{
return "(unrecognized error)";
}
}
};
template <typename E>
std::error_code make_error_code(E e)
{
static_assert(std::is_enum<E>::value, "!");
static const ECategory_impl<E> categ{};
return {static_cast<int>(e), categ};
}
#define MAKE_ERROR_CODE_CATEGORY(E) \
template <> const char* const enum_traits<E>::name = #E; \
namespace std \
{ \
template <> \
struct is_error_code_enum<E> : true_type {}; \
} \
using E##_category = ECategory_impl<E>;
enum class E {A, B};
template <> const std::map<E, std::string> enum_traits<E>::mapping
{
{E::A, "A"},
{E::B, "E::B"}
};
MAKE_ERROR_CODE_CATEGORY(E)
int main()
{
auto ec = make_error_code(E::A);
static_cast<void>(ec);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxtYXA+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRT4Kc3RydWN0IGVudW1fdHJhaXRzCnsKICAgIHN0YXRpYyBjb25zdCBjaGFyKiBjb25zdCBuYW1lOwogICAgc3RhdGljIGNvbnN0IHN0ZDo6bWFwPEUsIHN0ZDo6c3RyaW5nPiBtYXBwaW5nOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEU+CnN0cnVjdCBFQ2F0ZWdvcnlfaW1wbCA6IHN0ZDo6ZXJyb3JfY2F0ZWdvcnkKewogICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX2VudW08RT46OnZhbHVlLCAiISIpOwogICAgCiAgICBjb25zdCBjaGFyKiBuYW1lKCkgY29uc3Qgbm9leGNlcHQgb3ZlcnJpZGUKICAgIHsKICAgICAgcmV0dXJuIGVudW1fdHJhaXRzPEU+OjpuYW1lOwogICAgfQoKICAgIHN0ZDo6c3RyaW5nIG1lc3NhZ2UoaW50IGMpIGNvbnN0IG92ZXJyaWRlCiAgICB7CiAgICAgICAgY29uc3QgYXV0byYgTWFwID0gZW51bV90cmFpdHM8RT46Om1hcHBpbmc7CiAgICAgICAgRSBjb2RlID0gc3RhdGljX2Nhc3Q8RT4oYyk7CiAgICAgICAgYXV0byBpdHIgPSBNYXAuZmluZChjb2RlKTsKICAgICAgICBpZiAoaXRyICE9IE1hcC5lbmQoKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBpdHItPnNlY29uZDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICIodW5yZWNvZ25pemVkIGVycm9yKSI7CiAgICAgICAgfQogICAgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEU+CnN0ZDo6ZXJyb3JfY29kZSBtYWtlX2Vycm9yX2NvZGUoRSBlKQp7CiAgICBzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfZW51bTxFPjo6dmFsdWUsICIhIik7CiAgICBzdGF0aWMgY29uc3QgRUNhdGVnb3J5X2ltcGw8RT4gY2F0ZWd7fTsKICAgIHJldHVybiB7c3RhdGljX2Nhc3Q8aW50PihlKSwgY2F0ZWd9Owp9CgojZGVmaW5lIE1BS0VfRVJST1JfQ09ERV9DQVRFR09SWShFKSBcCiAgICAgdGVtcGxhdGUgPD4gY29uc3QgY2hhciogY29uc3QgZW51bV90cmFpdHM8RT46Om5hbWUgPSAjRTsgXApuYW1lc3BhY2Ugc3RkIFwKeyBcCiAgICB0ZW1wbGF0ZSA8PiBcCiAgICBzdHJ1Y3QgaXNfZXJyb3JfY29kZV9lbnVtPEU+IDogdHJ1ZV90eXBlIHt9OyBcCn0gXAp1c2luZyBFIyNfY2F0ZWdvcnkgPSBFQ2F0ZWdvcnlfaW1wbDxFPjsKCmVudW0gY2xhc3MgRSB7QSwgQn07CnRlbXBsYXRlIDw+IGNvbnN0IHN0ZDo6bWFwPEUsIHN0ZDo6c3RyaW5nPiBlbnVtX3RyYWl0czxFPjo6bWFwcGluZwp7CiAgICB7RTo6QSwgIkEifSwKICAgIHtFOjpCLCAiRTo6QiJ9Cn07CgpNQUtFX0VSUk9SX0NPREVfQ0FURUdPUlkoRSkKCmludCBtYWluKCkKewogICAgYXV0byBlYyA9IG1ha2VfZXJyb3JfY29kZShFOjpBKTsKICAgIHN0YXRpY19jYXN0PHZvaWQ+KGVjKTsKfQo=