Nameof operator for modern C++, simply obtain the name of a variable, type, function, macro, and enum

Overview
 _   _                             __    _____
| \ | |                           / _|  / ____|_     _
|  \| | __ _ _ __ ___   ___  ___ | |_  | |   _| |_ _| |_
| . ` |/ _` | '_ ` _ \ / _ \/ _ \|  _| | |  |_   _|_   _|
| |\  | (_| | | | | | |  __/ (_) | |   | |____|_|   |_|
|_| \_|\__,_|_| |_| |_|\___|\___/|_|    \_____|

Github releases Conan package Vcpkg package License Build status Build status Codacy badge Try online Compiler explorer

Nameof C++

Header-only C++17 library provides nameof macros and functions to simply obtain the name of a variable, type, function, macro, and enum.

Features

  • C++17
  • Header-only
  • Dependency-free
  • Compile-time
  • Name of variable, member variable
  • Name of type, variable type
  • Name of function, member function
  • Name of enum, enum variable
  • Name of macro
  • Enum to string

Documentation

Examples

  • Nameof

    // Name of variable.
    NAMEOF(somevar) -> "somevar"
    
    // Name of member variable.
    NAMEOF(person.address.zip_code) -> "zip_code"
    
    // Name of function.
    NAMEOF(foo<int, float>()) -> "foo"
    
    // Name of member function.
    NAMEOF(somevar.some_method()) -> "some_method"
    NAMEOF(somevar.some_method<int>()) -> "some_method"
    
    // Name of macro.
    NAMEOF(__LINE__) -> "__LINE__"
    NAMEOF(NAMEOF(structvar)) -> "NAMEOF"
  • Nameof enum

    enum class Color { RED = 1, BLUE = 2, GREEN = 4 };
    
    auto color = Color::RED;
    // Name of enum variable.
    NAMEOF_ENUM(color) -> "RED"
    nameof::nameof_enum(color) -> "RED"
    
    // Static storage enum variable to string.
    // This version is much lighter on the compile times and is not restricted to the enum_range limitation.
    NAMEOF_ENUM_CONST(Color::GREEN) -> "GREEN"
    nameof::nameof_enum<Color::GREEN>() -> "GREEN"
    
    // Enum flag variable to string.
    NAMEOF_ENUM_FLAG(Color::GREEN | Color::BLUE) -> "GREEN|BLUE"
    nameof::nameof_enum_flag<Color::GREEN>() -> "GREEN|BLUE"
  • Nameof type

    const my::detail::SomeClass<int>& var_ref = var;
    // Name of variable type.
    NAMEOF_TYPE_EXPR(var_ref) -> "my::detail::SomeClass<int>"
    nameof::nameof_type<decltype(var_ref)>() -> "my::detail::SomeClass<int>"
    NAMEOF_FULL_TYPE_EXPR(var_ref) -> "const my::detail::SomeClass<int>&"
    nameof::nameof_full_type<decltype(var_ref)>() -> "const my::detail::SomeClass<int>&"
    NAMEOF_SHORT_TYPE_EXPR(var_ref) -> "SomeClass"
    nameof::nameof_short_type<decltype(var_ref)>() -> "SomeClass"
    
    using T = const my::detail::SomeClass<int>&;
    // Name of type.
    NAMEOF_TYPE(T) ->"my::detail::SomeClass<int>"
    nameof::nameof_type<T>() -> "my::detail::SomeClass<int>"
    NAMEOF_FULL_TYPE(T) -> "const my::detail::SomeClass<int>&"
    nameof::nameof_full_type<T>() -> "const my::detail::SomeClass<int>&"
    NAMEOF_SHORT_TYPE(T) -> "SomeClass"
    nameof::nameof_short_type<T>() -> "SomeClass"
    
    my::detail::Base* ptr = new my::detail::Derived();
    // Name of type, using rtti.
    NAMEOF_TYPE_RTTI(*ptr) -> "my::detail::Derived"
    NAMEOF_FULL_TYPE_RTTI(*ptr) -> "volatile const my::detail::Derived&"
    NAMEOF_SHORT_TYPE_RTTI(*ptr) -> "Derived"
  • Compile-time

    constexpr auto somevar_name = NAMEOF(somevar);
    // somevar_name -> "somevar"
    constexpr auto color_name = NAMEOF_ENUM(Color::BLUE); // or nameof::nameof_enum(Color::BLUE)
    // color_name -> "BLUE"
    constexpr auto var_type_name = NAMEOF_TYPE_EXPR(var); // or nameof::nameof_type<decltype(var)>()
    // var_type_name -> "int"
    constexpr auto type_name = NAMEOF_TYPE(T); // or nameof::nameof_type<T>()
    // type_name -> "int"

Remarks

Integration

You should add required file nameof.hpp.

If you are using vcpkg on your project for external dependencies, then you can use the nameof package.

If you are using Conan to manage your dependencies, merely add nameof/x.y.z to your conan's requires, where x.y.z is the release version you want to use.

Alternatively, you can use something like CPM which is based on CMake's Fetch_Content module.

CPMAddPackage(
    NAME nameof
    GITHUB_REPOSITORY Neargye/nameof
    GIT_TAG x.y.z # Where `x.y.z` is the release version you want to use.
)

Compiler compatibility

  • Clang/LLVM >= 5
  • MSVC++ >= 14.11 / Visual Studio >= 2017
  • Xcode >= 10
  • GCC >= 7 (GCC >= 9 for NAMEOF_ENUM)

Licensed under the MIT License

Comments
  • Migrate to conan ci

    Migrate to conan ci

    This PR does the following things:

    • uses conan to acquire Catch2 if and only if the nameof lib is build using the build_test option
    • uses Appveyor and travis to make sure that the nameof library is usable on certain configuration and all the tests pass and the example builds
    • it will upload the package (recipe, nameof.hpp and the generated nameofConfig,cmake ... files) to bintray with the version specified in the conanfile.py.

    Note that

    The CI services can run any time you push a commit, it won't upload any versions to bintray, only if you create a new tag (with any name pattern) like v0.9.1 It won't upload any built binaries (neither tests, nor example), but it will upload the sources of the tests and example, since a consumer may want to build it himself.

    enhancement 
    opened by steakhal 16
  • MSVC Warning C26495 Variable nameof::cstring<14>::chars is uninitialized

    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

    help wanted 
    opened by ScottHutchinson 10
  • MSVC puts 'class ' prefix, but gcc doesn't

    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?

    question 
    opened by steakhal 10
  • Some questions related to your CMakeLists.txts

    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()
    
    question 
    opened by steakhal 9
  • request: operator std::string

    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

    question wontfix 
    opened by arolson101 8
  • Created conan.io recipe for this package.

    Created conan.io recipe for this package.

    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.

    enhancement 
    opened by steakhal 8
  • Error C2338: static_assert failed: 'nameof::nameof_enum requires enum implementation and valid max and min.'

    Error C2338: static_assert failed: 'nameof::nameof_enum requires enum implementation and valid max and min.'

    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.");

    invalid 
    opened by icegull 7
  • add MSVC member pointer name in c++20

    add MSVC member pointer name in c++20

    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.

    enhancement 
    opened by schaumb 5
  • x86 msvc v19.27 static code analysis warning C28020 after updating nameof.hpp to v0.10.0

    x86 msvc v19.27 static code analysis warning C28020 after updating nameof.hpp to v0.10.0

    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.

    opened by ScottHutchinson 5
  • NAMEOF_ENUM Out-of-Range Fallback to Type and Numerical Display

    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.

    opened by avlec 3
  • Incompatibility with CppUTest MemoryLeakDecector Malloc Macros

    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.

    bug 
    opened by avlec 3
  • type name without struct/class/enum

    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?

    enhancement help wanted 
    opened by Ubpa 12
Releases(v0.10.2)
  • v0.10.2(Aug 4, 2022)

    Release v0.10.2

    • add nameof_enum_or
    • add nameof_member for mscv and c++20
    • fix vs2022 build (https://github.com/Neargye/nameof/issues/34) (https://github.com/Neargye/nameof/issues/38)
    • fix (https://github.com/Neargye/nameof/issues/34)
    • fix (https://github.com/Neargye/nameof/issues/39)
    Source code(tar.gz)
    Source code(zip)
    nameof.hpp(42.87 KB)
  • v0.10.1(Jun 21, 2021)

  • v0.10.0(Jan 12, 2021)

    Release v0.10.0

    • Add way to switch std::string and std::string_view to custom type
    • Add syntax for defining custom enum and type names
    • Add NAMEOF_ENUM_FLAG
    • Add NAMEOF_SHORT_TYPE
    • Add NAMEOF_TYPE_RTTI, NAMEOF_FULL_TYPE_RTTI, NAMEOF_SHORT_TYPE_RTTI
    • Add NAMEOF_OPT_INSTALL option in CMakeLists.txt
    • Add detect values out of range: checks for a value at (range_min - 1) and (range_max + 1) and fails compilation with a static_assert if any value is found.
    • Fix hangs Intellisense
    • Fix compiler check
    • Fix build error in gcc
    • Fix build msvc with clang
    • Fix build error in clang
    • [breaking changes] enum_range moved to namespace magic_enum::customize
    Source code(tar.gz)
    Source code(zip)
    nameof.hpp(37.31 KB)
  • v0.9.4(Jun 6, 2020)

  • v0.9.3(Dec 30, 2019)

  • v0.9.2(Oct 19, 2019)

    Release v0.9.2

    • Add documentation.

    • nameof and nameof_type returns nameof::cstring - constexpr implementation of an string.

    • Fix nameof_enum cvref regression.

    • Fix nameof_enum bug signed casts to unsigned in min()/max().

    • Fix nameof_enum calculate reflected range.

    • Improving nameof_enum compile times.

    Source code(tar.gz)
    Source code(zip)
    nameof.hpp(23.85 KB)
  • v0.9.1(Oct 2, 2019)

    Release v0.9.1

    • Less bin size and overhead reduction, thanks @rollbear

    • nameof and nameof_type return static_string convertible to std::string_view or std::string.

    • Add error msg unsupported compiler.

    • Marco NAMEOF_ENUM_SUPPORTED and NAMEOF_TYPE_SUPPORTED to check is compiler compatibility.

    • Fix type cast for unsigned enum.

    Source code(tar.gz)
    Source code(zip)
    nameof.hpp(23.61 KB)
  • v0.9.0(Jul 25, 2019)

    Release v0.9.0

    • Fix build fail with sanitize, see https://github.com/Neargye/magic_enum/issues/6

    • Fix implicit conversion changes signedness.

    • Improving compile times.

    • [breaking changes] nameof_type return name same as typeid. NAMEOF_TYPE - obtains string name of type, reference and cv-qualifiers are ignored.

    • [breaking changes] Rename NAMEOF_VAR_TYPE to NAMEOF_TYPE_EXPR. NAMEOF_TYPE_EXPR - obtains string name type of expression, reference and cv-qualifiers are ignored.

    • Add nameof_full_type. NAMEOF_FULL_TYPE - obtains string name of full type, with reference and cv-qualifiers. NAMEOF_FULL_TYPE_EXPR - obtains string name full type of expression, with reference and cv-qualifiers.

    Source code(tar.gz)
    Source code(zip)
    nameof.hpp(11.85 KB)
  • v0.8.3(May 6, 2019)

Owner
Daniil Goncharov
Daniil Goncharov
Gesture-Detecting-Macro-Keyboard - Glorified Bluetooth macro keyboard with machine learning (TensorFlow Lite for Microcontrollers) running on an ESP32.

Gesture detection tldr; Glorified Bluetooth macro keyboard with machine learning (TensorFlow Lite for Microcontrollers) running on an ESP32. Main feat

Jakob Krantz 69 Oct 26, 2022
A C++14 macro to get the type of the current class without naming it

self_macro C++14 header only library that exposes a macro that creates a type alias for the current class without naming it. Also exposes macros that

Mital Ashok 11 Nov 23, 2022
A simply GUI to change settings in coreboot's CBFS, via the nvramtool utility.

coreboot-configurator A simple GUI to change settings in coreboot's CBFS, via the nvramtool utility. How to install Ubuntu, Linux Mint, elementary OS,

Star Labs 38 Nov 6, 2022
An injector is simply a program that injects some sort of file into your game

example-injector What it injector? An injector is simply a program that injects some sort of file into your game. This could be something as benign as

Speedy 23 Nov 14, 2022
A reflective enum implementation for C++

wise_enum Because reflection makes you wise, not smart wise_enum is a standalone smart enum library for C++11/14/17. It supports all of the standard f

Nir Friedman 269 Nov 28, 2022
Improved Fractions Calculator using structures, user input parsing, and dynamic operator switching

Improved Fractions Calculator Program Structure: Main File: Runs fnctions from various header files. IO.h Header file containing IO functions, Interfa

Colin McCormack 1 Dec 5, 2021
MissionImpossible - A concise C++17 implementation of automatic differentiation (operator overloading)

Mission : Impossible (AutoDiff) Table of contents What is it? News Compilation Meson CMake Examples Jacobian example Complex number example Hessian ac

pixor 18 Oct 13, 2022
C-function for traversing files/directories effectively and calling a given function with each encountered file and a void-pointer as parameters

C-function for traversing files/directories effectively and calling a given function with each encountered file and a void-pointer as parameters

null 1 Jun 27, 2022
Collection of DLL function export forwards for DLL export function proxying

dll-exports Collection of DLL function export forwards for DLL export function proxying. Typical usecase is for backdooring applications for persisten

Magnus Stubman 56 Nov 9, 2022
Cobalt Strike Beacon Object File (BOF) that takes the name of of a PE file as an argument and spawns the process in a suspended state

Beacon Object File (BOF) that spawns an arbitrary process from beacons memory. Supports Parent Process ID (PPID) spoofing & blocking non-MS signed DLLs from loading into the processes memory (some EDR DLLs).

boku 348 Nov 15, 2022
Phan Sang 13 Nov 12, 2022
The Project name is "ATM - Automated Teller Machine" and It is for beginners level Project.

ATM - Automated Teller Machine The Project name is "ATM - Automated Teller Machine" and It is for beginners level Project. What is ATM? An automated t

Sorav Kumar Sharma 1 Nov 7, 2021
The Project name is "ATM - Automated Teller Machine" and It is for beginners level Project.

ATM - Automated Teller Machine The Project name is "ATM - Automated Teller Machine" and It is for beginners level Project. What is ATM? An automated t

Sorav Kumar Sharma 1 Nov 8, 2021
The Project name is "ATM - Automated Teller Machine" and It is for beginners level Project.

ATM - Automated Teller Machine The Project name is "ATM - Automated Teller Machine" and It is for beginners level Project. What is ATM? An automated t

Sorav Kumar Sharma 0 Dec 26, 2021
High Quality DeNoise 3D is an AviSynth port of the MPlayer filter of the same name

High Quality DeNoise 3D is an AviSynth port of the MPlayer filter of the same name. It performs a 3-way low-pass filter, which can completely remove high-frequency noise while minimizing blending artifacts.

null 13 Oct 3, 2022
Pretty much the repo name sums it up.

?? Console_Calculator Version Supported Date Ended Support v.1.0 ✔️ ?? Features The ?? Console_Calculator can do basic arithmatic, and yes there is no

Angelo Petrai 3 Dec 31, 2021
A C implementation of Alien: Fate of the Nostromo, a 2021 board game of the same name

ALIEN: Fate of The Nostromo This is a terminal-based clone of the "ALIEN: Fate of The Nostromo" board game, implemented in C. Installation Debug Insta

Charles Averill 16 Jul 19, 2022