diff --git a/README.md b/README.md index 1287ee3..c1c2254 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,96 @@ -# nameof(x) c++ +# nameof() c++11 -C++ alternative to [nameOf](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/nameof) operator. +C++ alternative to [nameof](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/nameof) operator. + +Used to obtain the simple name of a variable, type, function. +Before, you had to use string literals to refer to definitions, which is brittle when renaming code elements because tools do not know to check these string literals. + +A nameof expression has this form: -Simple Example: ```cpp -#include -#include +std::cout << NAMEOF(person.Address.zip_code) << std::endl; // prints "zip_code" +``` -struct SomeStruct { - int SomeField; - void SomeMethod() { std::cout << "No called!" << std::endl; } -}; +## Features -int someVar = 0; +* Simple name +* C++11 +* Header-only +* Dependency-free +* Compile-time +* Compilation check -int main() { - SomeStruct someVar{1}; +## [Example & Key Use Cases](https://github.com/Terik23/nameof/blob/master/example/example.cpp) - constexpr auto a = NAMEOF_VAR(someVar.SomeField); - constexpr auto b = NAMEOF_VAR((&someVar)->SomeField); - constexpr auto c = NAMEOF_VAR(someVar); - constexpr auto d = NAMEOF_VAR(::someVar); - constexpr auto e = NAMEOF_VAR(&SomeStruct::SomeMethod); - constexpr auto f = NAMEOF_FUN(someVar.SomeMethod()); - constexpr auto g = NAMEOF_TYPE(SomeStruct); +* Name of a variable, function and etc - std::cout << a << std::endl; // SomeField - std::cout << b << std::endl; // SomeField - std::cout << c << std::endl; // someVar - std::cout << d << std::endl; // someVar - std::cout << e << std::endl; // SomeMethod - std::cout << f << std::endl; // SomeMethod() - std::cout << g << std::endl; // SomeStruct +```cpp +NAMEOF(someVar) -> "someVar" +NAMEOF(someVar.SomeField) -> "SomeField" + +NAMEOF(someVar.SomeMethod1()) -> "SomeMethod1()" +NAMEOF(&SomeStruct::SomeMethod2) -> "SomeMethod2" + +NAMEOF_FUNCTION(someVar.SomeMethod1()) -> "SomeMethod1()" +NAMEOF_FUNCTION(&SomeStruct::SomeMethod2) -> "SomeMethod2" + +NAMEOF_VAR(someVar) -> "someVar" +NAMEOF_VAR(someVar.SomeField) -> "SomeField" +``` + +* Name of type + +```cpp +NAMEOF_TYPE(int[]) -> "int[]" +NAMEOF_TYPE(std::string) -> "string" +NAMEOF_TYPE(std::stringgg) -> error namespace "std" has no member "stringgg" +``` + +* Constexpr + +```cpp +void f() { + int i; + constexpr auto constexpr_work_fine = NAMEOF(i); -> "i" } ``` + +* Compilation check + +```cpp +void f() { + int i; + NAMEOF(i); -> "i" + NAMEOF(iii); -> error identifier "iii" is undefined + NAMEOF_TYPE(std::stringgg) -> error namespace "std" has no member "stringgg" +} +``` + +* Validate parameters + +```cpp +void f(char* s) { + if (s == nullptr) + throw std::invalid_argument(NAMEOF(s)); +} +``` + +* Logging + +```cpp +void f() { + Log(NAMEOF(f), " method entry"); +} +``` + +## Remarks + +If you need to get the fully-qualified name, you can use the NAMEOF_FULL(). For example: + +```cpp +NAMEOF_FULL(someVar.SomeField) -> "someVar.SomeField" +NAMEOF_FULL(&SomeStruct::SomeMethod2) -> "&SomeStruct::SomeMethod2" +NAMEOF_TYPE_FULL(std::string) -> "std::string" +``` + +## License MIT \ No newline at end of file diff --git a/example/example.cpp b/example/example.cpp index 54d1a39..77c2106 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -104,10 +104,16 @@ void TestCase2() { } } +void TestCase3() { + std::cout << NAMEOF_FUNCTION(TestCase3) << " method entry" << std::endl; // TestCase3 method entry +} + int main() { TestCase1(); TestCase2(); + TestCase3(); + return 0; } \ No newline at end of file