1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-10 23:44:29 +00:00

add fmt support

This commit is contained in:
neargye 2023-05-19 19:36:50 +04:00
parent 5367f5183c
commit 737ed4fc7f
6 changed files with 42 additions and 27 deletions

View file

@ -6,7 +6,7 @@ permissions: read-all
jobs: jobs:
build: build:
runs-on: ${{matrix.config.os}} runs-on: ${{ matrix.config.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -14,7 +14,7 @@ jobs:
- { os: macos-11 } # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md#xcode - { os: macos-11 } # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md#xcode
- { os: macos-12 } # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-12-Readme.md#xcode - { os: macos-12 } # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-12-Readme.md#xcode
name: "${{matrix.config.os}}" name: "${{ matrix.config.os }}"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View file

@ -32,7 +32,7 @@ jobs:
- name: Configure clang - name: Configure clang
run: | run: |
if [[ "${{matrix.compiler.cc}}" == "clang"* ]]; then if [[ "${{ matrix.compiler.cc }}" == "clang"* ]]; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main" sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main"
sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main" sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main"
@ -44,15 +44,15 @@ jobs:
sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main" sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main"
sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main"
sudo apt update sudo apt update
sudo apt install ${{matrix.compiler.cc}} -y sudo apt install ${{ matrix.compiler.cc }} -y
fi fi
- name: Configure gcc - name: Configure gcc
run: | run: |
if [[ "${{matrix.compiler.cc}}" == "gcc"* ]]; then if [[ "${{ matrix.compiler.cc }}" == "gcc"* ]]; then
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt update sudo apt update
sudo apt install ${{matrix.compiler.cxx}} -y sudo apt install ${{ matrix.compiler.cxx }} -y
fi fi
- name: Build Release - name: Build Release
@ -60,7 +60,7 @@ jobs:
rm -rf build rm -rf build
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}} -DMAGIC_ENUM_OPT_ENABLE_NONASCII:BOOL=${{matrix.compiler.nonascii}} cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} -DMAGIC_ENUM_OPT_ENABLE_NONASCII:BOOL=${{ matrix.compiler.nonascii }}
cmake --build . -j 4 --config Release cmake --build . -j 4 --config Release
ctest --output-on-failure -C Release ctest --output-on-failure -C Release
@ -69,7 +69,7 @@ jobs:
rm -rf build rm -rf build
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}} -DMAGIC_ENUM_OPT_ENABLE_NONASCII:BOOL=${{matrix.compiler.nonascii}} cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} -DMAGIC_ENUM_OPT_ENABLE_NONASCII:BOOL=${{ matrix.compiler.nonascii }}
cmake --build . -j 4 --config Debug cmake --build . -j 4 --config Debug
ctest --output-on-failure -C Debug ctest --output-on-failure -C Debug

View file

@ -6,7 +6,7 @@ permissions: read-all
jobs: jobs:
build: build:
runs-on: ${{matrix.config.os}} runs-on: ${{ matrix.config.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View file

@ -32,14 +32,10 @@
#ifndef NEARGYE_MAGIC_ENUM_FORMAT_HPP #ifndef NEARGYE_MAGIC_ENUM_FORMAT_HPP
#define NEARGYE_MAGIC_ENUM_FORMAT_HPP #define NEARGYE_MAGIC_ENUM_FORMAT_HPP
#if !defined(__cpp_lib_format)
# error "Format is not supported"
#endif
#include "magic_enum.hpp" #include "magic_enum.hpp"
#if !defined(MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT) #if !defined(MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT)
# define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT true # define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT 1
# define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE # define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE
#endif // MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT #endif // MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT
@ -51,23 +47,48 @@ namespace magic_enum::customize {
} }
} // magic_enum::customize } // magic_enum::customize
#if defined(__cpp_lib_format)
#include <format> #include <format>
template <typename E> template <typename E>
struct std::formatter<E, std::enable_if_t<std::is_enum_v<E> && magic_enum::customize::enum_format_enabled<E>(), char>> : std::formatter<std::string_view, char> { struct std::formatter<E, std::enable_if_t<std::is_enum_v<std::decay_t<E>> && magic_enum::customize::enum_format_enabled<E>(), char>> : std::formatter<std::string_view, char> {
auto format(E e, format_context& ctx) const { auto format(E e, format_context& ctx) const {
static_assert(std::is_same_v<char, string_view::value_type>, "formatter requires string_view::value_type type same as char."); static_assert(std::is_same_v<char, string_view::value_type>, "formatter requires string_view::value_type type same as char.");
using D = std::decay_t<E>; using D = std::decay_t<E>;
if constexpr (magic_enum::detail::supported<D>::value) { if constexpr (magic_enum::detail::supported<D>::value) {
if (const auto name = magic_enum::enum_name<D, magic_enum::as_flags<magic_enum::detail::is_flags_v<D>>>(e); !name.empty()) { if (const auto name = magic_enum::enum_name<D, magic_enum::as_flags<magic_enum::detail::is_flags_v<D>>>(e); !name.empty()) {
return std::formatter<std::string_view, char>::format(std::string_view{name.data(), name.size()}, ctx); return formatter<std::string_view, char>::format(std::string_view{name.data(), name.size()}, ctx);
} }
} }
return std::formatter<std::string_view, char>::format(std::to_string(magic_enum::enum_integer<D>(e)), ctx); return formatter<std::string_view, char>::format(std::to_string(magic_enum::enum_integer<D>(e)), ctx);
} }
}; };
#endif // MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT
#if defined(FMT_VERSION)
#include <fmt/format.h>
template <typename E>
struct fmt::formatter<E, std::enable_if_t<std::is_enum_v<std::decay_t<E>> && magic_enum::customize::enum_format_enabled<E>(), char>> : fmt::formatter<std::string_view, char> {
auto format(E e, format_context& ctx) {
static_assert(std::is_same_v<char, string_view::value_type>, "formatter requires string_view::value_type type same as char.");
using D = std::decay_t<E>;
if constexpr (magic_enum::detail::supported<D>::value) {
if (const auto name = magic_enum::enum_name<D, magic_enum::as_flags<magic_enum::detail::is_flags_v<D>>>(e); !name.empty()) {
return formatter<std::string_view, char>::format(std::string_view{name.data(), name.size()}, ctx);
}
}
return formatter<std::string_view, char>::format(std::to_string(magic_enum::enum_integer<D>(e)), ctx);
}
};
#endif // FMT_VERSION
#if defined(MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE) #if defined(MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE)
# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT # undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT
# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE # undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE

View file

@ -47,7 +47,6 @@ if(MAGIC_ENUM_OPT_ENABLE_NONASCII)
make_test(test_nonascii.cpp test_nonascii-cpp17 c++17) make_test(test_nonascii.cpp test_nonascii-cpp17 c++17)
endif() endif()
if(HAS_CPP20_FLAG) if(HAS_CPP20_FLAG)
make_test(test.cpp test-cpp20 c++20) make_test(test.cpp test-cpp20 c++20)
make_test(test_flags.cpp test_flags-cpp20 c++20) make_test(test_flags.cpp test_flags-cpp20 c++20)

View file

@ -128,13 +128,11 @@ TEST_CASE("enum_cast") {
REQUIRE(enum_cast<Directions>("Left").value() == Directions::Left); REQUIRE(enum_cast<Directions>("Left").value() == Directions::Left);
REQUIRE_FALSE(enum_cast<Directions>("None").has_value()); REQUIRE_FALSE(enum_cast<Directions>("None").has_value());
#if !defined(MAGIC_ENUM_ENABLE_NONASCII)
constexpr auto dr2 = enum_cast<Directions>("RIGHT", case_insensitive); constexpr auto dr2 = enum_cast<Directions>("RIGHT", case_insensitive);
REQUIRE(dr2.value() == Directions::Right); REQUIRE(dr2.value() == Directions::Right);
REQUIRE(enum_cast<Directions&>("up", case_insensitive).value() == Directions::Up); REQUIRE(enum_cast<Directions&>("up", case_insensitive).value() == Directions::Up);
REQUIRE(enum_cast<const Directions>("dOwN", case_insensitive).value() == Directions::Down); REQUIRE(enum_cast<const Directions>("dOwN", case_insensitive).value() == Directions::Down);
REQUIRE_FALSE(enum_cast<Directions>("Left-", case_insensitive).has_value()); REQUIRE_FALSE(enum_cast<Directions>("Left-", case_insensitive).has_value());
#endif
constexpr auto nt = enum_cast<number>("three"); constexpr auto nt = enum_cast<number>("three");
REQUIRE(enum_cast<number>("one").value() == number::one); REQUIRE(enum_cast<number>("one").value() == number::one);
@ -350,13 +348,11 @@ TEST_CASE("enum_contains") {
REQUIRE(enum_contains<Directions>("Left")); REQUIRE(enum_contains<Directions>("Left"));
REQUIRE_FALSE(enum_contains<Directions>("None")); REQUIRE_FALSE(enum_contains<Directions>("None"));
#if !defined(MAGIC_ENUM_ENABLE_NONASCII)
auto dr2 = std::string{"RIGHT"}; auto dr2 = std::string{"RIGHT"};
REQUIRE(enum_contains<const Directions>(dr2, case_insensitive)); REQUIRE(enum_contains<const Directions>(dr2, case_insensitive));
REQUIRE(enum_contains<Directions&>("up", case_insensitive)); REQUIRE(enum_contains<Directions&>("up", case_insensitive));
REQUIRE(enum_contains<Directions>("dOwN", case_insensitive)); REQUIRE(enum_contains<Directions>("dOwN", case_insensitive));
REQUIRE_FALSE(enum_contains<Directions>("Left-", case_insensitive)); REQUIRE_FALSE(enum_contains<Directions>("Left-", case_insensitive));
#endif
constexpr auto nt = enum_contains<number>("three"); constexpr auto nt = enum_contains<number>("three");
REQUIRE(enum_contains<number>("one")); REQUIRE(enum_contains<number>("one"));
@ -1018,7 +1014,6 @@ TEST_CASE("multdimensional-switch-case") {
TEST_CASE("format-base") { TEST_CASE("format-base") {
REQUIRE(std::format("{}", Color::RED) == "red"); REQUIRE(std::format("{}", Color::RED) == "red");
REQUIRE(std::format("{}", Color{0}) == "0"); REQUIRE(std::format("{}", Color{0}) == "0");
REQUIRE(std::format("Test-{:~^10}.", Color::RED) == "Test-~~~red~~~~.");
} }
#endif #endif