Files
enum.hpp/README.md
2019-11-22 04:21:27 +07:00

5.2 KiB

enum.hpp

travis appveyor codecov language license paypal

Requirements

Installation

enum.hpp is a header-only library. All you need to do is copy the headers files from headers directory into your project and include them:

#include "enum.hpp/enum.hpp"

Also, you can add the root repository directory to your cmake project:

add_subdirectory(external/enum.hpp)
target_link_libraries(your_project_target enum.hpp)

Examples

Declarations

ENUM_HPP_DECL(debug_level, int,
    (level_info)
    (level_warning)
    (level_error))

// equivalent to:

enum debug_level : int {
    level_info,
    level_warning,
    level_error,
};

struct debug_level_traits {
    using underlying_type = int;
    static constexpr std::size_t size = 3;

    static constexpr const debug_level values[] = {
        level_info,
        level_warning,
        level_warning
    };

    static constexpr const std::string_view names[] = {
        "level_info",
        "level_warning",
        "level_warning"
    };

    static constexpr underlying_type to_underlying(debug_level e) noexcept;

    static constexpr std::optional<std::string_view> to_string(debug_level e) noexcept;
    static constexpr std::optional<debug_level> from_string(std::string_view name) noexcept;

    static constexpr std::optional<std::size_t> to_index(debug_level e) noexcept;
    static constexpr std::optional<debug_level> from_index(std::size_t index) noexcept;
};
ENUM_HPP_CLASS_DECL(color, unsigned,
    (red = 1 << 0)
    (green = 1 << 1)
    (blue = 1 << 2)
    (white = red | green | blue))

// equivalent to:

enum class color : unsigned {
    red = 1 << 0,
    green = 1 << 1,
    blue = 1 << 2,
    white = red | green | blue,
};

struct color_traits {
    using underlying_type = unsigned;
    static constexpr std::size_t size = 4;

    static constexpr const color values[] = {
        color::red,
        color::green,
        color::blue,
        color::white
    };

    static constexpr const std::string_view names[] = {
        "red",
        "green",
        "blue",
        "white"
    };

    static constexpr underlying_type to_underlying(color e) noexcept;

    static constexpr std::optional<std::string_view> to_string(color e) noexcept;
    static constexpr std::optional<color> from_string(std::string_view name) noexcept;

    static constexpr std::optional<std::size_t> to_index(color e) noexcept;
    static constexpr std::optional<color> from_index(std::size_t index) noexcept;
};

Traits using

namespace
{
    ENUM_HPP_CLASS_DECL(color, unsigned,
        (red = 0xFF0000)
        (green = 0x00FF00)
        (blue = 0x0000FF)
        (white = red | green | blue))
}

SECTION("traits_using") {
    // size
    STATIC_REQUIRE(color_traits::size == 4);

    // to_underlying
    STATIC_REQUIRE(color_traits::to_underlying(color::white) == 0xFFFFFF);

    // to_string
    STATIC_REQUIRE(color_traits::to_string(color::red) == "red");
    STATIC_REQUIRE(color_traits::to_string(color(42)) == std::nullopt);

    // from_string
    STATIC_REQUIRE(color_traits::from_string("green") == color::green);
    STATIC_REQUIRE(color_traits::from_string("error") == std::nullopt);

    // to_index
    STATIC_REQUIRE(color_traits::to_index(color::blue) == 2);
    STATIC_REQUIRE(color_traits::to_index(color(42)) == std::nullopt);

    // from_index
    STATIC_REQUIRE(color_traits::from_index(2) == color::blue);
    STATIC_REQUIRE(color_traits::from_index(42) == std::nullopt);

    // names
    for ( auto n : color_traits::names ) {
        std::cout << n << ",";
    } // stdout: red,green,blue,
}

Alternatives

Better Enums

  • Low variadic macros limit (64)
  • Replaces C++ enum semantics to custom class

wise_enum

Magic Enum

  • Amazing but requires at least GCC 9.0

License (MIT)