refactor(emojis): use std::variant and QStringView (#6714)
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 "},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"🐧",
|
"🐧",
|
||||||
|
|||||||
Reference in New Issue
Block a user