You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
1.5 KiB
94 lines
1.5 KiB
#pragma once |
|
|
|
#include <string> |
|
#include <utility> |
|
|
|
#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
|
|
|