diff --git a/include/magic_enum_format.hpp b/include/magic_enum_format.hpp new file mode 100644 index 0000000..ec91c47 --- /dev/null +++ b/include/magic_enum_format.hpp @@ -0,0 +1,79 @@ +// __ __ _ ______ _____ +// | \/ | (_) | ____| / ____|_ _ +// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ +// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| +// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| +// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| +// __/ | https://github.com/Neargye/magic_enum +// |___/ version 0.8.0 +// +// Licensed under the MIT License . +// SPDX-License-Identifier: MIT +// Copyright (c) 2019 - 2022 Daniil Goncharov . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef NEARGYE_MAGIC_ENUM_FORMAT_HPP +#define NEARGYE_MAGIC_ENUM_FORMAT_HPP + +#ifndef __cpp_lib_format +# error "Format is not supported" +#endif + +#include "magic_enum.hpp" + +#ifndef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT +# define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT true +# define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE +#endif // MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT + +namespace magic_enum::customize { + // customize enum to enable/disable automatic std::format + template + constexpr bool enum_format_enabled() noexcept { + return MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT; + } +} // magic_enum::customize + +#include + +template +struct std::formatter && magic_enum::customize::enum_format_enabled(), char>> : std::formatter { + auto format(E e, format_context& ctx) { + if constexpr (magic_enum::detail::is_flags_v) { + if (auto name = magic_enum::enum_flags_name(e); !name.empty()) { + return this->std::formatter::format(std::string_view{name.data(), name.size()}, ctx); + } + } else { + if (auto name = magic_enum::enum_name(e); !name.empty()) { + return this->std::formatter::format(std::string_view{name.data(), name.size()}, ctx); + } + } + constexpr auto type_name = magic_enum::enum_type_name(); + throw std::format_error("Type of " + std::string{type_name.data(), type_name.size()} + " enum value: " + + std::to_string(magic_enum::enum_integer(e)) + " is not exists."); + } +}; + +#ifdef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE +# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT +# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE +#endif // MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE + +#endif // NEARGYE_MAGIC_ENUM_FORMAT_HPP diff --git a/test/test.cpp b/test/test.cpp index 84967c3..b6a3276 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1201,3 +1201,13 @@ TEST_CASE("multdimensional-switch-case") { } #endif + +#ifdef __cpp_lib_format + +#include + +TEST_CASE("format-base") { + REQUIRE(std::format("Test-{:~^10}.", Color::RED) == "Test-~~~red~~~~."); +} + +#endif \ No newline at end of file diff --git a/test/test_flags.cpp b/test/test_flags.cpp index 0c14a5d..29626c2 100644 --- a/test/test_flags.cpp +++ b/test/test_flags.cpp @@ -822,3 +822,13 @@ TEST_CASE("constexpr_for") { } #endif + +#ifdef __cpp_lib_format + +#include + +TEST_CASE("format-base") { + REQUIRE(std::format("Test-{:~^11}.", Color::RED | Color::GREEN) == "Test-~RED|GREEN~."); +} + +#endif \ No newline at end of file