Last active
September 26, 2019 03:36
-
-
Save Bak-Jin-Hyeong/7fe5143985c65527d7a698c18b21625c to your computer and use it in GitHub Desktop.
Restrict creation of string_view to string literals only
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef LITERALSTRINGVIEW__H__ | |
#define LITERALSTRINGVIEW__H__ | |
#include <cassert> | |
#include <string_view> | |
class LiteralStringViewHolder; | |
namespace literals | |
{ | |
namespace string_view_literals | |
{ | |
constexpr | |
LiteralStringViewHolder operator"" _lit_sv(const char* p, size_t n) noexcept; | |
} // namespace string_view_literals | |
} // namespace literals | |
class LiteralStringViewHolder | |
{ | |
public: | |
constexpr LiteralStringViewHolder() noexcept = default; | |
#if defined(__x86_64__) || defined(_M_X64) | |
[[nodiscard]] constexpr std::string_view view() const noexcept | |
{ | |
return { data(), size() }; | |
} | |
#else | |
[[nodiscard]] constexpr std::string_view view() const noexcept | |
{ | |
return { p, n }; | |
} | |
#endif // #if defined(__x86_64__) || defined(_M_X64) | |
private: | |
friend constexpr LiteralStringViewHolder literals::string_view_literals:: | |
operator"" _lit_sv(const char* p, size_t n) noexcept; | |
#if defined(__x86_64__) || defined(_M_X64) | |
constexpr static uintptr_t pointer_mask = (1ull << 48) - 1; | |
constexpr static const char* zero_pointer = nullptr; | |
constexpr static uintptr_t pack_pointer(const char* p) noexcept | |
{ | |
return static_cast<uintptr_t>(p - zero_pointer) & pointer_mask; | |
} | |
constexpr static uintptr_t pack_mask(size_t n) noexcept | |
{ | |
return static_cast<uintptr_t>(n & 0xFFFF) << 48; | |
} | |
constexpr const char* data() const noexcept | |
{ | |
return zero_pointer + (packed & pointer_mask); | |
} | |
constexpr size_t size() const noexcept | |
{ | |
return static_cast<size_t>(packed >> 48); | |
} | |
constexpr LiteralStringViewHolder(const char* p, size_t n) noexcept | |
: packed(pack_pointer(p) | pack_mask(n)) | |
{ | |
} | |
uintptr_t packed = 0; | |
#else | |
constexpr LiteralStringViewHolder(const char* p, size_t n) noexcept | |
: p(p), n(n) | |
{ | |
} | |
const char* p = nullptr; | |
size_t n = 0; | |
#endif // #if defined(__x86_64__) || defined(_M_X64) | |
}; | |
namespace literals | |
{ | |
namespace string_view_literals | |
{ | |
constexpr | |
LiteralStringViewHolder operator"" _lit_sv(const char* p, size_t n) noexcept | |
{ | |
assert(n < 0xFFFF); | |
return LiteralStringViewHolder(p, n); | |
} | |
} // namespace string_view_literals | |
} // namespace literals | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment