neargye / nameof Goto Github PK
View Code? Open in Web Editor NEWNameof operator for modern C++, simply obtain the name of a variable, type, function, macro, and enum
License: MIT License
Nameof operator for modern C++, simply obtain the name of a variable, type, function, macro, and enum
License: MIT License
We should refactor out the copy of the Catch2 library.
We could probably use a find_package(Catch2)
in the corresponding cmake or something similar.
I'm going to look for a solution.
This is more a feature request/idea than issue. But it would be possibly more useful if NAMEOF_ENUM
could fallback to using NAMEOF_TYPE
with the literal underlying value something like this example.
enum Colour { Red, Green, Blue = 0xFFFFFFFF };
Blue would be definitely out of range. So instead of Blue
you would get Colour[4294967295]
or in hex Colour[0xFFFFFFFF]
This seems useful in providing partial support for enums with large ranges.
Hi, This project suport C++11?
Add API nameof::cstring to https://github.com/Neargye/nameof/blob/master/doc/reference.md
The library makes use of std::free
which interferes with the way cpputest uses define macros to override the instances of free (see https://github.com/cpputest/cpputest/blob/master/include/CppUTest/MemoryLeakDetectorMallocMacros.h#L39). This will cause compilation errors to complain that std::cpputest_free_location doesn't exist (which it doesn't in that namespace).
Looking into seeing where the fix should go (here or a in CppUTest) the easiest is definitely here. So I looked to the implemenations to see if I could provide some evidence that dropping the std::
prefix was valid.
Looking into the implemenations for __cxa_demangle
use (see https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/libiberty/cp-demangle.c#L6496). They seem to use the unprefixed variant.
As it turned out somebody already uploaded this library to Vcpkg's repository.
We should keep this in mind if we tag a new release, to issue a PR to Vcpkg's repository where we update the refs of the latest release.
https://github.com/microsoft/vcpkg/blob/master/ports/nameof/CONTROL
Maybe integrate into the CI loop? Or do this manually? - I'm not familiar with Vcpkg.
Maybe add some reference/badge to the README.md
which would advertise the Vcpkg as well besides Conan.
Hello, the following code snippet doesn't compile on MSVC (2022), but works fine with clang and gcc:
struct TestStruct{
std::string teststringfield = std::string{nameof::nameof_member<&TestStruct::teststringfield>()};
};
auto test = TestStruct{};
REQUIRE(test.teststringfield == "teststringfield");
There are several questions to the structure of your CMakeLists.txt.
CMakeLists.txt:7-11
link thereif(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(IS_TOPLEVEL_PROJECT TRUE)
else()
set(IS_TOPLEVEL_PROJECT FALSE)
endif()
example/CMakeLists.txt
link thereinclude(CheckCXXCompilerFlag)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
check_cxx_compiler_flag(-std=c++17 HAS_CPP17_FLAG)
if(!HAS_CPP17_FLAG)
MESSAGE(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support.")
endif()
set(CMAKE_VERBOSE_MAKEFILE ON)
set(OPTIONS -Wall -Wextra -pedantic-errors -Werror -std=c++17)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
check_cxx_compiler_flag(/std:c++17 HAS_CPP17_FLAG)
# more ...
nameof
target, instead of just simply including the nameof header. link thereadd_executable(example
example.cpp
${CMAKE_SOURCE_DIR}/include/${CMAKE_PROJECT_NAME}.hpp)
Is it a bad practice to bake in the projects name? I think that would be more readable than using the ${CMAKE_PROJECT_NAME}
. (It's only a question.)
What is going on in test/CMakeLists.txt
I don't really get it. Like creating two test binaries, but why?
I think it should be simplified. It also suffers from the problem which I described at the second bullet-point. link there
if(HAS_CPP17_FLAG)
make_test(${CMAKE_PROJECT_NAME}-cpp17.t c++17)
endif()
if(HAS_CPPLATEST_FLAG)
make_test(${CMAKE_PROJECT_NAME}-cpplatest.t c++latest)
endif()
Will try to find the code that triggers this when I have time.
...\nameof.hpp (579, 0)
...\nameof.hpp(579,0): Warning C28020: The expression '0<=Param(1)&&Param(1)<=1-1' is not true at this call.
I have submitted the package to AUR (Archlinux User Repository), Archlinux users could install nameof.hpp
to their system by package manager, using the following command:
yay -S nameof
Could you please add the information to Integration
section in README.md
?
I have a class with a method named MyMethod
.
class MyClass {
public:
void MyMethod() {}
};
using MyClassMethodType = void (MyClass*) ();
std::string GetMethodName(MyClassMethodType a) {
return std::string { NAMEOF_XXX(a) };
}
Now, GetMethodName
will return the string a
. That's not what I want.
I'd like to GetMethodName()
returns the method name MyMethod
or MyClass::MyMethod
.
Is it able to do that without rewriting the GetMethodName()
with macro?
How does this project compare to magic_enum?
Since this project supports "Enum to string", is this a superset of magic_enum?
Thanks for the great library!
In my enum type, i want use a special member to represent the invalid value. So i use a underlying_type's max value to define an invalid value.
But NAMEOF_ENUM
gives me an empty name string, if i change the invalid value to another value, it seems everything is ok.
I use is on Windows 10 with MSVC 17.4.2, /std:c++20, lib version is 0.10.2
Here is the reproduce code.
#include <cstdint>
#include <iostream>
#include <nameof.hpp>
enum class Media : std::uint8_t {
Air = 0,
Oil = 1,
Invalid = 10,
Invalid1 = std::numeric_limits<std::uint8_t>::max()
};
int main() {
{
auto constexpr m = Media::Air;
std::cout << NAMEOF_ENUM(m) << std::endl; // "Air"
}
{
auto constexpr m = Media::Oil;
std::cout << NAMEOF_ENUM(m) << std::endl; // "Oil"
}
{
auto constexpr m = Media::Invalid;
std::cout << NAMEOF_ENUM(m) << std::endl; // "Invalid"
}
{
auto constexpr m = Media::Invalid1;
std::cout << NAMEOF_ENUM(m) << std::endl; // empty name string
std::cout << NAMEOF_ENUM(Media::Invalid1) << std::endl; // empty name string, too
}
}
I see that there's an operator std::string_view
; could you add an operator std::string
? Functions that take a std::string require an explicit cast to pass in.
Example:
void foo(const std::string &asdf) {}
void bar()
{
const char *foo1;
foo(NAMEOF(foo1)); // error: no suitable user-defined conversion from "nameof::cstring<4UL>" to "const std::string" exists
foo(NAMEOF(foo1).data()); // ok
foo(std::string(NAMEOF(foo1))); // ok
}
This is compiling using MSVC's CL version 19.00.24234.1
If I set NAMEOF_ENUM_RANGE_MAX
to 3590
(or more) then I receive the error C2131:
nameof-v0.10.3\include\nameof.hpp(714,52): error C2131: expression did not evaluate to a constant
If NAMEOF_ENUM_RANGE_MAX <= 3580
, it works fine.
The limitations say I could go up to INT16_MAX
(32766). What am I missing?
#define NAMEOF_ENUM_RANGE_MIN 0
#define NAMEOF_ENUM_RANGE_MAX 3590 // <= 3580 or less would work.
#include <nameof.hpp>
enum class TestType: uint32_t { None = 0 };
auto none = nameof::nameof_enum(TestType::None);
Visual Studio 17.7.2;
/std:c++latest
nameof v0.10.3
Until C++20, MSVC doesn't supply the member name from member pointer in __FUNCSIG__
.
https://godbolt.org/z/nbGMMjrTf
With this technique, from the member pointer can be extract the member name.
Based on documentation, looks like it does not support yet?
For the following template class:
template <typename T>
class SomeClass {};
msvc and gcc returns different results for the following expression:
nameof::nameof_type<SomeClass<int>>()
msvc returns class SomeClass<int>
unlike gcc which returns just SomeClass<int>
.
Should it be in this way?
Just out of curiosity, is there a reason for using a macro for NAMEOF_ENUM
or 'NAMEOF_TYPE
? or is it just to be consistent with the rest of the NAMEOFs that actually require token pasting?
It would be nice if it was apparent from README
in the past, I used tostr to get enum string, I found nameof is very strong, but is this fast? will it slow down if i use it a lot?
#include "nameof.hpp"
#include <iostream>
struct A {
enum Enum : char {
AA = 'A',
BB = 'B'
};
[[nodiscard]] static std::string_view ToStr(Enum e) {
return NAMEOF_ENUM(e);
}
static std::string tostr(Enum e) {
if (e == A::AA) return "AA";
else return "BB";
}
};
int main() {
A::Enum t = A::AA;
std::string_view a = A::ToStr(t);
std::cout << a << std::endl;
}
Add a new macro like NAMEOF_POINTER
based on NAMEOF_MEMBER
but works with only pointers. This pointer can be a global or a member static variable too.
The current detail::n<ptr>()
is working as expected with minimal modification.
I created a branch where I experimented with these inside the `member˙ functions and It works.
Similar to Issue #15 previously resolved.
This MSVC static code analysis warning is triggered by code like this:
auto enu = static_cast<SOME_ENUM_t>(nSomeEnumeratorValue);
if (!nameof::nameof_enum(enu).empty()) { ... }
struct A{};
class B{};
enum C{};
template<typename T>
class D{};
constexpr auto name_A = nameof::nameof_type<A>(); // "struct A"
constexpr auto name_B = nameof::nameof_type<B>(); // "class B"
constexpr auto name_C = nameof::nameof_type<C>(); // "enum C"
constexpr auto name_D_A = nameof::nameof_type<D<A>>(); // "class D<struct A>"
but I want
name_A == "A"
name_B == "B"
name_C == "C"
name_D_A == D<A>
Is it possible to get them in compile-time?
Thank you for this excellent program that has helped me so much in my work!
I currently have a problem that after upgrading the MSVC version to 17.2.2, the previous code does not compile properly.
packages are configured via vcpkg and all up to date.
as follows.(compiled with -std=c++20)
#include <nameof.hpp>
#include <fmt/format.h>
enum class ObjectiveLensMedia {
Air = 0,
Oil = 1
};
int main() {
fmt::print("{}.\n", NAMEOF_ENUM(ObjectiveLensMedia::Air));
}
Will give me a static assert failed with message 'nameof::nameof_enum requires enum implementation and valid max and min.'.
I'm very confused about this and would like help, a lot of my code depends on this.
Thank you very much!
Hi, I finally got around to updating nameof in my project to test the fix of #46 by @schaumb.
Unfortunately, it doesn't work when TestStruct
has a member with a non-constexpr user-provided constructor. Is it possible to fix it?
I looked into the source, but I don't understand the union trick used in the member_name_v
implementation for MSVC, so I can't tell if it can be fixed.
As previously, the following code doesn't compile on MSVC (2022) using the latest master of nameof
, but works fine with clang and gcc
struct Foo{
~Foo(){};
};
struct TestStruct{
std::string teststringfield = std::string{nameof::nameof_member<&TestStruct::teststringfield>()};
Foo foo;
};
Hi guys. Today Micorsoft release VS2022 17.2, then the nameof is not happy with "Error C2338: static_assert failed: 'nameof::nameof_enum requires enum implementation and valid max and min.'"
The code is in 897 line:
static_assert(detail::count_v<D> > 0, "nameof::nameof_enum requires enum implementation and valid max and min.");
With the NAMEOF_ENUM_RANGE_MIN and NAMEOF_ENUM_RANGE_MAX set to [0, N] an enum like the following seems to produce an incorrect warning message.
#include <cstdint>
enum Test : uint32_t
{
First = 0,
Last = 0xFFFFFFFF,
};
[build] ../../tests/nameof.hpp:526:21: error: static assertion failed: nameof::enum_range detects enum value smaller than min range size.
[build] 526 | static_assert(!is_valid<E, value<E, lhs - 1, IsFlags>(0)>(), "nameof::enum_range detects enum value smaller than min range size.");
I would expect the warning to be something line "enum larger than the max range size"
I did not find your email address, so I write to you here.
I created a Conan recipe for your package. You can find it here: https://github.com/steakhal/conan-nameof
If you are no familiar with Conan, you can find more about it here: https://conan.io/
tldr. it is a package manager for c++
We can merge the recipe into your repository if you want to.
Our nightly static code analysis build with VS 2017 15.9.4 reported this warning:
Severity Code Description Line File Project Suppression State
Warning C26495 Variable 'nameof::cstring<14>::chars' is uninitialized. Always initialize a member variable (type.6). 92 c:\users\hutchinsons\source\dart\ng-dart\source\vs2012\ng-dart base\nameof.hpp NG-DART Active
I attempted to fix it by changing const std::array<char, N + 1> chars;
to const std::array<char, N + 1> chars{ {} };
, but that did not help.
Any idea how to fix this? Thanks
Example code:
struct Foo
{
int bar;
};
nameof::nameof_member<&Foo::bar>() // bar
Example "impl": https://godbolt.org/z/jx97n9
Maybe even add member function names?
This is a really nice feature to have.
I am doing this currently and I hate it, do you have any suggestions, with nameof?
Thanks,
Etorth
Stack:
C:\Users\PC\vcpkg\installed\x64-windows\include\nameof.hpp(956.19): message : see reference to variable template 'const auto static_v<nameof::detail::union_type >' compiled
1>C:\Users\PC\vcpkg\installed\x64-windows\include\nameof.hpp(961,1): message : compiled template function 'auto nameof::detail::get_member_name<pointer-to-member(0x10) See reference for creating )>(void) noexcept' instance
1>C:\Users\PC\vcpkg\installed\x64-windows\include\nameof.hpp(1098,40): message : see reference to compiled variable template 'const auto member_name_v<16>'
1>C:\Users\PC\Desktop\cartelsol\moscam-be\Entity\include\Entity/Spouse.h(28,41): message : compiled template function 'std::basic_string_view<char,std::char_traits< See reference to create char>> nameof::nameof_member<pointer-to-member(0x10)>(void) noexcept' instance
1>C:\Users\PC\vcpkg\installed\x64-windows\include\nameof.hpp(956.69): error C2296: '.*': not valid because left operand has type 'const int'
1>C:\Users\PC\vcpkg\installed\x64-windows\include\nameof.hpp(1099.29): error C2338: static_assert failed: 'Member does not have a name.'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.