add support for non-ASCII characters (UNIX/Linux)

This commit is contained in:
neargye 2022-05-18 17:34:03 +04:00
parent b5deb0055c
commit aeb37e86cf
7 changed files with 95 additions and 6 deletions

View file

@ -8,6 +8,7 @@ else()
set(IS_TOPLEVEL_PROJECT FALSE)
endif()
option(NAMEOF_OPT_ENABLE_NONASCII "Enable support for non-ASCII identifier" ${IS_TOPLEVEL_PROJECT})
option(NAMEOF_OPT_BUILD_EXAMPLES "Build nameof examples" ${IS_TOPLEVEL_PROJECT})
option(NAMEOF_OPT_BUILD_TESTS "Build and perform nameof tests" ${IS_TOPLEVEL_PROJECT})
option(NAMEOF_OPT_INSTALL "Generate and install nameof target" ${IS_TOPLEVEL_PROJECT})

View file

@ -41,6 +41,12 @@
#include <nameof.hpp>
```
* To add support for non-ASCII enumeration identifier, use special macros:
```cpp
#define NAMEOF_ENABLE_NONASCII
#include <nameof.hpp>
```
## `NAMEOF`
* Obtains simple (unqualified) name of variable, function, macro.

View file

@ -19,3 +19,12 @@ endfunction()
make_example(example)
make_example(example_custom_name)
if(NAMEOF_OPT_ENABLE_NONASCII)
if(((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(OPTIONS ${OPTIONS} -DMAGIC_ENUM_ENABLE_NONASCII)
make_example(example_nonascii_name)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC"))
message(WARNING "Non-ASCII feature on Windows is not supported yet")
endif()
endif()

View file

@ -0,0 +1,44 @@
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 - 2022 Daniil Goncharov <neargye@gmail.com>.
//
// 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.
#include <iostream>
#include <nameof.hpp>
enum class Language : int {
= 10,
= 20,
English = 30,
😃 = 40,
};
int main() {
std::cout << NAMEOF_ENUM(Language::) << std::endl; // Japanese
std::cout << NAMEOF_ENUM(Language::) << std::endl; // Korean
std::cout << NAMEOF_ENUM(Language::English) << std::endl; // English
std::cout << NAMEOF_ENUM(Language::😃) << std::endl; // Emoji
int 😃 = 42;
std::cout << NAMEOF(😃) << std::endl; // Emoji
return 0;
}

View file

@ -449,6 +449,9 @@ constexpr string_view pretty_name(string_view name, bool remove_suffix = true) n
if (!((name[i - 1] >= '0' && name[i - 1] <= '9') ||
(name[i - 1] >= 'a' && name[i - 1] <= 'z') ||
(name[i - 1] >= 'A' && name[i - 1] <= 'Z') ||
#if defined(NAMEOF_ENABLE_NONASCII)
(name[i - 1] & 0x80) ||
#endif
(name[i - 1] == '_'))) {
name.remove_prefix(i);
break;
@ -460,6 +463,9 @@ constexpr string_view pretty_name(string_view name, bool remove_suffix = true) n
if (name.size() > 0 && ((name.front() >= 'a' && name.front() <= 'z') ||
(name.front() >= 'A' && name.front() <= 'Z') ||
#if defined(NAMEOF_ENABLE_NONASCII)
(name.front() & 0x80) ||
#endif
(name.front() == '_'))) {
return name;
}
@ -1084,18 +1090,18 @@ template <auto V>
// Obtains type name, reference and cv-qualifiers are ignored.
#define NAMEOF_TYPE(...) ::nameof::nameof_type<__VA_ARGS__>()
// Obtains type name of expression, reference and cv-qualifiers are ignored.
#define NAMEOF_TYPE_EXPR(...) ::nameof::nameof_type<decltype(__VA_ARGS__)>()
// Obtains full type name, with reference and cv-qualifiers.
#define NAMEOF_FULL_TYPE(...) ::nameof::nameof_full_type<__VA_ARGS__>()
// Obtains full type name of expression, with reference and cv-qualifiers.
#define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type<decltype(__VA_ARGS__)>()
// Obtains short type name.
#define NAMEOF_SHORT_TYPE(...) ::nameof::nameof_short_type<__VA_ARGS__>()
// Obtains type name of expression, reference and cv-qualifiers are ignored.
#define NAMEOF_TYPE_EXPR(...) ::nameof::nameof_type<decltype(__VA_ARGS__)>()
// Obtains full type name of expression, with reference and cv-qualifiers.
#define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type<decltype(__VA_ARGS__)>()
// Obtains short type name of expression.
#define NAMEOF_SHORT_TYPE_EXPR(...) ::nameof::nameof_short_type<decltype(__VA_ARGS__)>()

View file

@ -18,6 +18,14 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
check_cxx_compiler_flag(-std=c++20 HAS_CPP20_FLAG)
endif()
if(NAMEOF_OPT_ENABLE_NONASCII)
if(((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0) OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(OPTIONS ${OPTIONS} -DMAGIC_ENUM_ENABLE_NONASCII)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC"))
message(WARNING "Non-ASCII feature on Windows is not supported yet")
endif()
endif()
function(make_test target std)
add_executable(${target} ${SOURCES})
target_compile_options(${target} PRIVATE ${OPTIONS})

View file

@ -99,6 +99,10 @@ enum class BigFlags : std::uint64_t {
D = (static_cast<std::uint64_t>(0x1) << 63),
};
#if defined(MAGIC_ENUM_ENABLE_NONASCII)
enum class Language : int { = 10, = 20, English = 30, 😃 = 40 };
#endif
template <>
struct nameof::customize::enum_range<number> {
static_assert(std::is_enum_v<number>, "nameof::enum_range<number> requires enum type.");
@ -380,6 +384,17 @@ TEST_CASE("NAMEOF_ENUM") {
REQUIRE(nt_name == "three");
NAMEOF_DEBUG_REQUIRE(NAMEOF_ENUM(number::four).empty());
NAMEOF_DEBUG_REQUIRE(NAMEOF_ENUM(static_cast<number>(0)).empty());
#if defined(MAGIC_ENUM_ENABLE_NONASCII)
constexpr Language lang = Language::;
constexpr auto lang_name = NAMEOF_ENUM(lang);
Language lk = Language::;
REQUIRE(NAMEOF_ENUM(lk) == "한국어");
REQUIRE(NAMEOF_ENUM(Language::English) == "English");
REQUIRE(lang_name == "日本語");
REQUIRE(NAMEOF_ENUM(Language::😃) == "😃");
REQUIRE(NAMEOF_ENUM(static_cast<Language>(0)).empty());
#endif
}
TEST_CASE("NAMEOF_ENUM_CONST") {