Nameof fork with modules for modern C++, simply obtain the name of a variable, type, function, macro, and enum
Find a file
2019-04-28 15:28:20 +05:00
example remove unused include 2019-04-26 00:42:04 +05:00
include v0.8.2 2019-04-28 15:28:20 +05:00
test update Catch2 2019-04-25 22:38:56 +05:00
.appveyor.yml wip v0.6.0 2019-03-20 21:41:51 +05:00
.gitignore add vscode to gitignore 2019-04-09 02:51:22 +05:00
.travis.yml update ci 2019-04-02 18:47:37 +05:00
CMakeLists.txt v0.8.2 2019-04-28 15:28:20 +05:00
LICENSE wip v0.6.0 2019-03-20 21:41:51 +05:00
README.md v0.8.2 2019-04-28 15:28:20 +05:00

Nameof C++

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

Github Releases License Build Status Build status Codacy Badge Try online

What is Nameof?

Header-only C++17 library provides nameof macros and functions to obtain simple name of 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

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

    auto color = Color::RED;
    // Name of enum variable.
    NAMEOF_ENUM(color) -> "RED"
    nameof::nameof_enum(color) -> "RED"
    
  • Nameof type

    using T = int;
    T var = 42;
    // Name of variable type.
    NAMEOF_VAR_TYPE(var) -> "int"
    nameof::nameof_type<decltype(var)>() -> "int"
    
    // Name of type.
    NAMEOF_TYPE(T) -> "int"
    nameof::nameof_type<T>() -> "int"
    
  • 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_VAR_TYPE(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

  • Nameof returns std::string_view. If argument does not have name, returns empty string.

  • Nameof expression argument are identified, but do not evaluated.

  • Nameof type returns compiler-specific type name.

  • If you need name with template suffix, use NAMEOF_FULL.

    // Full name of template function.
    NAMEOF_FULL(foo<int, float>()) -> "foo<int, float>"
    
    // Full name of template member function.
    NAMEOF_FULL(somevar.some_method<int>()) -> "some_method<int>"
    
  • If you need raw fully-qualified name, use NAMEOF_RAW.

    NAMEOF_RAW(::somevar.somefield) -> "::somevar.somefield"
    NAMEOF_RAW(&some_class::some_method<int>) -> "&some_class::some_method<int>"
    
  • Enum value must be in range [NAMEOF_ENUM_RANGE_MIN, NAMEOF_ENUM_RANGE_MAX]. By default NAMEOF_ENUM_RANGE_MIN = -128, NAMEOF_ENUM_RANGE_MAX = 128.

    If need another range for all enum types by default, redefine the macro NAMEOF_ENUM_RANGE_MIN and NAMEOF_ENUM_RANGE_MAX.

    #define NAMEOF_ENUM_RANGE_MIN 0
    #define NAMEOF_ENUM_RANGE_MAX 256
    #include <nameof.hpp>
    

    If need another range for specific enum type, add specialization enum_range for necessary enum type.

    #include <nameof.hpp>
    
    enum number { one = 100, two = 200, three = 300 };
    
    namespace nameof {
    template <>
    struct enum_range<number> {
      static constexpr int min = 100;
      static constexpr int max = 300;
    };
    }
    
  • Nameof enum obtains the first defined value enums, and won't work if value are aliased.

    enum ShapeKind {
      ConvexBegin = 0,
      Box = 0, // Won't work.
      Sphere = 1,
      ConvexEnd = 2,
      Donut = 2, // Won't work too.
      Banana = 3,
      COUNT = 4,
    };
    // NAMEOF_ENUM(ShapeKind::Box) -> "ConvexBegin"
    // nameof::nameof_enum(ShapeKind::Box) -> "ConvexBegin"
    

    Work around the issue:

    enum ShapeKind {
      // Convex shapes, see ConvexBegin and ConvexEnd below.
      Box = 0,
      Sphere = 1,
    
      // Non-convex shapes.
      Donut = 2,
      Banana = 3,
    
      COUNT = Banana + 1,
    
      // Non-reflected aliases.
      ConvexBegin = Box,
      ConvexEnd = Sphere + 1,
    };
    // NAMEOF_ENUM(ShapeKind::Box) -> "Box"
    // nameof::nameof_enum(ShapeKind::Box) -> "Box"
    
    // Non-reflected aliases.
    // NAMEOF_ENUM(ShapeKind::ConvexBegin) -> "Box"
    // nameof::nameof_enum(ShapeKind::ConvexBegin) -> "Box"
    

Integration

You should add required file nameof.hpp.

Compiler compatibility

  • Clang/LLVM >= 5
  • Visual C++ >= 15.3 / Visual Studio >= 2017
  • Xcode >= 9
  • GCC >= 7 (GCC >= 9 for NAMEOF_ENUM)

Licensed under the MIT License