add support for non-ASCII characters (UNIX/Linux)
This commit is contained in:
parent
b5deb0055c
commit
aeb37e86cf
7 changed files with 95 additions and 6 deletions
|
@ -8,6 +8,7 @@ else()
|
||||||
set(IS_TOPLEVEL_PROJECT FALSE)
|
set(IS_TOPLEVEL_PROJECT FALSE)
|
||||||
endif()
|
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_EXAMPLES "Build nameof examples" ${IS_TOPLEVEL_PROJECT})
|
||||||
option(NAMEOF_OPT_BUILD_TESTS "Build and perform nameof tests" ${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})
|
option(NAMEOF_OPT_INSTALL "Generate and install nameof target" ${IS_TOPLEVEL_PROJECT})
|
||||||
|
|
|
@ -41,6 +41,12 @@
|
||||||
#include <nameof.hpp>
|
#include <nameof.hpp>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* To add support for non-ASCII enumeration identifier, use special macros:
|
||||||
|
```cpp
|
||||||
|
#define NAMEOF_ENABLE_NONASCII
|
||||||
|
#include <nameof.hpp>
|
||||||
|
```
|
||||||
|
|
||||||
## `NAMEOF`
|
## `NAMEOF`
|
||||||
|
|
||||||
* Obtains simple (unqualified) name of variable, function, macro.
|
* Obtains simple (unqualified) name of variable, function, macro.
|
||||||
|
|
|
@ -19,3 +19,12 @@ endfunction()
|
||||||
|
|
||||||
make_example(example)
|
make_example(example)
|
||||||
make_example(example_custom_name)
|
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()
|
||||||
|
|
44
example/example_nonascii_name.cpp
Normal file
44
example/example_nonascii_name.cpp
Normal 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;
|
||||||
|
}
|
|
@ -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') ||
|
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') ||
|
||||||
(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[i - 1] == '_'))) {
|
||||||
name.remove_prefix(i);
|
name.remove_prefix(i);
|
||||||
break;
|
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') ||
|
if (name.size() > 0 && ((name.front() >= 'a' && name.front() <= 'z') ||
|
||||||
(name.front() >= 'A' && name.front() <= 'Z') ||
|
(name.front() >= 'A' && name.front() <= 'Z') ||
|
||||||
|
#if defined(NAMEOF_ENABLE_NONASCII)
|
||||||
|
(name.front() & 0x80) ||
|
||||||
|
#endif
|
||||||
(name.front() == '_'))) {
|
(name.front() == '_'))) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -1084,18 +1090,18 @@ template <auto V>
|
||||||
// Obtains type name, reference and cv-qualifiers are ignored.
|
// Obtains type name, reference and cv-qualifiers are ignored.
|
||||||
#define NAMEOF_TYPE(...) ::nameof::nameof_type<__VA_ARGS__>()
|
#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.
|
// Obtains full type name, with reference and cv-qualifiers.
|
||||||
#define NAMEOF_FULL_TYPE(...) ::nameof::nameof_full_type<__VA_ARGS__>()
|
#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.
|
// Obtains short type name.
|
||||||
#define NAMEOF_SHORT_TYPE(...) ::nameof::nameof_short_type<__VA_ARGS__>()
|
#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.
|
// Obtains short type name of expression.
|
||||||
#define NAMEOF_SHORT_TYPE_EXPR(...) ::nameof::nameof_short_type<decltype(__VA_ARGS__)>()
|
#define NAMEOF_SHORT_TYPE_EXPR(...) ::nameof::nameof_short_type<decltype(__VA_ARGS__)>()
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,14 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
check_cxx_compiler_flag(-std=c++20 HAS_CPP20_FLAG)
|
check_cxx_compiler_flag(-std=c++20 HAS_CPP20_FLAG)
|
||||||
endif()
|
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)
|
function(make_test target std)
|
||||||
add_executable(${target} ${SOURCES})
|
add_executable(${target} ${SOURCES})
|
||||||
target_compile_options(${target} PRIVATE ${OPTIONS})
|
target_compile_options(${target} PRIVATE ${OPTIONS})
|
||||||
|
|
|
@ -99,6 +99,10 @@ enum class BigFlags : std::uint64_t {
|
||||||
D = (static_cast<std::uint64_t>(0x1) << 63),
|
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 <>
|
template <>
|
||||||
struct nameof::customize::enum_range<number> {
|
struct nameof::customize::enum_range<number> {
|
||||||
static_assert(std::is_enum_v<number>, "nameof::enum_range<number> requires enum type.");
|
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");
|
REQUIRE(nt_name == "three");
|
||||||
NAMEOF_DEBUG_REQUIRE(NAMEOF_ENUM(number::four).empty());
|
NAMEOF_DEBUG_REQUIRE(NAMEOF_ENUM(number::four).empty());
|
||||||
NAMEOF_DEBUG_REQUIRE(NAMEOF_ENUM(static_cast<number>(0)).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") {
|
TEST_CASE("NAMEOF_ENUM_CONST") {
|
||||||
|
|
Loading…
Reference in a new issue