Skip to content

Instantly share code, notes, and snippets.

@Bak-Jin-Hyeong
Last active September 26, 2019 03:36
Show Gist options
  • Save Bak-Jin-Hyeong/7fe5143985c65527d7a698c18b21625c to your computer and use it in GitHub Desktop.
Save Bak-Jin-Hyeong/7fe5143985c65527d7a698c18b21625c to your computer and use it in GitHub Desktop.
Restrict creation of string_view to string literals only
#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