This commit is contained in:
Neargye 2018-04-04 17:19:02 +05:00
parent 425046ecb6
commit c9024c9f1c
10 changed files with 297 additions and 56 deletions

View file

@ -1,4 +1,5 @@
dist: trusty dist: trusty
sudo: required sudo: required
language: cpp language: cpp

View file

@ -1,13 +1,11 @@
cmake_minimum_required(VERSION 3.6.4) cmake_minimum_required(VERSION 3.6)
project(nameof) project(nameof)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-pedantic) add_compile_options(-Wall -Wextra -pedantic)
add_compile_options(-Wall)
add_compile_options(-Wextra)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/W4) add_compile_options(/W4)
endif() endif()

View file

@ -46,8 +46,8 @@ NAMEOF(SomeEnum::GREEN) -> "GREEN"
* Name of type * Name of type
```cpp ```cpp
NAMEOF_TYPE(int[]) -> "int[]" NAMEOF(int[]) -> "int[]"
NAMEOF_TYPE(std::string) -> "string" NAMEOF(std::string) -> "string"
``` ```
* Constexpr * Constexpr
@ -66,7 +66,7 @@ void f() {
int i; int i;
NAMEOF(i); -> "i" NAMEOF(i); -> "i"
NAMEOF(iii); -> error identifier "iii" is undefined NAMEOF(iii); -> error identifier "iii" is undefined
NAMEOF_TYPE(std::stringgg) -> error namespace "std" has no member "stringgg" NAMEOF(std::stringgg) -> error namespace "std" has no member "stringgg"
} }
``` ```
@ -105,11 +105,20 @@ void f() {
## Remarks ## Remarks
If you need to get the fully-qualified name, you can use the NAMEOF_FULL(). For example: * If you need to get the fully-qualified name, you could use the NAMEOF_FULL().
```cpp ```cpp
NAMEOF_FULL(someVar.SomeField) -> "someVar.SomeField" NAMEOF_FULL(someVar.SomeField) -> "someVar.SomeField"
NAMEOF_FULL(&SomeStruct::SomeMethod2) -> "&SomeStruct::SomeMethod2" NAMEOF_FULL(&SomeStruct::SomeMethod2) -> "&SomeStruct::SomeMethod2"
NAMEOF_FULL(std::string) -> "std::string"
```
* If compiling without RTTI, you need use the NAMEOF_TYPE() for get name of type.
```cpp
NAMEOF_TYPE(int[]) -> "int[]"
NAMEOF_TYPE(std::string) -> "string"
NAMEOF_TYPE_FULL(std::string) -> "std::string" NAMEOF_TYPE_FULL(std::string) -> "std::string"
``` ```

View file

@ -1,9 +1,5 @@
version: "{branch} #{build}" version: "{branch} #{build}"
branches:
only:
- master
image: Visual Studio 2017 image: Visual Studio 2017
platform: x64 platform: x64

View file

@ -1,5 +1,7 @@
include_directories(${CMAKE_SOURCE_DIR}/src) include_directories(${CMAKE_SOURCE_DIR}/src)
set(SRC example.cpp) set(SOURCE_EXAMPLE
${CMAKE_SOURCE_DIR}/src/nameof.hpp
example.cpp)
add_executable(${PROJECT_NAME}_example ${SRC}) add_executable(${PROJECT_NAME}_example ${SOURCE_EXAMPLE})

View file

@ -77,10 +77,18 @@ void TestCase1() {
std::cout << NAMEOF(&SomeStruct::SomeMethod2) << std::endl; // SomeMethod2 std::cout << NAMEOF(&SomeStruct::SomeMethod2) << std::endl; // SomeMethod2
std::cout << NAMEOF(SomeMethod3) << std::endl; // SomeMethod3 std::cout << NAMEOF(SomeMethod3) << std::endl; // SomeMethod3
std::cout << NAMEOF(int[]) << std::endl; // int[]
std::cout << NAMEOF(SomeStruct) << std::endl; // SomeStruct
std::cout << NAMEOF(Long::LL) << std::endl; // LL
std::cout << NAMEOF(volatile const int) << std::endl; // const volatile int
// If no RTTI, use NAMEOF_TYPE().
#if !defined(__GXX_RTTI) && !defined(_CPPRTTI) && !defined(__RTTI) && !defined(__INTEL_RTTI__)
std::cout << NAMEOF_TYPE(int[]) << std::endl; // int[] std::cout << NAMEOF_TYPE(int[]) << std::endl; // int[]
std::cout << NAMEOF_TYPE(SomeStruct) << std::endl; // SomeStruct std::cout << NAMEOF_TYPE(SomeStruct) << std::endl; // SomeStruct
std::cout << NAMEOF_TYPE(Long::LL) << std::endl; // LL std::cout << NAMEOF_TYPE(Long::LL) << std::endl; // LL
std::cout << NAMEOF_TYPE(const volatile int) << std::endl; // const volatile int std::cout << NAMEOF_TYPE(volatile const int) << std::endl; // const volatile int
#endif
std::cout << NAMEOF_FULL(someVar.SomeField) << std::endl; // someVar.SomeField std::cout << NAMEOF_FULL(someVar.SomeField) << std::endl; // someVar.SomeField
std::cout << NAMEOF_FULL(&SomeStruct::SomeMethod2) << std::endl; // &SomeStruct::SomeMethod2 std::cout << NAMEOF_FULL(&SomeStruct::SomeMethod2) << std::endl; // &SomeStruct::SomeMethod2

View file

@ -1,5 +1,5 @@
// nameof() c++11 https://github.com/Neargye/nameof // nameof() c++11 https://github.com/Neargye/nameof
// Vesion 0.1.5 // Vesion 0.2.0
// //
// Licensed under the MIT License <http://opensource.org/licenses/MIT>. // Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// Copyright (c) 2016, 2018 Daniil Goncharov <neargye@gmail.com>. // Copyright (c) 2016, 2018 Daniil Goncharov <neargye@gmail.com>.
@ -25,31 +25,61 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
namespace nameof { #define NAMEOF_RAW_(x) #x
#define NAMEOF_RAW(x) NAMEOF_RAW_(x)
namespace nameof {
namespace detail {
inline constexpr bool IsLexeme(const char s) { inline constexpr bool IsLexeme(const char s) {
return (s == '.' || s == '>' || s == ':' || s == '&' || s == '*' || return (s == '.' || s == '>' || s == ':' || s == '&' || s == '*' ||
s == '+' || s == '~' || s == '-' || s == '!'); s == '+' || s == '~' || s == '-' || s == '!');
} }
}
}
template <typename T, std::size_t N> #if defined(__GXX_RTTI) || defined(_CPPRTTI) || defined(__RTTI) || defined(__INTEL_RTTI__)
inline constexpr const char* Nameof(const char(&name)[N], const std::size_t length = N) {
return length == 0 ? name : IsLexeme(name[length - 1]) #include <typeinfo>
namespace nameof {
inline constexpr const char* Nameof(const char* name, const std::size_t length, const std::size_t) {
return length == 0 ? name : detail::IsLexeme(name[length - 1])
? &name[length]
: Nameof(name, length - 1, 0);
}
}
// Used to obtain the string name of a variable, type, function and etc.
#define NAMEOF(name) nameof::Nameof(NAMEOF_RAW(name), sizeof(NAMEOF_RAW(name)) / sizeof(char) - 1, sizeof(typeid(name)))
// Used to obtain the string full name of a variable, type, function and etc.
#define NAMEOF_FULL(name) nameof::Nameof(NAMEOF_RAW(name), 0, sizeof(typeid(name)))
// Alias
#define NAMEOF_TYPE(type) NAMEOF(type)
#define NAMEOF_TYPE_FULL(type) NAMEOF_FULL(type)
#else
namespace nameof {
template <typename T>
inline constexpr const char* Nameof(const char* name, const std::size_t length) {
return length == 0 ? name : detail::IsLexeme(name[length - 1])
? &name[length] ? &name[length]
: Nameof<T>(name, length - 1); : Nameof<T>(name, length - 1);
} }
} }
#define NAMEOF_RAW_(x) #x
#define NAMEOF_RAW(x) NAMEOF_RAW_(x)
// Used to obtain the string name of a variable, function and etc. // Used to obtain the string name of a variable, function and etc.
#define NAMEOF(name) nameof::Nameof<decltype(name)>(NAMEOF_RAW(name)) #define NAMEOF(name) nameof::Nameof<decltype(name)>(NAMEOF_RAW(name), sizeof(NAMEOF_RAW(name)) / sizeof(char) - 1)
// Used to obtain the string full name of a variable, function and etc.
#define NAMEOF_FULL(name) nameof::Nameof<decltype(name)>(NAMEOF_RAW(name), 0) #define NAMEOF_FULL(name) nameof::Nameof<decltype(name)>(NAMEOF_RAW(name), 0)
// Used to obtain the string name of a type. // Used to obtain the string name of a type.
#define NAMEOF_TYPE(type) nameof::Nameof<type>(NAMEOF_RAW(type)) #define NAMEOF_TYPE(type) nameof::Nameof<type>(NAMEOF_RAW(type), sizeof(NAMEOF_RAW(type)) / sizeof(char) - 1)
// Used to obtain the string full name of a type.
#define NAMEOF_TYPE_FULL(type) nameof::Nameof<type>(NAMEOF_RAW(type), 0) #define NAMEOF_TYPE_FULL(type) nameof::Nameof<type>(NAMEOF_RAW(type), 0)
#endif

View file

@ -1,8 +1,13 @@
include_directories(${CMAKE_SOURCE_DIR}/src) include_directories(3rdparty/Catch2)
include_directories(3rdparty/Catch2) include_directories(${CMAKE_SOURCE_DIR}/src)
set(SRC test.cpp) add_executable(${PROJECT_NAME}_test test.cpp)
add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test)
add_executable(${PROJECT_NAME}_test ${SRC}) add_executable(${PROJECT_NAME}_test_no_rtti test_no_rtti.cpp)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) target_compile_options(${PROJECT_NAME}_test_no_rtti PUBLIC -fno-rtti)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(${PROJECT_NAME}_test_no_rtti PUBLIC /GR-)
endif()
add_test(NAME ${PROJECT_NAME}_test_no_rtti COMMAND ${PROJECT_NAME}_test_no_rtti)

View file

@ -65,12 +65,12 @@ TEST_CASE("constexpr") {
} }
SECTION("NAMEOF_TYPE") { SECTION("NAMEOF_TYPE") {
constexpr auto n = NAMEOF_TYPE(std::string); constexpr auto n = NAMEOF(std::string);
REQUIRE(std::strcmp(n, "string") == 0); REQUIRE(std::strcmp(n, "string") == 0);
} }
SECTION("NAMEOF_TYPE_FULL") { SECTION("NAMEOF_TYPE_FULL") {
constexpr auto n = NAMEOF_TYPE_FULL(std::string); constexpr auto n = NAMEOF_FULL(std::string);
REQUIRE(std::strcmp(n, "std::string") == 0); REQUIRE(std::strcmp(n, "std::string") == 0);
} }
} }
@ -100,6 +100,26 @@ TEST_CASE("NAMEOF") {
REQUIRE(std::strcmp(NAMEOF(!intValue), "intValue") == 0); REQUIRE(std::strcmp(NAMEOF(!intValue), "intValue") == 0);
} }
SECTION("NAMEOF_TYPE") {
REQUIRE(std::strcmp(NAMEOF(int[]), "int[]") == 0);
REQUIRE(std::strcmp(NAMEOF(int[]), NAMEOF_TYPE(int[])) == 0);
REQUIRE(std::strcmp(NAMEOF(int), "int") == 0);
REQUIRE(std::strcmp(NAMEOF(int), NAMEOF_TYPE(int)) == 0);
REQUIRE(std::strcmp(NAMEOF(const volatile int[]), "const volatile int[]") == 0);
REQUIRE(std::strcmp(NAMEOF(const volatile int[]), NAMEOF_TYPE(const volatile int[])) == 0);
REQUIRE(std::strcmp(NAMEOF(std::string), "string") == 0);
REQUIRE(std::strcmp(NAMEOF(std::string), NAMEOF_TYPE(std::string)) == 0);
REQUIRE(std::strcmp(NAMEOF(SomeStruct), "SomeStruct") == 0);
REQUIRE(std::strcmp(NAMEOF(SomeStruct), NAMEOF_TYPE(SomeStruct)) == 0);
REQUIRE(std::strcmp(NAMEOF(Long::LL), "LL") == 0);
REQUIRE(std::strcmp(NAMEOF(Long::LL), NAMEOF_TYPE(Long::LL)) == 0);
}
SECTION("NAMEOF_FUNCTION") { SECTION("NAMEOF_FUNCTION") {
REQUIRE(std::strcmp(NAMEOF(someVar.SomeMethod1()), "SomeMethod1()") == 0); REQUIRE(std::strcmp(NAMEOF(someVar.SomeMethod1()), "SomeMethod1()") == 0);
REQUIRE(std::strcmp(NAMEOF(&SomeStruct::SomeMethod2), "SomeMethod2") == 0); REQUIRE(std::strcmp(NAMEOF(&SomeStruct::SomeMethod2), "SomeMethod2") == 0);
@ -112,17 +132,6 @@ TEST_CASE("NAMEOF") {
} }
} }
TEST_CASE("NAMEOF_TYPE") {
SECTION("NAMEOF_TYPE") {
REQUIRE(std::strcmp(NAMEOF_TYPE(int[]), "int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(int), "int") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(const volatile int[]), "const volatile int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(std::string), "string") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(SomeStruct), "SomeStruct") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(Long::LL), "LL") == 0);
}
}
TEST_CASE("NAMEOF_FULL") { TEST_CASE("NAMEOF_FULL") {
SomeStruct someVar; SomeStruct someVar;
Long otherVar; Long otherVar;
@ -148,6 +157,27 @@ TEST_CASE("NAMEOF_FULL") {
REQUIRE(std::strcmp(NAMEOF_FULL(!intValue), "!intValue") == 0); REQUIRE(std::strcmp(NAMEOF_FULL(!intValue), "!intValue") == 0);
} }
SECTION("NAMEOF_TYPE_FULL") {
REQUIRE(std::strcmp(NAMEOF_FULL(int[]), "int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(int[]), NAMEOF_TYPE_FULL(int[])) == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(int), "int") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(int), NAMEOF_TYPE_FULL(int)) == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(const volatile int[]), "const volatile int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(const volatile int[]), NAMEOF_TYPE_FULL(const volatile int[])) == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(std::string), "std::string") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(std::string), NAMEOF_TYPE_FULL(std::string)) == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(SomeStruct), "SomeStruct") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(SomeStruct), NAMEOF_TYPE_FULL(SomeStruct)) == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(Long::LL), "Long::LL") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(Long::LL), NAMEOF_TYPE_FULL(Long::LL)) == 0);
}
SECTION("NAMEOF_FUNCTION_FULL") { SECTION("NAMEOF_FUNCTION_FULL") {
REQUIRE(std::strcmp(NAMEOF_FULL(someVar.SomeMethod1()), "someVar.SomeMethod1()") == 0); REQUIRE(std::strcmp(NAMEOF_FULL(someVar.SomeMethod1()), "someVar.SomeMethod1()") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(&SomeStruct::SomeMethod2), "&SomeStruct::SomeMethod2") == 0); REQUIRE(std::strcmp(NAMEOF_FULL(&SomeStruct::SomeMethod2), "&SomeStruct::SomeMethod2") == 0);
@ -160,14 +190,3 @@ TEST_CASE("NAMEOF_FULL") {
} }
} }
TEST_CASE("NAMEOF_TYPE_FULL") {
SECTION("NAMEOF_TYPE_FULL") {
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(int[]), "int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(const volatile int[]), "const volatile int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(Long::LL), "Long::LL") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(std::string), "std::string") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(SomeStruct), "SomeStruct") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(Long::LL), "Long::LL") == 0);
}
}

173
test/test_no_rtti.cpp Normal file
View file

@ -0,0 +1,173 @@
// nameof() c++11 test_no_rtti
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// Copyright (c) 2018 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.
#if defined(__GXX_RTTI) || defined(_CPPRTTI) || defined(__RTTI) || defined(__INTEL_RTTI__)
#error "need test case with no rtti"
#endif
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <nameof.hpp>
#include <cstring>
#include <string>
#include <iostream>
struct SomeStruct {
int SomeField;
void SomeMethod1() { std::cout << "No called!" << std::endl; }
int SomeMethod2() {
std::cout << "No called!" << std::endl;
return 1;
}
};
void SomeMethod3() { std::cout << "No called!" << std::endl; }
struct Long {
struct LL {
int LLLField;
};
LL LLField;
};
int someVar = 0;
enum class Color { RED, GREEN, BLUE };
TEST_CASE("constexpr") {
SomeStruct someVar;
SECTION("NAMEOF") {
constexpr auto n = NAMEOF(someVar);
REQUIRE(std::strcmp(n, "someVar") == 0);
}
SECTION("NAMEOF_FULL") {
constexpr auto n = NAMEOF_FULL((&someVar)->SomeField);
REQUIRE(std::strcmp(n, "(&someVar)->SomeField") == 0);
}
SECTION("NAMEOF_TYPE") {
constexpr auto n = NAMEOF_TYPE(std::string);
REQUIRE(std::strcmp(n, "string") == 0);
}
SECTION("NAMEOF_TYPE_FULL") {
constexpr auto n = NAMEOF_TYPE_FULL(std::string);
REQUIRE(std::strcmp(n, "std::string") == 0);
}
}
TEST_CASE("NAMEOF") {
SomeStruct someVar;
Long otherVar;
int intValue;
SomeStruct* ptrVar;
SomeStruct** ptrptrVar;
SECTION("NAMEOF_VARIABLE") {
REQUIRE(std::strcmp(NAMEOF(someVar), "someVar") == 0);
REQUIRE(std::strcmp(NAMEOF(someVar.SomeField), "SomeField") == 0);
REQUIRE(std::strcmp(NAMEOF((&someVar)->SomeField), "SomeField") == 0);
REQUIRE(std::strcmp(NAMEOF(::someVar), "someVar") == 0);
REQUIRE(std::strcmp(NAMEOF(otherVar.LLField.LLLField), "LLLField") == 0);
REQUIRE(std::strcmp(NAMEOF(&someVar), "someVar") == 0);
REQUIRE(std::strcmp(NAMEOF(ptrVar), "ptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF(*ptrVar), "ptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF(ptrptrVar), "ptrptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF(*ptrptrVar), "ptrptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF(**ptrptrVar), "ptrptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF(+intValue), "intValue") == 0);
REQUIRE(std::strcmp(NAMEOF(-intValue), "intValue") == 0);
REQUIRE(std::strcmp(NAMEOF(~intValue), "intValue") == 0);
REQUIRE(std::strcmp(NAMEOF(!intValue), "intValue") == 0);
}
SECTION("NAMEOF_TYPE") {
REQUIRE(std::strcmp(NAMEOF_TYPE(int[]), "int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(int), "int") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(const volatile int[]), "const volatile int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(std::string), "string") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(SomeStruct), "SomeStruct") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE(Long::LL), "LL") == 0);
}
SECTION("NAMEOF_FUNCTION") {
REQUIRE(std::strcmp(NAMEOF(someVar.SomeMethod1()), "SomeMethod1()") == 0);
REQUIRE(std::strcmp(NAMEOF(&SomeStruct::SomeMethod2), "SomeMethod2") == 0);
REQUIRE(std::strcmp(NAMEOF(SomeMethod3), "SomeMethod3") == 0);
}
SECTION("NAMEOF_ENUM") {
REQUIRE(std::strcmp(NAMEOF(Color::RED), "RED") == 0);
REQUIRE(std::strcmp(NAMEOF(Color::BLUE), "BLUE") == 0);
}
}
TEST_CASE("NAMEOF_FULL") {
SomeStruct someVar;
Long otherVar;
int intValue;
SomeStruct* ptrVar;
SomeStruct** ptrptrVar;
SECTION("NAMEOF_VARIABLE_FULL") {
REQUIRE(std::strcmp(NAMEOF_FULL(someVar), "someVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(someVar.SomeField), "someVar.SomeField") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL((&someVar)->SomeField), "(&someVar)->SomeField") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(::someVar), "::someVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(otherVar.LLField.LLLField), "otherVar.LLField.LLLField") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(&someVar), "&someVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(ptrVar), "ptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(*ptrVar), "*ptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(ptrptrVar), "ptrptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(*ptrptrVar), "*ptrptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(**ptrptrVar), "**ptrptrVar") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(+intValue), "+intValue") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(-intValue), "-intValue") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(~intValue), "~intValue") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(!intValue), "!intValue") == 0);
}
SECTION("NAMEOF_TYPE_FULL") {
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(int[]), "int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(const volatile int[]), "const volatile int[]") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(std::string), "std::string") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(SomeStruct), "SomeStruct") == 0);
REQUIRE(std::strcmp(NAMEOF_TYPE_FULL(Long::LL), "Long::LL") == 0);
}
SECTION("NAMEOF_FUNCTION_FULL") {
REQUIRE(std::strcmp(NAMEOF_FULL(someVar.SomeMethod1()), "someVar.SomeMethod1()") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(&SomeStruct::SomeMethod2), "&SomeStruct::SomeMethod2") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(SomeMethod3), "SomeMethod3") == 0);
}
SECTION("NAMEOF_ENUM_FULL") {
REQUIRE(std::strcmp(NAMEOF_FULL(Color::RED), "Color::RED") == 0);
REQUIRE(std::strcmp(NAMEOF_FULL(Color::BLUE), "Color::BLUE") == 0);
}
}