diff --git a/.appveyor.yml b/.appveyor.yml index 8f4787e..286a9ed 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,6 +4,7 @@ image: - Visual Studio 2017 platform: + - Win32 - x64 configuration: @@ -17,16 +18,14 @@ matrix: environment: matrix: - - GENERATOR: "Visual Studio 15 2017 Win64" - GENERATOR: "Visual Studio 15 2017" - - GENERATOR: "Visual Studio 14 2015 Win64" - GENERATOR: "Visual Studio 14 2015" before_build: - if exist build RMDIR /S /Q build - if not exist build mkdir build - cd build - - cmake .. -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=${CONFIGURATION} + - cmake .. -G "%GENERATOR%" -A %PLATFORM% -DCMAKE_BUILD_TYPE=${CONFIGURATION} build_script: - cmake --build . --config %CONFIGURATION% diff --git a/.travis.yml b/.travis.yml index 8b3d470..8f19e3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -77,18 +77,6 @@ matrix: env: - CXX_COMPILER=g++-8 CC_COMPILER=gcc-8 CONFIGURATION=Debug - - os: linux - compiler: clang++ - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.5 - packages: - - clang-3.5 - env: - - CXX_COMPILER=clang++-3.5 CC_COMPILER=clang-3.5 CONFIGURATION=Debug - - os: linux compiler: clang++ addons: @@ -173,36 +161,6 @@ matrix: env: - CXX_COMPILER=clang++-6.0 CC_COMPILER=clang-6.0 CONFIGURATION=Debug - - os: osx - compiler: clang++ - osx_image: xcode6.0 - env: - - CXX_COMPILER=clang++ CC_COMPILER=clang CONFIGURATION=Debug - - - os: osx - compiler: clang++ - osx_image: xcode6.1 - env: - - CXX_COMPILER=clang++ CC_COMPILER=clang CONFIGURATION=Debug - - - os: osx - compiler: clang++ - osx_image: xcode6.2 - env: - - CXX_COMPILER=clang++ CC_COMPILER=clang CONFIGURATION=Debug - - - os: osx - compiler: clang++ - osx_image: xcode6.3 - env: - - CXX_COMPILER=clang++ CC_COMPILER=clang CONFIGURATION=Debug - - - os: osx - compiler: clang++ - osx_image: xcode6.4 - env: - - CXX_COMPILER=clang++ CC_COMPILER=clang CONFIGURATION=Debug - - os: osx compiler: clang++ osx_image: xcode7.0 @@ -289,7 +247,7 @@ install: # If linux and clang install the right version of libc++. if [[ "${TRAVIS_OS_NAME}" == "linux" && "${CXX%%+*}" == "clang" && -n "$(ls -A ${LLVM_INSTALL})" ]]; then LLVM_INSTALL=${DEPS_DIR}/llvm/install - if [[ "${CXX}" == "clang++-3.5" ]]; then LLVM_VERSION="3.6.2"; # libc++ bug uncaught_exception not yet implemented. + if [[ "${CXX}" == "clang++-3.5" ]]; then LLVM_VERSION="3.5.2"; elif [[ "${CXX}" == "clang++-3.6" ]]; then LLVM_VERSION="3.6.2"; elif [[ "${CXX}" == "clang++-3.7" ]]; then LLVM_VERSION="3.7.1"; elif [[ "${CXX}" == "clang++-3.8" ]]; then LLVM_VERSION="3.8.1"; @@ -306,8 +264,8 @@ install: travis_retry wget -O - ${LIBCXX_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxx travis_retry wget -O - ${LIBCXXABI_URL} | tar --strip-components=1 -xJ -C llvm/projects/libcxxabi (cd llvm/build && cmake .. -DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL}) - (cd llvm/build/projects/libcxx && sudo make install -j JOBS) - (cd llvm/build/projects/libcxxabi && sudo make install -j JOBS) + (cd llvm/build/projects/libcxx && sudo make install -j${JOBS}) + (cd llvm/build/projects/libcxxabi && sudo make install -j${JOBS}) export CXXFLAGS="-isystem ${LLVM_INSTALL}/include/c++/v1" export LDFLAGS="-L ${LLVM_INSTALL}/lib -l c++ -l c++abi" export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${LLVM_INSTALL}/lib" diff --git a/example/example.cpp b/example/example.cpp index 144b46d..ff29e35 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -79,12 +79,11 @@ enum class Color { RED, GREEN, BLUE }; SomeStruct somevar; Long othervar; -SomeStruct& refvar = somevar; SomeStruct* ptrvar = &somevar; int main() { -#if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSC_VER >= 1910 && _MSVC_LANG >= 201402L)) - // Compile-time supported by C++14. +#if NAMEOF_HAS_CONSTEXPR + // Compile-time nameof supported by C++14. constexpr auto constexpr_work_fine = NAMEOF(somevar); static_assert("somevar" == constexpr_work_fine, ""); #endif @@ -111,12 +110,7 @@ int main() { // Type name. std::cout << NAMEOF_TYPE(somevar) << std::endl; // SomeStruct - std::cout << NAMEOF_TYPE(refvar) << std::endl; // SomeStruct - std::cout << NAMEOF_TYPE(ptrvar) << std::endl; // SomeStruct std::cout << NAMEOF_TYPE(othervar.ll) << std::endl; // LL - std::cout << NAMEOF_TYPE(othervar.ll.field) << std::endl; // int - std::cout << NAMEOF_TYPE(Color::RED) << std::endl; // Color - std::cout << NAMEOF_TYPE(SomeClass{}) << std::endl; // SomeClass // Type full name. diff --git a/include/nameof.hpp b/include/nameof.hpp index 1879d35..34c37c8 100644 --- a/include/nameof.hpp +++ b/include/nameof.hpp @@ -35,10 +35,12 @@ #include #include -#if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSC_VER >= 1910 && _MSVC_LANG >= 201402L)) -# define NAMEOF_CONSTEXPR14 constexpr +#if (defined(__cpp_constexpr) && __cpp_constexpr >= 201304L) || (defined(_MSC_VER) && _MSC_VER >= 1910) +# define NAMEOF_CONSTEXPR constexpr +# define NAMEOF_HAS_CONSTEXPR 1 #else -# define NAMEOF_CONSTEXPR14 +# define NAMEOF_CONSTEXPR +# define NAMEOF_HAS_CONSTEXPR 0 #endif namespace nameof { @@ -70,16 +72,16 @@ inline constexpr std::size_t StrLen(const char* str, std::size_t size = 0) { // STD like compile-time const char* string. class cstring final { const char* str_; - std::size_t size_; + const std::size_t size_; public: - constexpr cstring(const char* str, std::size_t length, std::size_t prefix = 0, std::size_t suffix = 0) noexcept + inline constexpr cstring(const char* str, std::size_t length, std::size_t prefix = 0, std::size_t suffix = 0) noexcept : str_{str + prefix}, size_{length - prefix - suffix} {} - constexpr cstring() noexcept : cstring{nullptr, 0, 0, 0} {} + inline constexpr cstring() noexcept : cstring{nullptr, 0, 0, 0} {} - constexpr cstring(const char* str) noexcept : cstring{str, StrLen(str), 0, 0} {} + inline constexpr cstring(const char* str) noexcept : cstring{str, StrLen(str), 0, 0} {} cstring(const cstring&) = default; @@ -145,7 +147,7 @@ inline constexpr bool IsLexeme(char s) noexcept { return !((s >= '0' && s <= '9') || (s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || s == '_'); } -inline NAMEOF_CONSTEXPR14 cstring NameofBase(const char* name, std::size_t length, bool with_suffix) noexcept { +inline NAMEOF_CONSTEXPR cstring NameofBase(const char* name, std::size_t length, bool with_suffix) noexcept { std::size_t p = 0; if(IsLexeme(name[length - 1])) { for (std::size_t i = length, h = 0; i > 0; --i) { @@ -195,7 +197,7 @@ inline constexpr cstring NameofRaw(const char* name, std::size_t length) noexcep template ::value && !std::is_void::value>::type> -inline NAMEOF_CONSTEXPR14 detail::cstring Nameof(const T&, const char* name, std::size_t length, bool with_suffix = false) noexcept { +inline NAMEOF_CONSTEXPR detail::cstring Nameof(const T&, const char* name, std::size_t length, bool with_suffix = false) noexcept { return detail::NameofBase(name, length, with_suffix); } @@ -203,19 +205,23 @@ template ::value && !std::is_function::value && !std::is_member_function_pointer::value>::type> -inline NAMEOF_CONSTEXPR14 detail::cstring Nameof(T&&, const char*, std::size_t, bool) = delete; +inline NAMEOF_CONSTEXPR detail::cstring Nameof(T&&, const char*, std::size_t, bool) = delete; template -inline constexpr detail::cstring NameofTypeRaw() noexcept { +inline NAMEOF_CONSTEXPR detail::cstring NameofTypeRaw() noexcept { #if defined(__clang__) - return {__PRETTY_FUNCTION__, + return {__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, sizeof("detail::cstring nameof::NameofTypeRaw() [T = ") - 1, sizeof("]") - 1}; #elif defined(__GNUC__) return {__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 1, +# if NAMEOF_HAS_CONSTEXPR sizeof("constexpr nameof::detail::cstring nameof::NameofTypeRaw() [with T = ") - 1, +# else + sizeof("nameof::detail::cstring nameof::NameofTypeRaw() [with T = ") - 1, +# endif sizeof("]") - 1}; #elif defined(_MSC_VER) return {__FUNCSIG__, @@ -228,14 +234,14 @@ inline constexpr detail::cstring NameofTypeRaw() noexcept { } template ::type> -inline constexpr detail::cstring NameofType() noexcept { +inline NAMEOF_CONSTEXPR detail::cstring NameofType() noexcept { const auto raw_type_name = NameofTypeRaw(); return detail::NameofBase(raw_type_name.begin(), raw_type_name.length(), false); } } // namespace nameof -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) // Used to obtain the raw string name of a variable, type, member, function, macros. # define NAMEOF_RAW(name) ::nameof::detail::NameofRaw(#name, ((sizeof(#name) / sizeof(char)) - 1) + (0 * sizeof(void (*)(__typeof__(name))))) #elif defined(_MSC_VER) diff --git a/test/test.cpp b/test/test.cpp index bff76d2..750c244 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -75,8 +75,8 @@ Long othervar; SomeStruct& refvar = somevar; SomeStruct* ptrvar = &somevar; -#if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSC_VER >= 1910 && _MSVC_LANG >= 201402L)) -// Compile-time supported by C++14. +#if NAMEOF_HAS_CONSTEXPR +// Compile-time nameof supported by C++14. TEST_CASE("constexpr") { SECTION("NAMEOF") { // variable @@ -114,20 +114,20 @@ TEST_CASE("constexpr") { static_assert(cx6 == "__cplusplus", ""); } - //TODO: constexpr NameofType gcc. -#if (defined(__clang__) || (defined(_MSC_VER) && _MSC_VER >= 1910)) +# if defined(_MSC_VER) || defined(__clang__) SECTION("NAMEOF_TYPE") { SomeClass a; constexpr auto cx1 = NAMEOF_TYPE(a); - static_assert(cx1 == "SomeClass", ""); - constexpr auto cx2 = nameof::NameofType>(); - static_assert(cx2 == "SomeClass", ""); - constexpr auto cx3 = nameof::NameofType(); + + + static_assert(cx1 == "SomeClass", ""); + static_assert(cx2 == "SomeClass", ""); static_assert(cx3 == "SomeClass", ""); } +# endif SECTION("NAMEOF_TYPE_RAW") { SomeClass a; @@ -136,17 +136,16 @@ TEST_CASE("constexpr") { constexpr auto cx2 = nameof::NameofTypeRaw>(); constexpr auto cx3 = nameof::NameofTypeRaw(); -#if defined(_MSC_VER) +# if defined(_MSC_VER) static_assert(cx1 == "class SomeClass", ""); static_assert(cx2 == "class SomeClass", ""); static_assert(cx3 == "class SomeClass", ""); -#elif defined(__GNUC__) || defined(__clang__) +# elif defined(__clang__) static_assert(cx1 == "SomeClass", ""); static_assert(cx2 == "SomeClass", ""); static_assert(cx3 == "SomeClass", ""); -#endif +# endif } -#endif } #endif