fix constexpr, rvalue
This commit is contained in:
Neargye 2018-08-06 17:42:46 +05:00
parent ea58b9d963
commit e59687da2a
2 changed files with 20 additions and 18 deletions

View file

@ -35,8 +35,10 @@
#include <limits> #include <limits>
#include <ostream> #include <ostream>
#if !(__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)) #if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L))
#error "Request C++14." # define NAMEOF_CONSTEXPR14 constexpr
#else
# define NAMEOF_CONSTEXPR14
#endif #endif
namespace nameof { namespace nameof {
@ -116,7 +118,7 @@ class cstring final {
return {str_ + pos, n}; return {str_ + pos, n};
} }
inline friend constexpr bool operator==(const cstring& lhs, const cstring& rhs) noexcept { inline friend NAMEOF_CONSTEXPR14 bool operator==(const cstring& lhs, const cstring& rhs) noexcept {
if (lhs.size_ != rhs.size_) { if (lhs.size_ != rhs.size_) {
return false; return false;
} }
@ -130,17 +132,17 @@ class cstring final {
return true; return true;
} }
inline friend constexpr bool operator!=(const cstring& lhs, const cstring& rhs) noexcept { inline friend NAMEOF_CONSTEXPR14 bool operator!=(const cstring& lhs, const cstring& rhs) noexcept {
return !(lhs == rhs); return !(lhs == rhs);
} }
template <std::size_t N> template <std::size_t N>
inline friend constexpr bool operator==(const cstring& lhs, const char(&str)[N]) noexcept { inline friend NAMEOF_CONSTEXPR14 bool operator==(const cstring& lhs, const char(&str)[N]) noexcept {
return lhs == cstring{str, N - 1}; return lhs == cstring{str, N - 1};
} }
template <std::size_t N> template <std::size_t N>
inline friend constexpr bool operator!=(const cstring& lhs, const char(&str)[N]) noexcept { inline friend NAMEOF_CONSTEXPR14 bool operator!=(const cstring& lhs, const char(&str)[N]) noexcept {
return !(lhs == cstring{str, N - 1}); return !(lhs == cstring{str, N - 1});
} }
@ -156,7 +158,7 @@ inline constexpr bool IsLexeme(char s) noexcept {
return !((s >= '0' && s <= '9') || (s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || s == '_'); return !((s >= '0' && s <= '9') || (s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || s == '_');
} }
inline constexpr cstring NameofBase(const char* name, std::size_t length, bool with_suffix) noexcept { inline NAMEOF_CONSTEXPR14 cstring NameofBase(const char* name, std::size_t length, bool with_suffix) noexcept {
std::size_t p = 0; std::size_t p = 0;
if(IsLexeme(name[length - 1])) { if(IsLexeme(name[length - 1])) {
for (std::size_t i = length, h = 0; i > 0; --i) { for (std::size_t i = length, h = 0; i > 0; --i) {
@ -206,7 +208,7 @@ inline constexpr cstring NameofRaw(const char* name, std::size_t length) noexcep
template <typename T, template <typename T,
typename = typename std::enable_if<!std::is_reference<T>::value && typename = typename std::enable_if<!std::is_reference<T>::value &&
!std::is_void<T>::value>::type> !std::is_void<T>::value>::type>
inline constexpr detail::cstring Nameof(const T&, const char* name, std::size_t length, bool with_suffix = false) noexcept { inline NAMEOF_CONSTEXPR14 detail::cstring Nameof(const T&, const char* name, std::size_t length, bool with_suffix = false) noexcept {
return detail::NameofBase(name, length, with_suffix); return detail::NameofBase(name, length, with_suffix);
} }
@ -214,10 +216,10 @@ template <typename T,
typename = typename std::enable_if<!std::is_enum<T>::value && typename = typename std::enable_if<!std::is_enum<T>::value &&
!std::is_function<T>::value && !std::is_function<T>::value &&
!std::is_member_function_pointer<T>::value>::type> !std::is_member_function_pointer<T>::value>::type>
inline constexpr detail::cstring Nameof(T&&, const char*, std::size_t) = delete; inline NAMEOF_CONSTEXPR14 detail::cstring Nameof(T&&, const char*, std::size_t, bool) = delete;
template <typename T> template <typename T>
inline constexpr detail::cstring NameofTypeRaw() noexcept { inline NAMEOF_CONSTEXPR14 detail::cstring NameofTypeRaw() noexcept {
#if defined(__clang__) #if defined(__clang__)
const auto function_name = __PRETTY_FUNCTION__; const auto function_name = __PRETTY_FUNCTION__;
const auto total_length = sizeof(__PRETTY_FUNCTION__) - 1; const auto total_length = sizeof(__PRETTY_FUNCTION__) - 1;
@ -239,7 +241,7 @@ inline constexpr detail::cstring NameofTypeRaw() noexcept {
} }
template <typename T, typename D = typename detail::Decay<T>::type> template <typename T, typename D = typename detail::Decay<T>::type>
inline constexpr detail::cstring NameofType() noexcept { inline NAMEOF_CONSTEXPR14 detail::cstring NameofType() noexcept {
const auto raw_type_name = NameofTypeRaw<D>(); const auto raw_type_name = NameofTypeRaw<D>();
return detail::NameofBase(raw_type_name.begin(), raw_type_name.length(), false); return detail::NameofBase(raw_type_name.begin(), raw_type_name.length(), false);
} }
@ -255,7 +257,7 @@ inline constexpr detail::cstring NameofType() noexcept {
#endif #endif
// Used to obtain the simple (unqualified) string name of a variable, member, function. // Used to obtain the simple (unqualified) string name of a variable, member, function.
#define NAMEOF(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1) #define NAMEOF(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, false)
// Used to obtain the full string name of a variable, member, function. // Used to obtain the full string name of a variable, member, function.
#define NAMEOF_FULL(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, true) #define NAMEOF_FULL(name) ::nameof::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, true)

View file

@ -75,7 +75,7 @@ Long othervar;
SomeStruct& refvar = somevar; SomeStruct& refvar = somevar;
SomeStruct* ptrvar = &somevar; SomeStruct* ptrvar = &somevar;
#if 0 && (__cplusplus >= 201402L || (defined(_MSVC_LANG ) && _MSVC_LANG >= 201402L)) #if (__cplusplus >= 201402L || (defined(_MSVC_LANG ) && _MSVC_LANG >= 201402L))
// Compile-time supported by C++14. // Compile-time supported by C++14.
TEST_CASE("constexpr") { TEST_CASE("constexpr") {
SECTION("NAMEOF") { SECTION("NAMEOF") {
@ -138,7 +138,7 @@ TEST_CASE("constexpr") {
static_assert(cx1 == "class SomeClass<int>", ""); static_assert(cx1 == "class SomeClass<int>", "");
static_assert(cx2 == "class SomeClass<int>", ""); static_assert(cx2 == "class SomeClass<int>", "");
static_assert(cx3 == "class SomeClass<int>", ""); static_assert(cx3 == "class SomeClass<int>", "");
#else #elif defined(__GNUC__) || defined(__clang__)
static_assert(cx1 == "SomeClass<int>", ""); static_assert(cx1 == "SomeClass<int>", "");
static_assert(cx2 == "SomeClass<int>", ""); static_assert(cx2 == "SomeClass<int>", "");
static_assert(cx3 == "SomeClass<int>", ""); static_assert(cx3 == "SomeClass<int>", "");
@ -285,7 +285,7 @@ TEST_CASE("Spaces and Tabs ignored") {
REQUIRE(NAMEOF_TYPE( somevar ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE( somevar ) == "SomeStruct");
#if defined(_MSC_VER) #if defined(_MSC_VER)
REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "struct SomeStruct"); REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "struct SomeStruct");
#else #elif defined(__GNUC__) || defined(__clang__)
REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "SomeStruct");
#endif #endif
} }
@ -296,7 +296,7 @@ TEST_CASE("Spaces and Tabs ignored") {
REQUIRE(NAMEOF_TYPE( somevar ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE( somevar ) == "SomeStruct");
#if defined(_MSC_VER) #if defined(_MSC_VER)
REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "struct SomeStruct"); REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "struct SomeStruct");
#else #elif defined(__GNUC__) || defined(__clang__)
REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE_RAW( somevar ) == "SomeStruct");
#endif #endif
} }