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)
|
||||
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})
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
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') ||
|
||||
(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__)>()
|
||||
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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") {
|
||||
|
|
Loading…
Reference in a new issue