Git Product home page Git Product logo

nameof's People

Contributors

alexeydmitriev avatar kamchatka-volcano avatar kolanich avatar neargye avatar saxbophone avatar schaumb avatar sf-zhou avatar steakhal avatar striezel avatar ubpa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nameof's Issues

NAMEOF_ENUM compiled failed with MSVC 17.2.2

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!

Don't bring Catch2 with tests

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.

request: operator std::string

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

Add AUR install guide

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?

[Feature] Add `NAMEOF_POINTER`

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.

  • only at GCC, when member static variable passed as an auto template argument, in PRETTY_FUNCTION closes the name between brackets. This needs to be eliminated.
  • null pointer is handled differently. clang returns with "nullptr", GCC tries to return '0' and MSVC tries to return with '0x0' which are not valid names.

I created a branch where I experimented with these inside the `member˙ functions and It works.

Why use macros for the API?

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?

Is it possible to get the method name which is passed by argument.

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?

Compiling failed with mscv 19.34

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.'

Using nameof_member on structures with non-constexpr destructor fails to compile on MSVC

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;
};

is nameof fast?

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;
}

NAMEOF_ENUM Out-of-Range Fallback to Type and Numerical Display

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.

MSVC puts 'class ' prefix, but gcc doesn't

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?

type name without struct/class/enum

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?

Some questions related to your CMakeLists.txts

There are several questions to the structure of your CMakeLists.txt.

  1. Why branch on this? CMakeLists.txt:7-11 link there
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
    set(IS_TOPLEVEL_PROJECT TRUE)
else()
    set(IS_TOPLEVEL_PROJECT FALSE)
endif()
  1. Why do you try to specify the standard by hand? example/CMakeLists.txt link there
    You could use generator expressions which are well described in this blogpost.
    This would be more readable I think.
include(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 ...
  1. At the same CMakeLists.txt you should depend on the nameof target, instead of just simply including the nameof header. link there
add_executable(example
                    example.cpp
                    ${CMAKE_SOURCE_DIR}/include/${CMAKE_PROJECT_NAME}.hpp)
  1. 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.)

  2. 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()

Incorrect Message with uint32_t enum values

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"

why 'NAMEOF_ENUM' generate an empty name for enum with underlying_type's max value

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 can't compile (C2131) when NAMEOF_ENUM_RANGE_MAX >= 3590

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?

Code:

#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);

Setup

Visual Studio 17.7.2;
/std:c++latest
nameof v0.10.3

Incompatibility with CppUTest MemoryLeakDecector Malloc Macros

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.

MSVC Warning C26495 Variable nameof::cstring<14>::chars is uninitialized

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

This library is on Vcpkg

This library is on Vcpkg

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.