improve constexpr

This commit is contained in:
Neargye 2018-08-06 17:56:46 +05:00
parent e59687da2a
commit be4a49586c
3 changed files with 24 additions and 38 deletions

View file

@ -83,7 +83,7 @@ SomeStruct& refvar = somevar;
SomeStruct* ptrvar = &somevar; SomeStruct* ptrvar = &somevar;
int main() { int main() {
#if (__cplusplus >= 201402L || (defined(_MSVC_LANG ) && _MSVC_LANG >= 201402L)) #if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSC_VER >= 1910 && _MSVC_LANG >= 201402L))
// Compile-time supported by C++14. // Compile-time supported by C++14.
constexpr auto constexpr_work_fine = NAMEOF(somevar); constexpr auto constexpr_work_fine = NAMEOF(somevar);
std::cout << constexpr_work_fine << std::endl; // somevar std::cout << constexpr_work_fine << std::endl; // somevar

View file

@ -35,7 +35,7 @@
#include <limits> #include <limits>
#include <ostream> #include <ostream>
#if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)) #if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSC_VER >= 1910 && _MSVC_LANG >= 201402L))
# define NAMEOF_CONSTEXPR14 constexpr # define NAMEOF_CONSTEXPR14 constexpr
#else #else
# define NAMEOF_CONSTEXPR14 # define NAMEOF_CONSTEXPR14
@ -67,10 +67,7 @@ class cstring final {
public: public:
constexpr cstring(const char* str, std::size_t size) noexcept : str_(str), size_(size) {} constexpr cstring(const char* str, std::size_t size) noexcept : str_(str), size_(size) {}
template <std::size_t N> cstring() noexcept : str_(nullptr), size_(0) {}
constexpr cstring(const char(&str)[N]) noexcept : str_(str), size_(N - 1) {}
cstring() = delete;
cstring(const cstring&) = default; cstring(const cstring&) = default;
@ -118,32 +115,22 @@ class cstring final {
return {str_ + pos, n}; return {str_ + pos, n};
} }
inline friend NAMEOF_CONSTEXPR14 bool operator==(const cstring& lhs, const cstring& rhs) noexcept { inline friend constexpr bool operator==(const cstring& lhs, const cstring& rhs) noexcept {
if (lhs.size_ != rhs.size_) { return (lhs.size_ == rhs.size_) && equals(lhs.begin(), rhs.begin(), lhs.size());
return false;
}
for (std::size_t i = 0; i < lhs.size_; ++i) {
if (lhs.str_[i] != rhs.str_[i]) {
return false;
}
}
return true;
} }
inline friend NAMEOF_CONSTEXPR14 bool operator!=(const cstring& lhs, const cstring& rhs) noexcept { inline friend constexpr 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 NAMEOF_CONSTEXPR14 bool operator==(const cstring& lhs, const char(&str)[N]) noexcept { inline friend constexpr 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 NAMEOF_CONSTEXPR14 bool operator!=(const cstring& lhs, const char(&str)[N]) noexcept { inline friend constexpr bool operator!=(const cstring& lhs, const char(&str)[N]) noexcept {
return !(lhs == cstring{str, N - 1}); return lhs != cstring{str, N - 1};
} }
inline friend std::ostream& operator<<(std::ostream& os, const cstring& str) { inline friend std::ostream& operator<<(std::ostream& os, const cstring& str) {
@ -152,6 +139,11 @@ class cstring final {
} }
inline operator std::string() const { return std::string(begin(), size()); } inline operator std::string() const { return std::string(begin(), size()); }
private:
static inline constexpr bool equals(const char* lhs, const char* rhs, std::size_t size) {
return size == 0 ? (lhs[0] == rhs[0]) : ((lhs[size - 1] == rhs[size - 1]) && equals(lhs, rhs, size - 1));
}
}; };
inline constexpr bool IsLexeme(char s) noexcept { inline constexpr bool IsLexeme(char s) noexcept {
@ -219,25 +211,19 @@ template <typename T,
inline NAMEOF_CONSTEXPR14 detail::cstring Nameof(T&&, const char*, std::size_t, bool) = delete; inline NAMEOF_CONSTEXPR14 detail::cstring Nameof(T&&, const char*, std::size_t, bool) = delete;
template <typename T> template <typename T>
inline NAMEOF_CONSTEXPR14 detail::cstring NameofTypeRaw() noexcept { inline constexpr detail::cstring NameofTypeRaw() noexcept {
#if defined(__clang__) #if defined(__clang__)
const auto function_name = __PRETTY_FUNCTION__; return {__PRETTY_FUNCTION__ + (sizeof("detail::cstring nameof::NameofTypeRaw() [T = ") - 1),
const auto total_length = sizeof(__PRETTY_FUNCTION__) - 1; (sizeof(__PRETTY_FUNCTION__) - 1) - (sizeof("detail::cstring nameof::NameofTypeRaw() [T = ") - 1) - (sizeof("]") - 1)};
constexpr auto prefix_length = sizeof("detail::cstring nameof::NameofTypeRaw() [T = ") - 1;
constexpr auto suffix_length = sizeof("]") - 1;
#elif defined(__GNUC__) #elif defined(__GNUC__)
const auto function_name = __PRETTY_FUNCTION__; return {__PRETTY_FUNCTION__ + (sizeof("constexpr nameof::detail::cstring nameof::NameofTypeRaw() [with T = ") - 1),
const auto total_length = sizeof(__PRETTY_FUNCTION__) - 1; (sizeof(__PRETTY_FUNCTION__) - 1) - (sizeof("constexpr nameof::detail::cstring nameof::NameofTypeRaw() [with T = ") - 1) - (sizeof("]") - 1)};
constexpr auto prefix_length = sizeof("constexpr nameof::detail::cstring nameof::NameofTypeRaw() [with T = ") - 1;
constexpr auto suffix_length = sizeof("]") - 1;
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
const auto function_name = __FUNCSIG__; return {__FUNCSIG__ + (sizeof("class nameof::detail::cstring __cdecl nameof::NameofTypeRaw<") - 1),
const auto total_length = sizeof(__FUNCSIG__) - 1; (sizeof(__FUNCSIG__) - 1) - (sizeof("class nameof::detail::cstring __cdecl nameof::NameofTypeRaw<") - 1) - (sizeof(">(void) noexcept") - 1)};
constexpr auto prefix_length = sizeof("class nameof::detail::cstring __cdecl nameof::NameofTypeRaw<") - 1; #else
constexpr auto suffix_length = sizeof(">(void) noexcept") - 1; return {};
#endif #endif
return {function_name + prefix_length, total_length - prefix_length - suffix_length};
} }
template <typename T, typename D = typename detail::Decay<T>::type> template <typename T, typename D = typename detail::Decay<T>::type>

View file

@ -75,7 +75,7 @@ Long othervar;
SomeStruct& refvar = somevar; SomeStruct& refvar = somevar;
SomeStruct* ptrvar = &somevar; SomeStruct* ptrvar = &somevar;
#if (__cplusplus >= 201402L || (defined(_MSVC_LANG ) && _MSVC_LANG >= 201402L)) #if (__cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSC_VER >= 1910 && _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") {