add doc
This commit is contained in:
parent
96ac608d13
commit
4319be3c2e
3 changed files with 323 additions and 86 deletions
91
README.md
91
README.md
|
@ -33,6 +33,11 @@ Header-only C++17 library provides nameof macros and functions to simply obtain
|
|||
* Name of macro
|
||||
* Enum to string
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Reference](doc/reference.md)
|
||||
* [limitations](doc/limitations.md)
|
||||
|
||||
## [Examples](example/example.cpp)
|
||||
|
||||
* Nameof
|
||||
|
@ -97,92 +102,6 @@ Header-only C++17 library provides nameof macros and functions to simply obtain
|
|||
// type_name -> "int"
|
||||
```
|
||||
|
||||
## Remarks
|
||||
|
||||
* Nameof returns `std::string_view`. If argument does not have name, returns empty string.
|
||||
|
||||
* Nameof expression argument are identified, but are not evaluated.
|
||||
|
||||
* Nameof type returns compiler-specific type name. In all cases, reference and cv-qualifiers are ignored by `nameof_type` (that is, `nameof_type<const T&>() == nameof_type<T>()`). If you need detailed name of full type, use `nameof_full_type`.
|
||||
|
||||
* If you need name with template suffix, use NAMEOF_FULL.
|
||||
```cpp
|
||||
// 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.
|
||||
```cpp
|
||||
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`.
|
||||
```cpp
|
||||
#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.
|
||||
```cpp
|
||||
#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.
|
||||
```cpp
|
||||
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:
|
||||
```cpp
|
||||
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](include/nameof.hpp).
|
||||
|
|
82
doc/limitations.md
Normal file
82
doc/limitations.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
# Nameof
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
# Nameof Type
|
||||
|
||||
* This library uses a compiler-specific hack (based on `__PRETTY_FUNCTION__` / `__FUNCSIG__`), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 7.
|
||||
|
||||
* Nameof type returns compiler-specific type name.
|
||||
|
||||
* In all cases, reference and cv-qualifiers are ignored by `nameof_type` (that is, `nameof_type<const T&>() == nameof_type<T>()`).
|
||||
|
||||
* If you need detailed name of full type, use `nameof_full_type`.
|
||||
|
||||
# Nameof Enum
|
||||
|
||||
* This library uses a compiler-specific hack (based on `__PRETTY_FUNCTION__` / `__FUNCSIG__`), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 9.
|
||||
|
||||
* Enum can't reflect if the enum is a forward declaration.
|
||||
|
||||
* Enum value must be in range `[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]`. By default `MAGIC_ENUM_RANGE_MIN = -128`, `MAGIC_ENUM_RANGE_MAX = 128`.
|
||||
|
||||
* If need another range for all enum types by default, redefine the macro `MAGIC_ENUM_RANGE_MIN` and `MAGIC_ENUM_RANGE_MAX`.
|
||||
```cpp
|
||||
#define MAGIC_ENUM_RANGE_MIN 0
|
||||
#define MAGIC_ENUM_RANGE_MAX 256
|
||||
#include <magic_enum.hpp>
|
||||
```
|
||||
|
||||
* If need another range for specific enum type, add specialization `enum_range` for necessary enum type.
|
||||
```cpp
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
enum number { one = 100, two = 200, three = 300 };
|
||||
|
||||
namespace magic_enum {
|
||||
template <>
|
||||
struct enum_range<number> {
|
||||
static constexpr int min = 100;
|
||||
static constexpr int max = 300;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
* `magic_enum` obtains the first defined value enums, and won't work if value are aliased.
|
||||
```cpp
|
||||
enum ShapeKind {
|
||||
ConvexBegin = 0,
|
||||
Box = 0, // Won't work.
|
||||
Sphere = 1,
|
||||
ConvexEnd = 2,
|
||||
Donut = 2, // Won't work too.
|
||||
Banana = 3,
|
||||
COUNT = 4,
|
||||
};
|
||||
// magic_enum::enum_cast<ShapeKind>("Box") -> std::nullopt
|
||||
// magic_enum::enum_name(ShapeKind::Box) -> "ConvexBegin"
|
||||
```
|
||||
Work around the issue:
|
||||
```cpp
|
||||
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,
|
||||
};
|
||||
// magic_enum::enum_cast<ShapeKind>("Box") -> ShapeKind::Box
|
||||
// magic_enum::enum_name(ShapeKind::Box) -> "Box"
|
||||
|
||||
// Non-reflected aliases.
|
||||
// magic_enum::enum_cast<ShapeKind>("ConvexBegin") -> std::nullopt
|
||||
// magic_enum::enum_name(ShapeKind::ConvexBegin) -> "Box"
|
||||
```
|
236
doc/reference.md
Normal file
236
doc/reference.md
Normal file
|
@ -0,0 +1,236 @@
|
|||
# Reference
|
||||
|
||||
* [`NAMEOF` macro that obtains simple (unqualified) string name of variable, function, macro.](#NAMEOF)
|
||||
* [`NAMEOF_FULL` macro that obtains simple (unqualified) full (with template suffix) string name of variable, function, macro.](#NAMEOF_FULL)
|
||||
* [`NAMEOF_RAW` macro that obtains raw string name of variable, function, macro.](#NAMEOF_RAW)
|
||||
* [`nameof_enum(E value)` function that obtains simple (unqualified) string enum name of enum variable.](#nameof_enum(value))
|
||||
* [`nameof_enum<auto V>()` function that obtains simple (unqualified) string enum name of static storage enum variable.](#nameof_enum<Value>())
|
||||
* [`NAMEOF_ENUM` macro that obtains simple (unqualified) string enum name of enum variable.](#NAMEOF_ENUM)
|
||||
* [`NAMEOF_CONST_ENUM` macro that obtains simple (unqualified) string enum name of static storage enum variable.](#NAMEOF_CONST_ENUM)
|
||||
* [`nameof_type<T>()` function that obtains string name of type, reference and cv-qualifiers are ignored.](#nameof_type<T>())
|
||||
* [`nameof_full_type<T>()` function that obtains string name of full type, with reference and cv-qualifiers.](#nameof_full_type<T>())
|
||||
* [`NAMEOF_TYPE` macro that obtains string name of type, reference and cv-qualifiers are ignored.](#NAMEOF_TYPE)
|
||||
* [`NAMEOF_FULL_TYPE` macro that obtains string name of full type, with reference and cv-qualifiers.](#NAMEOF_FULL_TYPE)
|
||||
* [`NAMEOF_TYPE_EXPR` macro that obtains string name type of expression, reference and cv-qualifiers are ignored.](#NAMEOF_TYPE_EXPR)
|
||||
* [`NAMEOF_FULL_TYPE_EXPR` macro that obtains string name full type of expression, with reference and cv-qualifiers.](#NAMEOF_FULL_TYPE_EXPR)
|
||||
|
||||
## `NAMEOF`
|
||||
|
||||
* Macro that obtains simple (unqualified) string name of variable, function, macro.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
// 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_FULL`
|
||||
|
||||
* Macro that obtains simple (unqualified) full (with template suffix) string name of variable, function, macro.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
// 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>"
|
||||
```
|
||||
|
||||
## `NAMEOF_RAW`
|
||||
|
||||
* Macro that obtains raw string name of variable, function, macro.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
NAMEOF_RAW(::somevar.somefield) -> "::somevar.somefield"
|
||||
NAMEOF_RAW(&some_class::some_method<int>) -> "&some_class::some_method<int>"
|
||||
```
|
||||
|
||||
## `nameof_enum(value)`
|
||||
|
||||
* Function that obtains simple (unqualified) string enum name of enum variable.
|
||||
|
||||
* Returns `std::string_view`.
|
||||
|
||||
* If argument does not have name, returns empty `std::string_view`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
auto color = Color::RED;
|
||||
nameof::nameof_enum(color) -> "RED"
|
||||
```
|
||||
|
||||
## `nameof_enum<Value>()`
|
||||
|
||||
* Function that obtains simple (unqualified) string enum name of static storage enum variable.
|
||||
|
||||
* Returns `std::string_view`.
|
||||
|
||||
* This version is much lighter on the compile times and is not restricted to the enum_range [limitation](limitations.md).
|
||||
|
||||
* If argument does not have name, returns empty `std::string_view`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
nameof::nameof_enum<Color::GREEN>() -> "GREEN"
|
||||
```
|
||||
|
||||
## `NAMEOF_ENUM`
|
||||
|
||||
* Macro that obtains simple (unqualified) string enum name of enum variable.
|
||||
|
||||
* Returns `std::string_view`.
|
||||
|
||||
* If argument does not have name, returns empty `std::string_view`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
auto color = Color::RED;
|
||||
NAMEOF_ENUM(color) -> "RED"
|
||||
```
|
||||
|
||||
## `NAMEOF_CONST_ENUM`
|
||||
|
||||
* Macro macro that obtains simple (unqualified) string enum name of static storage enum variable.
|
||||
|
||||
* Returns `std::string_view`.
|
||||
|
||||
* This version is much lighter on the compile times and is not restricted to the enum_range [limitation](limitations.md).
|
||||
|
||||
* If argument does not have name, returns empty `std::string_view`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
NAMEOF_CONST_ENUM(Color::GREEN) -> "GREEN"
|
||||
```
|
||||
|
||||
## `nameof_type<T>()`
|
||||
|
||||
* Function macro that obtains string name of type, reference and cv-qualifiers are ignored.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* In all cases, reference and cv-qualifiers are ignored by `nameof_type` (that is, `nameof_type<const T&>() == nameof_type<T>()`).
|
||||
|
||||
* Returns compiler-specific type name.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
using T = const int&;
|
||||
nameof::nameof_type<T>() -> "int"
|
||||
```
|
||||
|
||||
## `nameof_full_type<T>()`
|
||||
|
||||
* Function that obtains string name of full type, with reference and cv-qualifiers.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* Returns compiler-specific type name.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
using T = const int&;
|
||||
nameof::nameof_full_type<T>() -> "const int&"
|
||||
```
|
||||
|
||||
## `NAMEOF_TYPE`
|
||||
|
||||
* Macro macro that obtains string name of type, reference and cv-qualifiers are ignored.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* In all cases, reference and cv-qualifiers are ignored by `NAMEOF_TYPE` (that is, `NAMEOF_TYPE(const T&) == NAMEOF_TYPE(T)`).
|
||||
|
||||
* Returns compiler-specific type name.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
using T = const int&;
|
||||
NAMEOF_TYPE(T) -> "int"
|
||||
```
|
||||
|
||||
## `NAMEOF_FULL_TYPE`
|
||||
|
||||
* Macro that obtains string name of full type, with reference and cv-qualifiers.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* Returns compiler-specific type name.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
using T = const int&;
|
||||
NAMEOF_TYPE(T) -> "const int&"
|
||||
```
|
||||
|
||||
## `NAMEOF_TYPE_EXPR`
|
||||
|
||||
* Macro that obtains string name type of expression, reference and cv-qualifiers are ignored.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* Returns returns compiler-specific type name.
|
||||
|
||||
* In all cases, reference and cv-qualifiers are ignored.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
using T = const int&;
|
||||
T var = 42;
|
||||
NAMEOF_TYPE_EXPR(var) -> "int"
|
||||
```
|
||||
|
||||
## `NAMEOF_TYPE_EXPR`
|
||||
|
||||
* Macro that obtains string name full type of expression, with reference and cv-qualifiers.
|
||||
|
||||
* Returns `nameof::cstring` - constexpr implementation of an string.
|
||||
|
||||
* Returns compiler-specific type name.
|
||||
|
||||
* If argument does not have name, occurs the compilation error `"Expression does not have a name."`.
|
||||
|
||||
* Examples
|
||||
```cpp
|
||||
using T = const int&;
|
||||
T var = 42;
|
||||
NAMEOF_FULL_TYPE_EXPR(var) -> "const int&"
|
||||
```
|
Loading…
Reference in a new issue