1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-09 23:34:23 +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:
build:
runs-on: ${{matrix.config.os}}
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
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-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:
- uses: actions/checkout@v3

View file

@ -32,7 +32,7 @@ jobs:
- name: Configure clang
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 -
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"
@ -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 main"
sudo apt update
sudo apt install ${{matrix.compiler.cc}} -y
sudo apt install ${{ matrix.compiler.cc }} -y
fi
- name: Configure gcc
run: |
if [[ "${{matrix.compiler.cc}}" == "gcc"* ]]; then
if [[ "${{ matrix.compiler.cc }}" == "gcc"* ]]; then
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt update
sudo apt install ${{matrix.compiler.cxx}} -y
sudo apt install ${{ matrix.compiler.cxx }} -y
fi
- name: Build Release
@ -60,7 +60,7 @@ jobs:
rm -rf build
mkdir 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
ctest --output-on-failure -C Release
@ -69,7 +69,7 @@ jobs:
rm -rf build
mkdir 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
ctest --output-on-failure -C Debug

View file

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

View file

@ -32,14 +32,10 @@
#ifndef 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"
#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
#endif // MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT
@ -51,23 +47,48 @@ namespace magic_enum::customize {
}
} // magic_enum::customize
#if defined(__cpp_lib_format)
#include <format>
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 {
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 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)
# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT
# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE

View file

@ -44,17 +44,16 @@ make_test(test_aliases.cpp test_aliases-cpp17 c++17)
make_test(test_containers.cpp test_containers-cpp17 c++17)
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()
if(HAS_CPP20_FLAG)
make_test(test.cpp test-cpp20 c++20)
make_test(test_flags.cpp test_flags-cpp20 c++20)
make_test(test_aliases.cpp test_aliases-cpp20 c++20)
make_test(test_containers.cpp test_containers-cpp20 c++20)
if(MAGIC_ENUM_OPT_ENABLE_NONASCII)
make_test(test_nonascii.cpp test_nonascii-cpp20 c++20)
make_test(test_nonascii.cpp test_nonascii-cpp20 c++20)
endif()
endif()
@ -64,7 +63,7 @@ if(HAS_CPP23_FLAG)
make_test(test_aliases.cpp test_aliases-cpp23 c++23)
make_test(test_containers.cpp test_containers-cpp23 c++23)
if(MAGIC_ENUM_OPT_ENABLE_NONASCII)
make_test(test_nonascii.cpp test_nonascii-cpp23 c++23)
make_test(test_nonascii.cpp test_nonascii-cpp23 c++23)
endif()
endif()
@ -74,6 +73,6 @@ if(HAS_CPPLATEST_FLAG)
make_test(test_aliases.cpp test_aliases-cpplatest c++latest)
make_test(test_containers.cpp test_containers-cpplatest c++latest)
if(MAGIC_ENUM_OPT_ENABLE_NONASCII)
make_test(test_nonascii.cpp test_nonascii-cpplatest c++latest)
make_test(test_nonascii.cpp test_nonascii-cpplatest c++latest)
endif()
endif()

View file

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