diff --git a/Source/control.cpp b/Source/control.cpp index bfb81cb89..e981609d4 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -883,7 +883,7 @@ void InitControlPan() for (bool &buttonEnabled : chrbtn) buttonEnabled = false; chrbtnactive = false; - InfoString = {}; + InfoString = StringOrView {}; RedrawComponent(PanelDrawComponent::Health); RedrawComponent(PanelDrawComponent::Mana); CloseCharPanel(); @@ -1165,7 +1165,7 @@ void DrawInfoBox(const Surface &out) { DrawPanelBox(out, { 177, 62, 288, 63 }, GetMainPanel().position + Displacement { 177, 46 }); if (!panelflag && !trigflag && pcursinvitem == -1 && pcursstashitem == StashStruct::EmptyCell && !spselflag) { - InfoString = {}; + InfoString = StringOrView {}; InfoColor = UiFlags::ColorWhite; } Player &myPlayer = *MyPlayer; diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 23f5d81ae..fdcb89e91 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -1781,7 +1781,7 @@ void plrctrls_after_check_curs_move() return; } if (!invflag) { - InfoString = {}; + InfoString = StringOrView {}; FindActor(); FindItemOrObject(); FindTrigger(); diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 2bbd4a6d0..7a4434be1 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -1435,7 +1435,7 @@ void TimeoutCursor(bool bTimeout) if (sgnTimeoutCurs == CURSOR_NONE && sgbMouseDown == CLICK_NONE) { sgnTimeoutCurs = pcurs; multi_net_ping(); - InfoString = {}; + InfoString = StringOrView {}; AddPanelString(_("-- Network timeout --")); AddPanelString(_("-- Waiting for players --")); NewCursor(CURSOR_HOURGLASS); @@ -1449,7 +1449,7 @@ void TimeoutCursor(bool bTimeout) if (pcurs == CURSOR_HOURGLASS) NewCursor(sgnTimeoutCurs); sgnTimeoutCurs = CURSOR_NONE; - InfoString = {}; + InfoString = StringOrView {}; RedrawEverything(); } } @@ -1459,7 +1459,7 @@ void HelpKeyPressed() if (HelpFlag) { HelpFlag = false; } else if (stextflag != TalkID::None) { - InfoString = {}; + InfoString = StringOrView {}; AddPanelString(_("No help available")); /// BUGFIX: message isn't displayed AddPanelString(_("while in stores")); LastMouseButtonAction = MouseActionType::None; diff --git a/Source/panels/spell_list.cpp b/Source/panels/spell_list.cpp index f8381119c..3d2972e43 100644 --- a/Source/panels/spell_list.cpp +++ b/Source/panels/spell_list.cpp @@ -114,7 +114,7 @@ void DrawSpell(const Surface &out) void DrawSpellList(const Surface &out) { - InfoString = {}; + InfoString = StringOrView {}; Player &myPlayer = *MyPlayer; diff --git a/Source/utils/string_or_view.hpp b/Source/utils/string_or_view.hpp index 779ad02eb..1d38c75bd 100644 --- a/Source/utils/string_or_view.hpp +++ b/Source/utils/string_or_view.hpp @@ -3,78 +3,51 @@ #include #include #include +#include namespace devilution { class StringOrView { public: StringOrView() - : owned_(false) - , view_() + : rep_ { std::string_view {} } { } + StringOrView(StringOrView &&) noexcept = default; + StringOrView(std::string &&str) - : owned_(true) - , str_(std::move(str)) + : rep_ { std::move(str) } { } StringOrView(std::string_view str) - : owned_(false) - , view_(str) + : rep_ { str } { } - StringOrView(StringOrView &&other) noexcept - : owned_(other.owned_) - { - if (other.owned_) { - new (&str_) std::string(std::move(other.str_)); - } else { - new (&view_) std::string_view(other.view_); - } - } + StringOrView &operator=(StringOrView &&) noexcept = default; - StringOrView &operator=(StringOrView &&other) noexcept + StringOrView &operator=(std::string &&value) noexcept { - if (owned_) { - if (other.owned_) { - str_ = std::move(other.str_); - } else { - str_.~basic_string(); - owned_ = false; - new (&view_) std::string_view(other.view_); - } - } else { - if (other.owned_) { - view_.~basic_string_view(); - owned_ = true; - new (&str_) std::string(std::move(other.str_)); - } else { - view_ = other.view_; - } - } + rep_ = std::move(value); return *this; } - ~StringOrView() + StringOrView &operator=(std::string_view value) noexcept { - if (owned_) { - str_.~basic_string(); - } else { - view_.~basic_string_view(); - } + rep_ = value; + return *this; } bool empty() const { - return owned_ ? str_.empty() : view_.empty(); + return std::visit([](auto &&val) -> bool { return val.empty(); }, rep_); } std::string_view str() const { - return owned_ ? str_ : view_; + return std::visit([](auto &&val) -> std::string_view { return val; }, rep_); } operator std::string_view() const @@ -83,11 +56,7 @@ public: } private: - bool owned_; - union { - std::string str_; - std::string_view view_; - }; + std::variant rep_; }; } // namespace devilution