module routemon:util$impl; import :util; namespace routemon::util { lazy_zstring_view::lazy_zstring_view(lazy_zstring_view const& sv) noexcept : s_{sv.s_}, length_{sv.length_.load(std::memory_order_acquire)} { } lazy_zstring_view::lazy_zstring_view(lazy_zstring_view&& sv) noexcept : s_{sv.s_}, length_{sv.length_.load(std::memory_order_acquire)} { } auto lazy_zstring_view::operator=(lazy_zstring_view const& rhs) noexcept -> lazy_zstring_view& { if (this != &rhs) { s_ = rhs.s_; length_.store( rhs.length_.load(std::memory_order_acquire), std::memory_order_release); } return *this; } auto lazy_zstring_view::operator=(lazy_zstring_view&& rhs) noexcept -> lazy_zstring_view& { return *this = rhs; // use the copy assignment operator } auto lazy_zstring_view::length() const noexcept -> std::size_t { if (auto v = length_.load(std::memory_order_acquire); v != unset_length) return v; auto l = std::char_traits::length(s_); length_.store(l, std::memory_order_release); return l; } auto lazy_zstring_view::c_str() const noexcept -> char const* { return s_; } lazy_zstring_view::operator std::string_view() const noexcept { return std::string_view{s_, length()}; } lazy_zstring_view::operator char const*() const noexcept { return s_; } auto lazy_zstring_view::operator==(std::string_view sv) const noexcept -> bool { if (auto v = length_.load(std::memory_order_acquire); v != unset_length) if (sv.length() != v) return false; auto res = std::char_traits::compare(s_, sv.data(), sv.length()); if (res != 0) return false; // Strings are equal for sv.length() characters. if (s_[sv.length()] != '\0') return false; // Strings are actually equal, and we have just found out the // length of this string, so we might as well set it. length_.store(sv.length(), std::memory_order_release); return true; } auto operator==(zstring_view lhs, zstring_view rhs) -> bool { return std::string_view{lhs} == std::string_view{rhs}; } } // namespace routemon::util