From c9024c9f1c6b519ceb70a3e9196d86e67684a1c1 Mon Sep 17 00:00:00 2001 From: Neargye Date: Wed, 4 Apr 2018 17:19:02 +0500 Subject: [PATCH] v0.2.0 --- .travis.yml | 1 + CMakeLists.txt | 6 +- README.md | 17 +++- appveyor.yml | 4 - example/CMakeLists.txt | 6 +- example/example.cpp | 10 ++- src/nameof.hpp | 52 ++++++++++--- test/CMakeLists.txt | 17 ++-- test/test.cpp | 67 ++++++++++------ test/test_no_rtti.cpp | 173 +++++++++++++++++++++++++++++++++++++++++ 10 files changed, 297 insertions(+), 56 deletions(-) create mode 100644 test/test_no_rtti.cpp diff --git a/.travis.yml b/.travis.yml index 66b0ea7..5537aa5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ dist: trusty + sudo: required language: cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index da3b19a..437c671 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,11 @@ -cmake_minimum_required(VERSION 3.6.4) +cmake_minimum_required(VERSION 3.6) project(nameof) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - add_compile_options(-pedantic) - add_compile_options(-Wall) - add_compile_options(-Wextra) + add_compile_options(-Wall -Wextra -pedantic) elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options(/W4) endif() diff --git a/README.md b/README.md index fedb626..7fcd5d2 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ NAMEOF(SomeEnum::GREEN) -> "GREEN" * Name of type ```cpp -NAMEOF_TYPE(int[]) -> "int[]" -NAMEOF_TYPE(std::string) -> "string" +NAMEOF(int[]) -> "int[]" +NAMEOF(std::string) -> "string" ``` * Constexpr @@ -66,7 +66,7 @@ void f() { int i; NAMEOF(i); -> "i" 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 -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 NAMEOF_FULL(someVar.SomeField) -> "someVar.SomeField" 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" ``` diff --git a/appveyor.yml b/appveyor.yml index 994d6ab..e439a17 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,9 +1,5 @@ version: "{branch} #{build}" -branches: - only: - - master - image: Visual Studio 2017 platform: x64 diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index e4643ff..b00474b 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,5 +1,7 @@ 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}) \ No newline at end of file +add_executable(${PROJECT_NAME}_example ${SOURCE_EXAMPLE}) \ No newline at end of file diff --git a/example/example.cpp b/example/example.cpp index f9d1bf5..a02639d 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -77,10 +77,18 @@ void TestCase1() { std::cout << NAMEOF(&SomeStruct::SomeMethod2) << std::endl; // SomeMethod2 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(SomeStruct) << std::endl; // SomeStruct 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(&SomeStruct::SomeMethod2) << std::endl; // &SomeStruct::SomeMethod2 diff --git a/src/nameof.hpp b/src/nameof.hpp index 1846361..e94dc3a 100644 --- a/src/nameof.hpp +++ b/src/nameof.hpp @@ -1,5 +1,5 @@ // nameof() c++11 https://github.com/Neargye/nameof -// Vesion 0.1.5 +// Vesion 0.2.0 // // Licensed under the MIT License . // Copyright (c) 2016, 2018 Daniil Goncharov . @@ -25,31 +25,61 @@ #pragma once #include -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) { return (s == '.' || s == '>' || s == ':' || s == '&' || s == '*' || s == '+' || s == '~' || s == '-' || s == '!'); } +} +} -template -inline constexpr const char* Nameof(const char(&name)[N], const std::size_t length = N) { - return length == 0 ? name : IsLexeme(name[length - 1]) +#if defined(__GXX_RTTI) || defined(_CPPRTTI) || defined(__RTTI) || defined(__INTEL_RTTI__) + +#include + +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 +inline constexpr const char* Nameof(const char* name, const std::size_t length) { + return length == 0 ? name : detail::IsLexeme(name[length - 1]) ? &name[length] : Nameof(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. -#define NAMEOF(name) nameof::Nameof(NAMEOF_RAW(name)) +#define NAMEOF(name) nameof::Nameof(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(NAMEOF_RAW(name), 0) // Used to obtain the string name of a type. -#define NAMEOF_TYPE(type) nameof::Nameof(NAMEOF_RAW(type)) +#define NAMEOF_TYPE(type) nameof::Nameof(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(NAMEOF_RAW(type), 0) + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 78dc856..446db4e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) \ No newline at end of file +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")) + 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) \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index 0504ac9..9a8c005 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -65,12 +65,12 @@ TEST_CASE("constexpr") { } SECTION("NAMEOF_TYPE") { - constexpr auto n = NAMEOF_TYPE(std::string); + constexpr auto n = NAMEOF(std::string); REQUIRE(std::strcmp(n, "string") == 0); } 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); } } @@ -100,6 +100,26 @@ TEST_CASE("NAMEOF") { 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") { REQUIRE(std::strcmp(NAMEOF(someVar.SomeMethod1()), "SomeMethod1()") == 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") { SomeStruct someVar; Long otherVar; @@ -148,6 +157,27 @@ TEST_CASE("NAMEOF_FULL") { 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") { REQUIRE(std::strcmp(NAMEOF_FULL(someVar.SomeMethod1()), "someVar.SomeMethod1()") == 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); - } -} \ No newline at end of file diff --git a/test/test_no_rtti.cpp b/test/test_no_rtti.cpp new file mode 100644 index 0000000..b2819da --- /dev/null +++ b/test/test_no_rtti.cpp @@ -0,0 +1,173 @@ +// nameof() c++11 test_no_rtti +// +// Licensed under the MIT License . +// Copyright (c) 2018 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. + +#if defined(__GXX_RTTI) || defined(_CPPRTTI) || defined(__RTTI) || defined(__INTEL_RTTI__) +#error "need test case with no rtti" +#endif + +#define CATCH_CONFIG_MAIN + +#include +#include +#include +#include +#include + +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); + } + +}