WIP
This commit is contained in:
parent
fc2bf032d9
commit
7dbb2dc63b
3 changed files with 180 additions and 102 deletions
|
@ -56,10 +56,16 @@ T SomeMethod4() {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
public:
|
public:
|
||||||
void SomeMethod5() const {}
|
void SomeMethod5() const {
|
||||||
|
std::cout << nameof::NameofType<T>(false) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
C SomeMethod6() const { return C{}; }
|
C SomeMethod6() const {
|
||||||
|
C t{};
|
||||||
|
std::cout << NAMEOF_TYPE(t) << std::endl;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Long {
|
struct Long {
|
||||||
|
@ -77,24 +83,25 @@ SomeStruct& refvar = somevar;
|
||||||
SomeStruct* ptrvar = &somevar;
|
SomeStruct* ptrvar = &somevar;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
std::cout << typeid(std::string).name() << std::endl;
|
#if __cplusplus >= 201402L || (defined(_MSVC_LANG ) && _MSVC_LANG >= 201402L )
|
||||||
// constexpr
|
// Compile-time supported by C++14.
|
||||||
constexpr auto constexpr_work_fine = NAMEOF(somevar);
|
constexpr auto constexpr_work_fine = NAMEOF(somevar);
|
||||||
std::cout << constexpr_work_fine << std::endl; // somevar
|
std::cout << constexpr_work_fine << std::endl; // somevar
|
||||||
|
#endif
|
||||||
|
|
||||||
// enum
|
// Enum name.
|
||||||
std::cout << NAMEOF(Color::RED) << std::endl; // RED
|
std::cout << NAMEOF(Color::RED) << std::endl; // RED
|
||||||
|
|
||||||
// variable
|
// Variable name.
|
||||||
std::cout << NAMEOF(somevar) << std::endl; // somevar
|
std::cout << NAMEOF(somevar) << std::endl; // somevar
|
||||||
std::cout << NAMEOF(::somevar) << std::endl; // somevar
|
std::cout << NAMEOF(::somevar) << std::endl; // somevar
|
||||||
|
|
||||||
// member
|
// Member name.
|
||||||
std::cout << NAMEOF(somevar.somefield) << std::endl; // somefield
|
std::cout << NAMEOF(somevar.somefield) << std::endl; // somefield
|
||||||
std::cout << NAMEOF((&somevar)->somefield) << std::endl; // somefield
|
std::cout << NAMEOF((&somevar)->somefield) << std::endl; // somefield
|
||||||
std::cout << NAMEOF(othervar.ll.field) << std::endl; // field
|
std::cout << NAMEOF(othervar.ll.field) << std::endl; // field
|
||||||
|
|
||||||
// function
|
// Function name.
|
||||||
std::cout << NAMEOF(&SomeStruct::SomeMethod1) << std::endl; // SomeMethod1
|
std::cout << NAMEOF(&SomeStruct::SomeMethod1) << std::endl; // SomeMethod1
|
||||||
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
|
||||||
|
@ -102,29 +109,25 @@ int main() {
|
||||||
std::cout << NAMEOF(&SomeClass<int>::SomeMethod5) << std::endl; // SomeMethod5
|
std::cout << NAMEOF(&SomeClass<int>::SomeMethod5) << std::endl; // SomeMethod5
|
||||||
std::cout << NAMEOF(&SomeClass<int>::SomeMethod6<long int>) << std::endl; // SomeMethod6
|
std::cout << NAMEOF(&SomeClass<int>::SomeMethod6<long int>) << std::endl; // SomeMethod6
|
||||||
|
|
||||||
// function with template prefix
|
// Type name.
|
||||||
std::cout << NAMEOF_T(SomeMethod4<int>) << std::endl; // SomeMethod4<int>
|
|
||||||
std::cout << NAMEOF_T(&SomeClass<int>::SomeMethod6<long int>) << std::endl; // SomeMethod6<long int>
|
|
||||||
|
|
||||||
// type
|
|
||||||
std::cout << NAMEOF_TYPE(std::string{}) << std::endl; // basic_string
|
|
||||||
std::cout << NAMEOF_TYPE(somevar) << std::endl; // SomeStruct
|
std::cout << NAMEOF_TYPE(somevar) << std::endl; // SomeStruct
|
||||||
std::cout << NAMEOF_TYPE(refvar) << std::endl; // SomeStruct&
|
std::cout << NAMEOF_TYPE(refvar) << std::endl; // SomeStruct
|
||||||
std::cout << NAMEOF_TYPE(ptrvar) << std::endl; // SomeStruct*
|
std::cout << NAMEOF_TYPE(ptrvar) << std::endl; // SomeStruct
|
||||||
|
std::cout << NAMEOF_TYPE(othervar.ll) << std::endl; // LL
|
||||||
|
std::cout << NAMEOF_TYPE(othervar.ll.field) << std::endl; // int
|
||||||
std::cout << NAMEOF_TYPE(Color::RED) << std::endl; // Color
|
std::cout << NAMEOF_TYPE(Color::RED) << std::endl; // Color
|
||||||
|
|
||||||
std::cout << NAMEOF_RAW(int[]) << std::endl; // int[]
|
std::cout << NAMEOF_TYPE(SomeClass<int>{}) << std::endl; // SomeClass
|
||||||
std::cout << NAMEOF_RAW(SomeStruct) << std::endl; // SomeStruct
|
|
||||||
std::cout << NAMEOF_RAW(Long::LL) << std::endl; // Long::LL
|
// Type full name.
|
||||||
|
std::cout << NAMEOF_TYPE_RAW(othervar.ll) << std::endl; // Long::LL
|
||||||
|
std::cout << NAMEOF_TYPE_RAW(std::declval<const SomeClass<int>>()) << std::endl; // SomeClass<int>&&
|
||||||
|
|
||||||
|
// Raw name.
|
||||||
std::cout << NAMEOF_RAW(volatile const int) << std::endl; // volatile const int
|
std::cout << NAMEOF_RAW(volatile const int) << std::endl; // volatile const int
|
||||||
|
|
||||||
// macros
|
|
||||||
std::cout << NAMEOF_RAW(__LINE__) << std::endl; // __LINE__
|
std::cout << NAMEOF_RAW(__LINE__) << std::endl; // __LINE__
|
||||||
std::cout << NAMEOF_RAW(__FILE__) << std::endl; // __FILE__
|
|
||||||
|
|
||||||
// full name
|
|
||||||
std::cout << NAMEOF_RAW(somevar.somefield) << std::endl; // somevar.somefield
|
std::cout << NAMEOF_RAW(somevar.somefield) << std::endl; // somevar.somefield
|
||||||
std::cout << NAMEOF_RAW(&SomeClass<int>::SomeMethod6<long int>) << std::endl; // &SomeClass<int>::SomeMethod6<long int>
|
std::cout << NAMEOF_RAW(&SomeStruct::SomeMethod1) << std::endl; // &SomeStruct::SomeMethod1
|
||||||
std::cout << NAMEOF_RAW(Long::LL) << std::endl; // Long::LL
|
std::cout << NAMEOF_RAW(Long::LL) << std::endl; // Long::LL
|
||||||
|
|
||||||
const auto div = [](int x, int y) -> int {
|
const auto div = [](int x, int y) -> int {
|
||||||
|
@ -143,7 +146,7 @@ int main() {
|
||||||
|
|
||||||
/* Remarks */
|
/* Remarks */
|
||||||
|
|
||||||
// Spaces and Tabs ignored
|
// Spaces and Tabs ignored.
|
||||||
std::cout << NAMEOF( somevar ) << std::endl; // somevar
|
std::cout << NAMEOF( somevar ) << std::endl; // somevar
|
||||||
std::cout << NAMEOF( somevar ) << std::endl; // somevar
|
std::cout << NAMEOF( somevar ) << std::endl; // somevar
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ template <typename T>
|
||||||
struct remove_all_pointers
|
struct remove_all_pointers
|
||||||
: std::conditional<std::is_pointer<T>::value,
|
: std::conditional<std::is_pointer<T>::value,
|
||||||
remove_all_pointers<typename std::remove_pointer<T>::type>,
|
remove_all_pointers<typename std::remove_pointer<T>::type>,
|
||||||
identity<T>> {};
|
identity<T>>::type {};
|
||||||
class cstring final {
|
class cstring final {
|
||||||
const char* str_;
|
const char* str_;
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
|
@ -89,6 +89,25 @@ class cstring final {
|
||||||
|
|
||||||
inline constexpr const char& operator[](std::size_t i) const { return str_[i]; }
|
inline constexpr const char& operator[](std::size_t i) const { return str_[i]; }
|
||||||
|
|
||||||
|
inline constexpr const char& front() const { return str_[0]; }
|
||||||
|
|
||||||
|
inline constexpr const char& back() const { return str_[size_ - 1]; }
|
||||||
|
|
||||||
|
inline constexpr const char* data() const noexcept { return str_; }
|
||||||
|
|
||||||
|
inline constexpr void remove_prefix(std::size_t n) {
|
||||||
|
str_ += n;
|
||||||
|
size_ -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr void remove_suffix(std::size_t n) {
|
||||||
|
size_ -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr cstring substr(std::size_t pos, std::size_t n) const {
|
||||||
|
return {str_ + pos, n};
|
||||||
|
}
|
||||||
|
|
||||||
inline friend constexpr bool operator==(const cstring& lhs, const cstring& rhs) noexcept;
|
inline friend constexpr bool operator==(const cstring& lhs, const cstring& rhs) noexcept;
|
||||||
|
|
||||||
inline friend constexpr bool operator!=(const cstring& lhs, const cstring& rhs) noexcept;
|
inline friend constexpr bool operator!=(const cstring& lhs, const cstring& rhs) noexcept;
|
||||||
|
@ -105,13 +124,15 @@ class cstring final {
|
||||||
};
|
};
|
||||||
|
|
||||||
inline constexpr bool operator==(const cstring& lhs, const cstring& rhs) noexcept {
|
inline constexpr bool operator==(const cstring& lhs, const cstring& rhs) noexcept {
|
||||||
if (lhs.size_ != rhs.size_)
|
if (lhs.size_ != rhs.size_) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < lhs.size_; ++i) {
|
for (std::size_t i = 0; i < lhs.size_; ++i) {
|
||||||
if (lhs.str_[i] != rhs.str_[i])
|
if (lhs.str_[i] != rhs.str_[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -141,8 +162,9 @@ inline constexpr bool IsLexeme(char s) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr cstring NameofBase(const char* name, std::size_t length) noexcept {
|
inline constexpr cstring NameofBase(const char* name, std::size_t length) noexcept {
|
||||||
if (length == 0)
|
if (length == 0) {
|
||||||
return {name, length};
|
return {name, length};
|
||||||
|
}
|
||||||
|
|
||||||
for (std::size_t i = length; i > 0; --i) {
|
for (std::size_t i = length; i > 0; --i) {
|
||||||
if (IsLexeme(name[i - 1])) {
|
if (IsLexeme(name[i - 1])) {
|
||||||
|
@ -153,9 +175,10 @@ inline constexpr cstring NameofBase(const char* name, std::size_t length) noexce
|
||||||
return {name, length};
|
return {name, length};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr cstring NameofFunction(const char* name, std::size_t length, bool with_prefix) noexcept {
|
inline constexpr cstring NameofFunction(const char* name, std::size_t length) noexcept {
|
||||||
if (length == 0)
|
if (length == 0) {
|
||||||
return {name, length};
|
return {name, length};
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t h = 0;
|
std::size_t h = 0;
|
||||||
std::size_t p = 0;
|
std::size_t p = 0;
|
||||||
|
@ -178,16 +201,17 @@ inline constexpr cstring NameofFunction(const char* name, std::size_t length, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsLexeme(name[i - 1]) && h == 0) {
|
if (IsLexeme(name[i - 1]) && h == 0) {
|
||||||
return {&name[i], length - i - (with_prefix ? 0 : p)};
|
return {&name[i], length - i - p};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {name, length - (with_prefix ? 0 : p)};
|
return {name, length - p};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr cstring NameofType(const char* name, std::size_t length, bool with_prefix) noexcept {
|
inline constexpr cstring NameofType(const char* name, std::size_t length) noexcept {
|
||||||
if (length == 0)
|
if (length == 0) {
|
||||||
return {name, length};
|
return {name, length};
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t h = 0;
|
std::size_t h = 0;
|
||||||
std::size_t p = 0;
|
std::size_t p = 0;
|
||||||
|
@ -215,11 +239,11 @@ inline constexpr cstring NameofType(const char* name, std::size_t length, bool w
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsLexeme(name[i - 1]) && h == 0) {
|
if (IsLexeme(name[i - 1]) && h == 0) {
|
||||||
return {&name[i], length - i - (with_prefix ? 0 : p)};
|
return {&name[i], length - i - p};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {name, length - (with_prefix ? 0 : p)};
|
return {name, length - p};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr cstring NameofRaw(const char* name, std::size_t length) noexcept {
|
inline constexpr cstring NameofRaw(const char* name, std::size_t length) noexcept {
|
||||||
|
@ -231,10 +255,11 @@ inline constexpr cstring NameofRaw(const char* name, std::size_t length) noexcep
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if<!std::is_reference<T>::value &&
|
typename = typename std::enable_if<!std::is_reference<T>::value &&
|
||||||
!std::is_void<T>::value>::type>
|
!std::is_void<T>::value>::type>
|
||||||
inline constexpr detail::cstring Nameof(const T&, const char* name, std::size_t length, bool with_prefix) noexcept {
|
inline constexpr detail::cstring Nameof(const T&, const char* name, std::size_t length) noexcept {
|
||||||
// TODO: conditional expression is constant
|
// TODO: conditional expression is constant
|
||||||
if (std::is_function<T>::value || std::is_member_function_pointer<T>::value)
|
if (std::is_function<T>::value || std::is_member_function_pointer<T>::value) {
|
||||||
return detail::NameofFunction(name, length, with_prefix);
|
return detail::NameofFunction(name, length);
|
||||||
|
}
|
||||||
|
|
||||||
return detail::NameofBase(name, length);
|
return detail::NameofBase(name, length);
|
||||||
}
|
}
|
||||||
|
@ -258,40 +283,33 @@ inline constexpr detail::cstring NameofType(bool full) noexcept {
|
||||||
constexpr auto prefix_length = sizeof("class nameof::detail::cstring __cdecl nameof::NameofType<") - 1;
|
constexpr auto prefix_length = sizeof("class nameof::detail::cstring __cdecl nameof::NameofType<") - 1;
|
||||||
constexpr auto suffix_length = sizeof(">(bool) noexcept") - 1;
|
constexpr auto suffix_length = sizeof(">(bool) noexcept") - 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto type_name = detail::cstring{function_name + prefix_length, total_length - prefix_length - suffix_length};
|
auto type_name = detail::cstring{function_name + prefix_length, total_length - prefix_length - suffix_length};
|
||||||
|
|
||||||
|
type_name = full ? type_name : detail::NameofType(type_name.begin(), type_name.length());
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
constexpr auto class_length = sizeof("class") - 1;
|
constexpr auto class_length = sizeof("class") - 1;
|
||||||
constexpr auto struct_length = sizeof("struct") - 1;
|
constexpr auto struct_length = sizeof("struct") - 1;
|
||||||
constexpr auto enum_length = sizeof("enum") - 1;
|
constexpr auto enum_length = sizeof("enum") - 1;
|
||||||
|
|
||||||
if (std::is_class<typename detail::remove_all_pointers<typename std::remove_reference<T>::type>::type>::value) {
|
using D = typename detail::remove_all_pointers<typename std::remove_reference<T>::type>::type;
|
||||||
if (type_name[0] == 'c') {
|
|
||||||
if (type_name[class_length] == ' ') {
|
if (!full && (std::is_class<D>::value || std::is_enum<D>::value) && (std::is_reference<T>::value || std::is_pointer<T>::value)) {
|
||||||
type_name = detail::cstring{type_name.begin() + class_length + 1, type_name.length() - class_length - 1};
|
if (std::is_class<D>::value && type_name[0] == 'c' && type_name[1] == 'l' && type_name[2] == 'a' && type_name[3] == 's' && type_name[4] == 's') {
|
||||||
} else {
|
type_name.remove_prefix(class_length);
|
||||||
type_name = detail::cstring{type_name.begin() + class_length, type_name.length() - class_length};
|
} else if (std::is_class<D>::value && type_name[0] == 's' && type_name[1] == 't' && type_name[2] == 'r' && type_name[3] == 'u' && type_name[4] == 'c' && type_name[5] == 't') {
|
||||||
}
|
type_name.remove_prefix(struct_length);
|
||||||
} else if (type_name[0] == 's') {
|
} else if(std::is_enum<D>::value && type_name[0] == 'e' && type_name[1] == 'n' && type_name[2] == 'u' && type_name[3] == 'm') {
|
||||||
if (type_name[struct_length] == ' ') {
|
type_name.remove_prefix(enum_length);
|
||||||
type_name = detail::cstring{type_name.begin() + struct_length + 1, type_name.length() - struct_length - 1};
|
|
||||||
} else {
|
|
||||||
type_name = detail::cstring{type_name.begin() + struct_length, type_name.length() - struct_length};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (std::is_enum<typename detail::remove_all_pointers<typename std::remove_reference<T>::type>::type>::value) {
|
|
||||||
if (type_name[0] == 'e') {
|
|
||||||
if (type_name[enum_length] == ' ') {
|
|
||||||
type_name = detail::cstring{type_name.begin() + enum_length + 1, type_name.length() - enum_length - 1};
|
|
||||||
} else {
|
|
||||||
type_name = detail::cstring{type_name.begin() + enum_length, type_name.length() - enum_length};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//type_name.remove_prefix(type_name[0] == ' ' ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return full ? type_name : detail::NameofType(type_name.begin(), type_name.length(), false);
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace nameof
|
} // namespace nameof
|
||||||
|
@ -305,15 +323,10 @@ inline constexpr detail::cstring NameofType(bool full) noexcept {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Used to obtain the simple (unqualified) string name of a variable, member, function.
|
// Used to obtain the simple (unqualified) string name of a variable, member, function.
|
||||||
#define NAMEOF(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, false)
|
#define NAMEOF(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1)
|
||||||
|
|
||||||
// Used to obtain the simple (unqualified) string name of a variable, member, function with template prefix.
|
|
||||||
#define NAMEOF_T(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, true)
|
|
||||||
|
|
||||||
#define NAMEOF_FULL 0
|
|
||||||
|
|
||||||
// Used to obtain the simple (unqualified) string name of a type.
|
// Used to obtain the simple (unqualified) string name of a type.
|
||||||
#define NAMEOF_TYPE(name) ::nameof::NameofType<decltype(name)>(false)
|
#define NAMEOF_TYPE(name) ::nameof::NameofType<decltype(name)>(false)
|
||||||
|
|
||||||
// Used to obtain the full string name of a type.
|
// Used to obtain the raw string name of a type.
|
||||||
#define NAMEOF_TYPE_FULL(name) ::nameof::NameofType<decltype(name)>(true)
|
#define NAMEOF_TYPE_RAW(name) ::nameof::NameofType<decltype(name)>(true)
|
||||||
|
|
124
test/test.cpp
124
test/test.cpp
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#include <nameof.hpp>
|
#include <nameof.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -50,10 +49,16 @@ T SomeMethod4() {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
public:
|
public:
|
||||||
void SomeMethod5() const {}
|
void SomeMethod5() const {
|
||||||
|
std::cout << nameof::NameofType<T>(false) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
C SomeMethod6() const { return C{}; }
|
C SomeMethod6() const {
|
||||||
|
C t{};
|
||||||
|
std::cout << NAMEOF_TYPE(t) << std::endl;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Long {
|
struct Long {
|
||||||
|
@ -67,8 +72,11 @@ enum class Color { RED, GREEN, BLUE };
|
||||||
|
|
||||||
SomeStruct somevar;
|
SomeStruct somevar;
|
||||||
Long othervar;
|
Long othervar;
|
||||||
|
SomeStruct& refvar = somevar;
|
||||||
SomeStruct* ptrvar = &somevar;
|
SomeStruct* ptrvar = &somevar;
|
||||||
|
|
||||||
|
#if __cplusplus >= 201402L || (defined(_MSVC_LANG ) && _MSVC_LANG >= 201402L )
|
||||||
|
// Compile-time supported by C++14.
|
||||||
TEST_CASE("constexpr") {
|
TEST_CASE("constexpr") {
|
||||||
SECTION("NAMEOF") {
|
SECTION("NAMEOF") {
|
||||||
// variable
|
// variable
|
||||||
|
@ -105,7 +113,39 @@ TEST_CASE("constexpr") {
|
||||||
constexpr auto cx6 = NAMEOF_RAW(__cplusplus);
|
constexpr auto cx6 = NAMEOF_RAW(__cplusplus);
|
||||||
static_assert(cx6 == "__cplusplus", "");
|
static_assert(cx6 == "__cplusplus", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("NAMEOF_TYPE") {
|
||||||
|
SomeClass<int> a;
|
||||||
|
|
||||||
|
constexpr auto cx1 = NAMEOF_TYPE(a);
|
||||||
|
static_assert(cx1 == "SomeClass", "");
|
||||||
|
|
||||||
|
constexpr auto cx2 = nameof::NameofType<SomeClass<int>>(false);
|
||||||
|
static_assert(cx2 == "SomeClass", "");
|
||||||
|
|
||||||
|
constexpr auto cx3 = nameof::NameofType<decltype(a)>(false);
|
||||||
|
static_assert(cx3 == "SomeClass", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("NAMEOF_TYPE_RAW") {
|
||||||
|
SomeClass<int> a;
|
||||||
|
|
||||||
|
constexpr auto cx1 = NAMEOF_TYPE_RAW(a);
|
||||||
|
constexpr auto cx2 = nameof::NameofType<SomeClass<int>>(true);
|
||||||
|
constexpr auto cx3 = nameof::NameofType<decltype(a)>(true);
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
static_assert(cx1 == "class SomeClass<int>", "");
|
||||||
|
static_assert(cx2 == "class SomeClass<int>", "");
|
||||||
|
static_assert(cx3 == "class SomeClass<int>", "");
|
||||||
|
#else
|
||||||
|
static_assert(cx1 == "SomeClass<int>", "");
|
||||||
|
static_assert(cx2 == "SomeClass<int>", "");
|
||||||
|
static_assert(cx3 == "SomeClass<int>", "");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_CASE("simple name") {
|
TEST_CASE("simple name") {
|
||||||
SECTION("variable") {
|
SECTION("variable") {
|
||||||
|
@ -134,6 +174,7 @@ TEST_CASE("simple name") {
|
||||||
REQUIRE(NAMEOF(Color::BLUE) == "BLUE");
|
REQUIRE(NAMEOF(Color::BLUE) == "BLUE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("raw name") {
|
TEST_CASE("raw name") {
|
||||||
SECTION("variable") {
|
SECTION("variable") {
|
||||||
REQUIRE(NAMEOF_RAW(somevar) == "somevar");
|
REQUIRE(NAMEOF_RAW(somevar) == "somevar");
|
||||||
|
@ -184,42 +225,63 @@ TEST_CASE("raw name") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("type name") {
|
||||||
|
REQUIRE(NAMEOF_TYPE(somevar) == "SomeStruct");
|
||||||
|
REQUIRE(NAMEOF_TYPE(ptrvar) == "SomeStruct");
|
||||||
|
REQUIRE(NAMEOF_TYPE(refvar) == "SomeStruct");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE(othervar) == "Long");
|
||||||
|
REQUIRE(NAMEOF_TYPE(othervar.ll) == "LL");
|
||||||
|
REQUIRE(NAMEOF_TYPE(othervar.ll.field) == "int");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE(Color::RED) == "Color");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE(std::string{}) == "basic_string");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE(std::declval<const SomeClass<int>>()) == "SomeClass");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("type raw name") {
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(somevar) == "struct SomeStruct");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(ptrvar) == "structSomeStruct*");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(refvar) == "structSomeStruct&");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(othervar) == "struct Long");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(othervar.ll) == "struct Long::LL");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(othervar.ll.field) == "int");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(Color::RED) == "enum Color");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(std::declval<const SomeClass<int>>()) == "const classSomeClass<int>&&");
|
||||||
|
#else
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(somevar) == "SomeStruct");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(ptrvar) == "SomeStruct*");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(refvar) == "SomeStruct&");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(othervar) == "Long");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(othervar.ll) == "Long::LL");
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(othervar.ll.field) == "int");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(Color::RED) == "Color");
|
||||||
|
|
||||||
|
REQUIRE(NAMEOF_TYPE_RAW(std::declval<const SomeClass<int>>()) == "const SomeClass<int>&&");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Spaces and Tabs ignored") {
|
TEST_CASE("Spaces and Tabs ignored") {
|
||||||
SECTION("Spaces") {
|
SECTION("Spaces") {
|
||||||
// variable
|
|
||||||
REQUIRE(NAMEOF( somevar ) == "somevar");
|
REQUIRE(NAMEOF( somevar ) == "somevar");
|
||||||
REQUIRE(NAMEOF_RAW( somevar ) == "somevar");
|
REQUIRE(NAMEOF_RAW( somevar ) == "somevar");
|
||||||
// member
|
REQUIRE(NAMEOF_TYPE( int{} ) == "int");
|
||||||
REQUIRE(NAMEOF( (&somevar)->somefield ) == "somefield");
|
REQUIRE(NAMEOF_TYPE_RAW( int{} ) == "int");
|
||||||
REQUIRE(NAMEOF_RAW( (&somevar)->somefield ) == "(&somevar)->somefield");
|
|
||||||
// type
|
|
||||||
REQUIRE(NAMEOF_RAW( std::string ) == "std::string");
|
|
||||||
// function
|
|
||||||
REQUIRE(NAMEOF( &SomeStruct::SomeMethod2 ) == "SomeMethod2");
|
|
||||||
REQUIRE(NAMEOF_RAW( &SomeStruct::SomeMethod2 ) == "&SomeStruct::SomeMethod2");
|
|
||||||
// enum
|
|
||||||
REQUIRE(NAMEOF( Color::RED ) == "RED");
|
|
||||||
REQUIRE(NAMEOF_RAW( Color::RED ) == "Color::RED");
|
|
||||||
// macros
|
|
||||||
REQUIRE(NAMEOF_RAW( __cplusplus ) == "__cplusplus");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Tabs") {
|
SECTION("Tabs") {
|
||||||
// variable
|
|
||||||
REQUIRE(NAMEOF( somevar ) == "somevar");
|
REQUIRE(NAMEOF( somevar ) == "somevar");
|
||||||
REQUIRE(NAMEOF_RAW( somevar ) == "somevar");
|
REQUIRE(NAMEOF_RAW( somevar ) == "somevar");
|
||||||
// member
|
REQUIRE(NAMEOF_TYPE( int{} ) == "int");
|
||||||
REQUIRE(NAMEOF( (&somevar)->somefield ) == "somefield");
|
REQUIRE(NAMEOF_TYPE_RAW( int{} ) == "int");
|
||||||
REQUIRE(NAMEOF_RAW( (&somevar)->somefield ) == "(&somevar)->somefield");
|
|
||||||
// type
|
|
||||||
REQUIRE(NAMEOF_RAW( std::string ) == "std::string");
|
|
||||||
// function
|
|
||||||
REQUIRE(NAMEOF( &SomeStruct::SomeMethod2 ) == "SomeMethod2");
|
|
||||||
REQUIRE(NAMEOF_RAW( &SomeStruct::SomeMethod2 ) == "&SomeStruct::SomeMethod2");
|
|
||||||
// enum
|
|
||||||
REQUIRE(NAMEOF( Color::RED ) == "RED");
|
|
||||||
REQUIRE(NAMEOF_RAW( Color::RED ) == "Color::RED");
|
|
||||||
// macros
|
|
||||||
REQUIRE(NAMEOF_RAW( __cplusplus ) == "__cplusplus");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue