refactor(emojis): use std::variant and QStringView (#6714)

This commit is contained in:
Nerixyz
2026-01-05 21:06:42 +01:00
committed by GitHub
parent 327dc0ebcb
commit b7b592098f
8 changed files with 52 additions and 52 deletions
+1
View File
@@ -82,6 +82,7 @@
- Dev: Enable C++ 23. (#6693) - Dev: Enable C++ 23. (#6693)
- Dev: Prefer `std::expected` over `nonstd::expected_lite`. (#6693) - Dev: Prefer `std::expected` over `nonstd::expected_lite`. (#6693)
- Dev: Moved Twitch PubSub to liveupdates. (#6638) - Dev: Moved Twitch PubSub to liveupdates. (#6638)
- Dev: Refactored types used for emoji parsing. (#6714)
## 2.5.4 ## 2.5.4
+9 -9
View File
@@ -64,7 +64,7 @@ static void BM_EmojiParsing(benchmark::State &state)
struct TestCase { struct TestCase {
QString input; QString input;
std::vector<boost::variant<EmotePtr, QString>> expectedOutput; std::vector<std::variant<EmotePtr, QStringView>> expectedOutput;
}; };
const auto &emojiMap = emojis.getEmojis(); const auto &emojiMap = emojis.getEmojis();
@@ -89,9 +89,9 @@ static void BM_EmojiParsing(benchmark::State &state)
"foo 🐧 bar", "foo 🐧 bar",
// expected output // expected output
{ {
"foo ", u"foo ",
penguinEmoji, penguinEmoji,
" bar", u" bar",
}, },
}, },
{ {
@@ -99,7 +99,7 @@ static void BM_EmojiParsing(benchmark::State &state)
"foo bar", "foo bar",
// expected output // expected output
{ {
"foo bar", u"foo bar",
}, },
}, },
{ {
@@ -107,9 +107,9 @@ static void BM_EmojiParsing(benchmark::State &state)
"foo 🐧 bar 🐧🐧🐧🐧🐧", "foo 🐧 bar 🐧🐧🐧🐧🐧",
// expected output // expected output
{ {
"foo ", u"foo ",
penguinEmoji, penguinEmoji,
" bar ", u" bar ",
penguinEmoji, penguinEmoji,
penguinEmoji, penguinEmoji,
penguinEmoji, penguinEmoji,
@@ -133,9 +133,9 @@ static void BM_EmojiParsing(benchmark::State &state)
qDebug() << "BAD BENCH"; qDebug() << "BAD BENCH";
for (const auto &v : output) for (const auto &v : output)
{ {
if (v.type() == typeid(QString)) if (std::holds_alternative<QStringView>(v))
{ {
qDebug() << "output:" << boost::get<QString>(v); qDebug() << "output:" << std::get<QStringView>(v);
} }
} }
} }
@@ -158,7 +158,7 @@ static void BM_EmojiParsing2(benchmark::State &state, const QString &input,
int actualNumEmojis = 0; int actualNumEmojis = 0;
for (const auto &part : output) for (const auto &part : output)
{ {
if (part.type() == typeid(EmotePtr)) if (std::holds_alternative<EmotePtr>(part))
{ {
++actualNumEmojis; ++actualNumEmojis;
} }
@@ -143,9 +143,11 @@ bool appendWhisperMessageWordsLocally(const QStringList &words)
b.emplace<EmoteElement>(emote, b.emplace<EmoteElement>(emote,
MessageElementFlag::EmojiAll); MessageElementFlag::EmojiAll);
} }
void operator()(const QString &string, void operator()(QStringView stringView,
MessageBuilder &b) const MessageBuilder &b) const
{ {
QString string =
stringView.toString(); // FIXME: use string view
auto link = linkparser::parse(string); auto link = linkparser::parse(string);
if (link) if (link)
{ {
@@ -158,7 +160,7 @@ bool appendWhisperMessageWordsLocally(const QStringList &words)
} }
} }
} visitor; } visitor;
boost::apply_visitor( std::visit(
[&b](auto &&arg) { [&b](auto &&arg) {
visitor(arg, b); visitor(arg, b);
}, },
+18 -20
View File
@@ -2363,16 +2363,15 @@ void MessageBuilder::addWords(
for (auto variant : for (auto variant :
getApp()->getEmotes()->getEmojis()->parse(preText)) getApp()->getEmotes()->getEmojis()->parse(preText))
{ {
boost::apply_visitor(variant::Overloaded{ std::visit(variant::Overloaded{
[&](const EmotePtr &emote) { [&](const EmotePtr &emote) {
this->addEmoji(emote); this->addEmoji(emote);
}, },
[&](QString text) { [&](QStringView text) {
this->addTextOrEmote( this->addTextOrEmote(state, text.toString());
state, std::move(text)); },
}, },
}, variant);
variant);
} }
cursor += preText.size(); cursor += preText.size();
@@ -2388,16 +2387,15 @@ void MessageBuilder::addWords(
// split words // split words
for (auto variant : getApp()->getEmotes()->getEmojis()->parse(word)) for (auto variant : getApp()->getEmotes()->getEmojis()->parse(word))
{ {
boost::apply_visitor(variant::Overloaded{ std::visit(variant::Overloaded{
[&](const EmotePtr &emote) { [&](const EmotePtr &emote) {
this->addEmoji(emote); this->addEmoji(emote);
}, },
[&](QString text) { [&](QStringView text) {
this->addTextOrEmote(state, this->addTextOrEmote(state, text.toString());
std::move(text)); },
}, },
}, variant);
variant);
} }
cursor += word.size() + 1; cursor += word.size() + 1;
+4 -4
View File
@@ -929,9 +929,9 @@ void SingleLineTextElement::addToContainer(MessageLayoutContainer &container,
for (const auto &parsedWord : for (const auto &parsedWord :
app->getEmotes()->getEmojis()->parse(word)) app->getEmotes()->getEmojis()->parse(word))
{ {
if (parsedWord.type() == typeid(QString)) if (std::holds_alternative<QStringView>(parsedWord))
{ {
currentText += boost::get<QString>(parsedWord); currentText += std::get<QStringView>(parsedWord);
QString prev = QString prev =
currentText; // only increments the ref-count currentText; // only increments the ref-count
currentText = currentText =
@@ -943,9 +943,9 @@ void SingleLineTextElement::addToContainer(MessageLayoutContainer &container,
break; break;
} }
} }
else if (parsedWord.type() == typeid(EmotePtr)) else if (std::holds_alternative<EmotePtr>(parsedWord))
{ {
auto emote = boost::get<EmotePtr>(parsedWord); auto emote = std::get<EmotePtr>(parsedWord);
auto image = auto image =
emote->images.getImageOrLoaded(container.getScale()); emote->images.getImageOrLoaded(container.getScale());
if (!image->isEmpty()) if (!image->isEmpty())
+5 -6
View File
@@ -312,10 +312,10 @@ void Emojis::loadEmojiSet()
}); });
} }
std::vector<boost::variant<EmotePtr, QString>> Emojis::parse( std::vector<std::variant<EmotePtr, QStringView>> Emojis::parse(
const QString &text) const QStringView text) const
{ {
auto result = std::vector<boost::variant<EmotePtr, QString>>(); auto result = std::vector<std::variant<EmotePtr, QStringView>>();
QString::size_type lastParsedEmojiEndIndex = 0; QString::size_type lastParsedEmojiEndIndex = 0;
for (qsizetype i = 0; i < text.length(); ++i) for (qsizetype i = 0; i < text.length(); ++i)
@@ -351,7 +351,7 @@ std::vector<boost::variant<EmotePtr, QString>> Emojis::parse(
{ {
// look in emoji->value // look in emoji->value
bool match = QStringView{emoji->value}.mid(1) == bool match = QStringView{emoji->value}.mid(1) ==
QStringView{text}.mid(i + 1, emojiExtraCharacters); text.mid(i + 1, emojiExtraCharacters);
if (match) if (match)
{ {
@@ -367,8 +367,7 @@ std::vector<boost::variant<EmotePtr, QString>> Emojis::parse(
// This checking here relies on the fact that the nonQualified string // This checking here relies on the fact that the nonQualified string
// always starts with the same byte as value (the unified string) // always starts with the same byte as value (the unified string)
bool match = QStringView{emoji->nonQualified}.mid(1) == bool match = QStringView{emoji->nonQualified}.mid(1) ==
QStringView{text}.mid( text.mid(i + 1, emojiNonQualifiedExtraCharacters);
i + 1, emojiNonQualifiedExtraCharacters);
if (match) if (match)
{ {
+5 -5
View File
@@ -3,12 +3,12 @@
#include "common/FlagsEnum.hpp" #include "common/FlagsEnum.hpp"
#include "providers/emoji/EmojiStyle.hpp" #include "providers/emoji/EmojiStyle.hpp"
#include <boost/variant.hpp>
#include <QMap> #include <QMap>
#include <QRegularExpression> #include <QRegularExpression>
#include <QVector> #include <QVector>
#include <memory> #include <memory>
#include <variant>
#include <vector> #include <vector>
namespace chatterino { namespace chatterino {
@@ -50,8 +50,8 @@ class IEmojis
public: public:
virtual ~IEmojis() = default; virtual ~IEmojis() = default;
virtual std::vector<boost::variant<EmotePtr, QString>> parse( virtual std::vector<std::variant<EmotePtr, QStringView>> parse(
const QString &text) const = 0; QStringView text) const = 0;
virtual const std::vector<EmojiPtr> &getEmojis() const = 0; virtual const std::vector<EmojiPtr> &getEmojis() const = 0;
virtual const std::vector<QString> &getShortCodes() const = 0; virtual const std::vector<QString> &getShortCodes() const = 0;
virtual QString replaceShortCodes(const QString &text) const = 0; virtual QString replaceShortCodes(const QString &text) const = 0;
@@ -61,8 +61,8 @@ class Emojis : public IEmojis
{ {
public: public:
void load(); void load();
std::vector<boost::variant<EmotePtr, QString>> parse( std::vector<std::variant<EmotePtr, QStringView>> parse(
const QString &text) const override; QStringView text) const override;
std::vector<QString> shortCodes; std::vector<QString> shortCodes;
QString replaceShortCodes(const QString &text) const override; QString replaceShortCodes(const QString &text) const override;
+6 -6
View File
@@ -65,7 +65,7 @@ TEST(Emojis, Parse)
struct TestCase { struct TestCase {
QString input; QString input;
std::vector<boost::variant<EmotePtr, QString>> expectedOutput; std::vector<std::variant<EmotePtr, QStringView>> expectedOutput;
}; };
auto getEmoji = [&](auto code) { auto getEmoji = [&](auto code) {
@@ -96,23 +96,23 @@ TEST(Emojis, Parse)
const std::vector<TestCase> tests{ const std::vector<TestCase> tests{
{ {
"abc", "abc",
{"abc"}, {u"abc"},
}, },
{ {
"abc def", "abc def",
{"abc def"}, {u"abc def"},
}, },
{ {
"abc🐧def", "abc🐧def",
{"abc", penguin, "def"}, {u"abc", penguin, u"def"},
}, },
{ {
"abc 🐧def", "abc 🐧def",
{"abc ", penguin, "def"}, {u"abc ", penguin, u"def"},
}, },
{ {
" abc🐧 def ", " abc🐧 def ",
{" abc", penguin, " def "}, {u" abc", penguin, u" def "},
}, },
{ {
"🐧", "🐧",