Add nameof module support
Some checks failed
macos / macos-13 (push) Has been cancelled
macos / macos-14 (push) Has been cancelled
ubuntu / clang-10 (push) Has been cancelled
ubuntu / clang-11 (push) Has been cancelled
ubuntu / clang-12 (push) Has been cancelled
ubuntu / clang-13 (push) Has been cancelled
ubuntu / clang-14 (push) Has been cancelled
ubuntu / clang-15 (push) Has been cancelled
ubuntu / clang-16 (push) Has been cancelled
ubuntu / clang-9 (push) Has been cancelled
ubuntu / gcc-10 (push) Has been cancelled
ubuntu / gcc-11 (push) Has been cancelled
ubuntu / gcc-12 (push) Has been cancelled
ubuntu / gcc-13 (push) Has been cancelled
ubuntu / gcc-14 (push) Has been cancelled
ubuntu / gcc-9 (push) Has been cancelled
windows / Visual Studio 2019 (push) Has been cancelled
windows / Visual Studio 2022 (push) Has been cancelled
Some checks failed
macos / macos-13 (push) Has been cancelled
macos / macos-14 (push) Has been cancelled
ubuntu / clang-10 (push) Has been cancelled
ubuntu / clang-11 (push) Has been cancelled
ubuntu / clang-12 (push) Has been cancelled
ubuntu / clang-13 (push) Has been cancelled
ubuntu / clang-14 (push) Has been cancelled
ubuntu / clang-15 (push) Has been cancelled
ubuntu / clang-16 (push) Has been cancelled
ubuntu / clang-9 (push) Has been cancelled
ubuntu / gcc-10 (push) Has been cancelled
ubuntu / gcc-11 (push) Has been cancelled
ubuntu / gcc-12 (push) Has been cancelled
ubuntu / gcc-13 (push) Has been cancelled
ubuntu / gcc-14 (push) Has been cancelled
ubuntu / gcc-9 (push) Has been cancelled
windows / Visual Studio 2019 (push) Has been cancelled
windows / Visual Studio 2022 (push) Has been cancelled
This commit is contained in:
parent
6c8e87da57
commit
ad4ba073a3
6 changed files with 599 additions and 351 deletions
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
|
@ -22,6 +22,7 @@ endif()
|
|||
option(NAMEOF_OPT_BUILD_EXAMPLES "Build nameof examples" ${IS_TOPLEVEL_PROJECT})
|
||||
option(NAMEOF_OPT_BUILD_TESTS "Build and perform nameof tests" ${IS_TOPLEVEL_PROJECT})
|
||||
option(NAMEOF_OPT_INSTALL "Generate and install nameof target" ${IS_TOPLEVEL_PROJECT})
|
||||
option(NAMEOF_MODULE "Build nameof module" OFF)
|
||||
|
||||
if(NAMEOF_OPT_BUILD_EXAMPLES)
|
||||
add_subdirectory(example)
|
||||
|
@ -36,14 +37,34 @@ include(CMakePackageConfigHelpers)
|
|||
|
||||
set(EXPORT_NAMESPACE "${PROJECT_NAME}::")
|
||||
|
||||
add_library("${PROJECT_NAME}" INTERFACE)
|
||||
add_library("${EXPORT_NAMESPACE}${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")
|
||||
|
||||
set(INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
if(NAMEOF_MODULE)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
add_library(${PROJECT_NAME})
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${INCLUDES}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE NAMEOF_MODULE)
|
||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
|
||||
|
||||
target_sources(${PROJECT_NAME} PUBLIC FILE_SET nameofModules TYPE CXX_MODULES
|
||||
FILES src/nameof.cpp)
|
||||
else()
|
||||
add_library("${PROJECT_NAME}" INTERFACE)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${INCLUDES}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
endif()
|
||||
|
||||
add_library("${EXPORT_NAMESPACE}${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")
|
||||
|
||||
|
||||
|
||||
|
||||
if(NAMEOF_OPT_INSTALL)
|
||||
list(APPEND CMAKE_MODULE_PATH "${ADDITIONAL_MODULES_DIR}/GenPkgConfig")
|
||||
|
@ -54,6 +75,10 @@ if(NAMEOF_OPT_INSTALL)
|
|||
string(REPLACE "/${CMAKE_LIBRARY_ARCHITECTURE}" "" CMAKE_INSTALL_LIBDIR_ARCHIND "${CMAKE_INSTALL_LIBDIR}")
|
||||
install(TARGETS "${PROJECT_NAME}"
|
||||
EXPORT ${PROJECT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
FILE_SET nameofModules DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
INCLUDES
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
# COMPONENT "${SDK_COMPONENT_NAME}" # component is not allowed for includes! Headers are installed separately! Includes only marks the headers for export
|
||||
|
|
|
@ -12,10 +12,12 @@ endif()
|
|||
function(make_example target)
|
||||
add_executable(${target} ${target}.cpp)
|
||||
set_target_properties(${target} PROPERTIES CXX_EXTENSIONS OFF)
|
||||
target_compile_features(${target} PRIVATE cxx_std_17)
|
||||
target_compile_options(${target} PRIVATE ${OPTIONS})
|
||||
target_link_libraries(${target} PRIVATE ${CMAKE_PROJECT_NAME})
|
||||
endfunction()
|
||||
|
||||
make_example(example)
|
||||
make_example(example_custom_name)
|
||||
if(NAMEOF_MODULE)
|
||||
make_example(example_module)
|
||||
endif()
|
||||
|
|
11
example/example_module.cpp
Normal file
11
example/example_module.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
import nameof;
|
||||
#include <nameof_macro.hpp>
|
||||
|
||||
struct Test {};
|
||||
|
||||
auto main() -> int {
|
||||
auto _ = nameof::nameof_type<Test>();
|
||||
{
|
||||
auto _ = NAMEOF_TYPE(Test);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
149
include/nameof_macro.hpp
Normal file
149
include/nameof_macro.hpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#ifndef NEARGYE_NAMEOF_MACRO_HPP
|
||||
#define NEARGYE_NAMEOF_MACRO_HPP
|
||||
|
||||
// Checks nameof_type compiler compatibility.
|
||||
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 7 || defined(_MSC_VER) && _MSC_VER >= 1910
|
||||
#undef NAMEOF_TYPE_SUPPORTED
|
||||
#define NAMEOF_TYPE_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// Checks nameof_type_rtti compiler compatibility.
|
||||
#if defined(__clang__)
|
||||
#if __has_feature(cxx_rtti)
|
||||
#undef NAMEOF_TYPE_RTTI_SUPPORTED
|
||||
#define NAMEOF_TYPE_RTTI_SUPPORTED 1
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(__GXX_RTTI)
|
||||
#undef NAMEOF_TYPE_RTTI_SUPPORTED
|
||||
#define NAMEOF_TYPE_RTTI_SUPPORTED 1
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#if defined(_CPPRTTI)
|
||||
#undef NAMEOF_TYPE_RTTI_SUPPORTED
|
||||
#define NAMEOF_TYPE_RTTI_SUPPORTED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Checks nameof_member compiler compatibility.
|
||||
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 7 || \
|
||||
defined(_MSC_VER) && defined(_MSVC_LANG) && _MSVC_LANG >= 202002L
|
||||
#undef NAMEOF_MEMBER_SUPPORTED
|
||||
#define NAMEOF_MEMBER_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// Checks nameof_pointer compiler compatibility.
|
||||
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 7 || \
|
||||
defined(_MSC_VER) && defined(_MSVC_LANG) && _MSVC_LANG >= 202002L
|
||||
#undef NAMEOF_POINTER_SUPPORTED
|
||||
#define NAMEOF_POINTER_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// Checks nameof_enum compiler compatibility.
|
||||
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910
|
||||
#undef NAMEOF_ENUM_SUPPORTED
|
||||
#define NAMEOF_ENUM_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
// Checks nameof_enum compiler aliases compatibility.
|
||||
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920
|
||||
#undef NAMEOF_ENUM_SUPPORTED_ALIASES
|
||||
#define NAMEOF_ENUM_SUPPORTED_ALIASES 1
|
||||
#endif
|
||||
|
||||
// Enum value must be greater or equals than NAMEOF_ENUM_RANGE_MIN. By default NAMEOF_ENUM_RANGE_MIN = -128.
|
||||
// If need another min range for all enum types by default, redefine the macro NAMEOF_ENUM_RANGE_MIN.
|
||||
#if !defined(NAMEOF_ENUM_RANGE_MIN)
|
||||
#define NAMEOF_ENUM_RANGE_MIN -128
|
||||
#endif
|
||||
|
||||
// Enum value must be less or equals than NAMEOF_ENUM_RANGE_MAX. By default NAMEOF_ENUM_RANGE_MAX = 128.
|
||||
// If need another max range for all enum types by default, redefine the macro NAMEOF_ENUM_RANGE_MAX.
|
||||
#if !defined(NAMEOF_ENUM_RANGE_MAX)
|
||||
#define NAMEOF_ENUM_RANGE_MAX 128
|
||||
#endif
|
||||
|
||||
#define NAMEOF_VERSION_MAJOR 0
|
||||
#define NAMEOF_VERSION_MINOR 10
|
||||
#define NAMEOF_VERSION_PATCH 4
|
||||
|
||||
// Obtains name of variable, function, macro.
|
||||
#define NAMEOF(...) \
|
||||
[]() constexpr noexcept { \
|
||||
::std::void_t<decltype(__VA_ARGS__)>(); \
|
||||
constexpr auto _name = ::nameof::detail::pretty_name(#__VA_ARGS__); \
|
||||
static_assert(!_name.empty(), "Expression does not have a name."); \
|
||||
constexpr auto _size = _name.size(); \
|
||||
constexpr auto _nameof = ::nameof::cstring<_size>{_name}; \
|
||||
return _nameof; \
|
||||
}()
|
||||
|
||||
// Obtains full name of variable, function, macro.
|
||||
#define NAMEOF_FULL(...) \
|
||||
[]() constexpr noexcept { \
|
||||
::std::void_t<decltype(__VA_ARGS__)>(); \
|
||||
constexpr auto _name = ::nameof::detail::pretty_name(#__VA_ARGS__, false); \
|
||||
static_assert(!_name.empty(), "Expression does not have a name."); \
|
||||
constexpr auto _size = _name.size(); \
|
||||
constexpr auto _nameof_full = ::nameof::cstring<_size>{_name}; \
|
||||
return _nameof_full; \
|
||||
}()
|
||||
|
||||
// Obtains raw name of variable, function, macro.
|
||||
#define NAMEOF_RAW(...) \
|
||||
[]() constexpr noexcept { \
|
||||
::std::void_t<decltype(__VA_ARGS__)>(); \
|
||||
constexpr auto _name = ::nameof::string_view{#__VA_ARGS__}; \
|
||||
static_assert(!_name.empty(), "Expression does not have a name."); \
|
||||
constexpr auto _size = _name.size(); \
|
||||
constexpr auto _nameof_raw = ::nameof::cstring<_size>{_name}; \
|
||||
return _nameof_raw; \
|
||||
}()
|
||||
|
||||
// Obtains name of enum variable.
|
||||
#define NAMEOF_ENUM(...) ::nameof::nameof_enum<::std::decay_t<decltype(__VA_ARGS__)>>(__VA_ARGS__)
|
||||
|
||||
// Obtains name of enum variable or default value if enum variable out of range.
|
||||
#define NAMEOF_ENUM_OR(...) ::nameof::nameof_enum_or(__VA_ARGS__)
|
||||
|
||||
// Obtains name of static storage enum variable.
|
||||
// This version is much lighter on the compile times and is not restricted to the enum_range limitation.
|
||||
#define NAMEOF_ENUM_CONST(...) ::nameof::nameof_enum<__VA_ARGS__>()
|
||||
|
||||
// Obtains name of enum-flags variable.
|
||||
#define NAMEOF_ENUM_FLAG(...) ::nameof::nameof_enum_flag<::std::decay_t<decltype(__VA_ARGS__)>>(__VA_ARGS__)
|
||||
|
||||
// Obtains type name, reference and cv-qualifiers are ignored.
|
||||
#define NAMEOF_TYPE(...) ::nameof::nameof_type<__VA_ARGS__>()
|
||||
|
||||
// Obtains full type name, with reference and cv-qualifiers.
|
||||
#define NAMEOF_FULL_TYPE(...) ::nameof::nameof_full_type<__VA_ARGS__>()
|
||||
|
||||
// Obtains short type name.
|
||||
#define NAMEOF_SHORT_TYPE(...) ::nameof::nameof_short_type<__VA_ARGS__>()
|
||||
|
||||
// Obtains type name of expression, reference and cv-qualifiers are ignored.
|
||||
#define NAMEOF_TYPE_EXPR(...) ::nameof::nameof_type<decltype(__VA_ARGS__)>()
|
||||
|
||||
// Obtains full type name of expression, with reference and cv-qualifiers.
|
||||
#define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type<decltype(__VA_ARGS__)>()
|
||||
|
||||
// Obtains short type name of expression.
|
||||
#define NAMEOF_SHORT_TYPE_EXPR(...) ::nameof::nameof_short_type<decltype(__VA_ARGS__)>()
|
||||
|
||||
// Obtains type name, with reference and cv-qualifiers, using RTTI.
|
||||
#define NAMEOF_TYPE_RTTI(...) ::nameof::detail::nameof_type_rtti<::std::void_t<decltype(__VA_ARGS__)>>(typeid(__VA_ARGS__).name())
|
||||
|
||||
// Obtains full type name, using RTTI.
|
||||
#define NAMEOF_FULL_TYPE_RTTI(...) ::nameof::detail::nameof_full_type_rtti<decltype(__VA_ARGS__)>(typeid(__VA_ARGS__).name())
|
||||
|
||||
// Obtains short type name, using RTTI.
|
||||
#define NAMEOF_SHORT_TYPE_RTTI(...) ::nameof::detail::nameof_short_type_rtti<decltype(__VA_ARGS__)>(typeid(__VA_ARGS__).name())
|
||||
|
||||
// Obtains name of member.
|
||||
#define NAMEOF_MEMBER(...) ::nameof::nameof_member<__VA_ARGS__>()
|
||||
|
||||
// Obtains name of a function, a global or class static variable.
|
||||
#define NAMEOF_POINTER(...) ::nameof::nameof_pointer<__VA_ARGS__>()
|
||||
|
||||
#endif
|
46
src/nameof.cpp
Normal file
46
src/nameof.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
module;
|
||||
|
||||
#ifndef NAMEOF_IMPORT_STD
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#if !defined(NAMEOF_USING_ALIAS_STRING)
|
||||
#include <string>
|
||||
#endif
|
||||
#if !defined(NAMEOF_USING_ALIAS_STRING_VIEW)
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
#if __has_include(<cxxabi.h>)
|
||||
#include <cxxabi.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
export module nameof;
|
||||
|
||||
#ifdef NAMEOF_IMPORT_STD
|
||||
|
||||
import std;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NAMEOF_ATTACH_TO_GLOBAL_MODULE
|
||||
extern "C++" {
|
||||
#endif
|
||||
|
||||
#include <nameof.hpp>
|
||||
|
||||
#ifdef NAMEOF_ATTACH_TO_GLOBAL_MODULE
|
||||
} // extern "C++"
|
||||
#endif
|
Loading…
Reference in a new issue