#pragma once #include #include #include "utils/stdcompat/string_view.hpp" namespace devilution { class StringOrView { public: StringOrView() : owned_(false) , view_() { } StringOrView(std::string &&str) : owned_(true) , str_(std::move(str)) { } StringOrView(string_view str) : owned_(false) , view_(str) { } StringOrView(StringOrView &&other) noexcept : owned_(other.owned_) { if (other.owned_) { new (&str_) std::string(std::move(other.str_)); } else { new (&view_) string_view(other.view_); } } StringOrView &operator=(StringOrView &&other) noexcept { if (owned_) { if (other.owned_) { str_ = std::move(other.str_); } else { str_.~basic_string(); owned_ = false; new (&view_) string_view(other.view_); } } else { if (other.owned_) { view_.~string_view(); owned_ = true; new (&str_) std::string(std::move(other.str_)); } else { view_ = other.view_; } } return *this; } ~StringOrView() { if (owned_) { str_.~basic_string(); } else { view_.~string_view(); } } bool empty() const { return owned_ ? str_.empty() : view_.empty(); } string_view str() const { return owned_ ? str_ : view_; } operator string_view() const { return str(); } private: bool owned_; union { std::string str_; string_view view_; }; }; } // namespace devilution