Moved out all block implementations from header file.
This commit is contained in:
parent
c9a9751472
commit
8e999fe8fb
2 changed files with 306 additions and 197 deletions
|
|
@ -446,6 +446,10 @@ TextBlock::TextBlock(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFixed TextBlock::real_f_rbearing() const {
|
||||||
|
return _words.isEmpty() ? 0 : _words.back().f_rbearing();
|
||||||
|
}
|
||||||
|
|
||||||
EmojiBlock::EmojiBlock(
|
EmojiBlock::EmojiBlock(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
const QString &str,
|
const QString &str,
|
||||||
|
|
@ -470,5 +474,279 @@ EmojiBlock::EmojiBlock(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NewlineBlock::NewlineBlock(
|
||||||
|
const style::font &font,
|
||||||
|
const QString &str,
|
||||||
|
uint16 from,
|
||||||
|
uint16 length,
|
||||||
|
uchar flags,
|
||||||
|
uint16 lnkIndex,
|
||||||
|
uint16 spoilerIndex)
|
||||||
|
: AbstractBlock(font, str, from, length, flags, lnkIndex, spoilerIndex) {
|
||||||
|
_flags |= ((TextBlockTNewline & 0x0F) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::LayoutDirection NewlineBlock::nextDirection() const {
|
||||||
|
return _nextDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipBlock::SkipBlock(
|
||||||
|
const style::font &font,
|
||||||
|
const QString &str,
|
||||||
|
uint16 from,
|
||||||
|
int32 w,
|
||||||
|
int32 h,
|
||||||
|
uint16 lnkIndex,
|
||||||
|
uint16 spoilerIndex)
|
||||||
|
: AbstractBlock(font, str, from, 1, 0, lnkIndex, spoilerIndex)
|
||||||
|
, _height(h) {
|
||||||
|
_flags |= ((TextBlockTSkip & 0x0F) << 8);
|
||||||
|
_width = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SkipBlock::height() const {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TextWord::TextWord(
|
||||||
|
uint16 from,
|
||||||
|
QFixed width,
|
||||||
|
QFixed rbearing,
|
||||||
|
QFixed rpadding)
|
||||||
|
: _from(from)
|
||||||
|
, _rbearing((rbearing.value() > 0x7FFF)
|
||||||
|
? 0x7FFF
|
||||||
|
: (rbearing.value() < -0x7FFF ? -0x7FFF : rbearing.value()))
|
||||||
|
, _width(width)
|
||||||
|
, _rpadding(rpadding) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 TextWord::from() const {
|
||||||
|
return _from;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFixed TextWord::f_rbearing() const {
|
||||||
|
return QFixed::fromFixed(_rbearing);
|
||||||
|
}
|
||||||
|
|
||||||
|
QFixed TextWord::f_width() const {
|
||||||
|
return _width;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFixed TextWord::f_rpadding() const {
|
||||||
|
return _rpadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextWord::add_rpadding(QFixed padding) {
|
||||||
|
_rpadding += padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block::Block() {
|
||||||
|
Unexpected("Should not be called.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Block::Block(const Block &other) {
|
||||||
|
switch (other->type()) {
|
||||||
|
case TextBlockTNewline:
|
||||||
|
emplace<NewlineBlock>(other.unsafe<NewlineBlock>());
|
||||||
|
break;
|
||||||
|
case TextBlockTText:
|
||||||
|
emplace<TextBlock>(other.unsafe<TextBlock>());
|
||||||
|
break;
|
||||||
|
case TextBlockTEmoji:
|
||||||
|
emplace<EmojiBlock>(other.unsafe<EmojiBlock>());
|
||||||
|
break;
|
||||||
|
case TextBlockTSkip:
|
||||||
|
emplace<SkipBlock>(other.unsafe<SkipBlock>());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Unexpected("Bad text block type in Block(const Block&).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Block::Block(Block &&other) {
|
||||||
|
switch (other->type()) {
|
||||||
|
case TextBlockTNewline:
|
||||||
|
emplace<NewlineBlock>(std::move(other.unsafe<NewlineBlock>()));
|
||||||
|
break;
|
||||||
|
case TextBlockTText:
|
||||||
|
emplace<TextBlock>(std::move(other.unsafe<TextBlock>()));
|
||||||
|
break;
|
||||||
|
case TextBlockTEmoji:
|
||||||
|
emplace<EmojiBlock>(std::move(other.unsafe<EmojiBlock>()));
|
||||||
|
break;
|
||||||
|
case TextBlockTSkip:
|
||||||
|
emplace<SkipBlock>(std::move(other.unsafe<SkipBlock>()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Unexpected("Bad text block type in Block(Block&&).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Block &Block::operator=(const Block &other) {
|
||||||
|
if (&other == this) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
destroy();
|
||||||
|
switch (other->type()) {
|
||||||
|
case TextBlockTNewline:
|
||||||
|
emplace<NewlineBlock>(other.unsafe<NewlineBlock>());
|
||||||
|
break;
|
||||||
|
case TextBlockTText:
|
||||||
|
emplace<TextBlock>(other.unsafe<TextBlock>());
|
||||||
|
break;
|
||||||
|
case TextBlockTEmoji:
|
||||||
|
emplace<EmojiBlock>(other.unsafe<EmojiBlock>());
|
||||||
|
break;
|
||||||
|
case TextBlockTSkip:
|
||||||
|
emplace<SkipBlock>(other.unsafe<SkipBlock>());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Unexpected("Bad text block type in operator=(const Block&).");
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block &Block::operator=(Block &&other) {
|
||||||
|
if (&other == this) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
destroy();
|
||||||
|
switch (other->type()) {
|
||||||
|
case TextBlockTNewline:
|
||||||
|
emplace<NewlineBlock>(std::move(other.unsafe<NewlineBlock>()));
|
||||||
|
break;
|
||||||
|
case TextBlockTText:
|
||||||
|
emplace<TextBlock>(std::move(other.unsafe<TextBlock>()));
|
||||||
|
break;
|
||||||
|
case TextBlockTEmoji:
|
||||||
|
emplace<EmojiBlock>(std::move(other.unsafe<EmojiBlock>()));
|
||||||
|
break;
|
||||||
|
case TextBlockTSkip:
|
||||||
|
emplace<SkipBlock>(std::move(other.unsafe<SkipBlock>()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Unexpected("Bad text block type in operator=(Block&&).");
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block::~Block() {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::Newline(
|
||||||
|
const style::font &font,
|
||||||
|
const QString &str,
|
||||||
|
uint16 from,
|
||||||
|
uint16 length,
|
||||||
|
uchar flags,
|
||||||
|
uint16 lnkIndex,
|
||||||
|
uint16 spoilerIndex) {
|
||||||
|
return New<NewlineBlock>(
|
||||||
|
font,
|
||||||
|
str,
|
||||||
|
from,
|
||||||
|
length,
|
||||||
|
flags,
|
||||||
|
lnkIndex,
|
||||||
|
spoilerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::Text(
|
||||||
|
const style::font &font,
|
||||||
|
const QString &str,
|
||||||
|
QFixed minResizeWidth,
|
||||||
|
uint16 from,
|
||||||
|
uint16 length,
|
||||||
|
uchar flags,
|
||||||
|
uint16 lnkIndex,
|
||||||
|
uint16 spoilerIndex) {
|
||||||
|
return New<TextBlock>(
|
||||||
|
font,
|
||||||
|
str,
|
||||||
|
minResizeWidth,
|
||||||
|
from,
|
||||||
|
length,
|
||||||
|
flags,
|
||||||
|
lnkIndex,
|
||||||
|
spoilerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::Emoji(
|
||||||
|
const style::font &font,
|
||||||
|
const QString &str,
|
||||||
|
uint16 from,
|
||||||
|
uint16 length,
|
||||||
|
uchar flags,
|
||||||
|
uint16 lnkIndex,
|
||||||
|
uint16 spoilerIndex,
|
||||||
|
EmojiPtr emoji) {
|
||||||
|
return New<EmojiBlock>(
|
||||||
|
font,
|
||||||
|
str,
|
||||||
|
from,
|
||||||
|
length,
|
||||||
|
flags,
|
||||||
|
lnkIndex,
|
||||||
|
spoilerIndex,
|
||||||
|
emoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
Block Block::Skip(
|
||||||
|
const style::font &font,
|
||||||
|
const QString &str,
|
||||||
|
uint16 from,
|
||||||
|
int32 w,
|
||||||
|
int32 h,
|
||||||
|
uint16 lnkIndex,
|
||||||
|
uint16 spoilerIndex) {
|
||||||
|
return New<SkipBlock>(font, str, from, w, h, lnkIndex, spoilerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractBlock *Block::get() {
|
||||||
|
return &unsafe<AbstractBlock>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AbstractBlock *Block::get() const {
|
||||||
|
return &unsafe<AbstractBlock>();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractBlock *Block::operator->() {
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AbstractBlock *Block::operator->() const {
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractBlock &Block::operator*() {
|
||||||
|
return *get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AbstractBlock &Block::operator*() const {
|
||||||
|
return *get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::destroy() {
|
||||||
|
switch (get()->type()) {
|
||||||
|
case TextBlockTNewline:
|
||||||
|
unsafe<NewlineBlock>().~NewlineBlock();
|
||||||
|
break;
|
||||||
|
case TextBlockTText:
|
||||||
|
unsafe<TextBlock>().~TextBlock();
|
||||||
|
break;
|
||||||
|
case TextBlockTEmoji:
|
||||||
|
unsafe<EmojiBlock>().~EmojiBlock();
|
||||||
|
break;
|
||||||
|
case TextBlockTSkip:
|
||||||
|
unsafe<SkipBlock>().~SkipBlock();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Unexpected("Bad text block type in Block(Block&&).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Text
|
} // namespace Text
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
||||||
|
|
@ -88,14 +88,9 @@ public:
|
||||||
uint16 length,
|
uint16 length,
|
||||||
uchar flags,
|
uchar flags,
|
||||||
uint16 lnkIndex,
|
uint16 lnkIndex,
|
||||||
uint16 spoilerIndex)
|
uint16 spoilerIndex);
|
||||||
: AbstractBlock(font, str, from, length, flags, lnkIndex, spoilerIndex) {
|
|
||||||
_flags |= ((TextBlockTNewline & 0x0F) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::LayoutDirection nextDirection() const {
|
Qt::LayoutDirection nextDirection() const;
|
||||||
return _nextDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Qt::LayoutDirection _nextDir = Qt::LayoutDirectionAuto;
|
Qt::LayoutDirection _nextDir = Qt::LayoutDirectionAuto;
|
||||||
|
|
@ -109,29 +104,12 @@ private:
|
||||||
class TextWord final {
|
class TextWord final {
|
||||||
public:
|
public:
|
||||||
TextWord() = default;
|
TextWord() = default;
|
||||||
TextWord(uint16 from, QFixed width, QFixed rbearing, QFixed rpadding = 0)
|
TextWord(uint16 from, QFixed width, QFixed rbearing, QFixed rpadding = 0);
|
||||||
: _from(from)
|
uint16 from() const;
|
||||||
, _rbearing((rbearing.value() > 0x7FFF)
|
QFixed f_rbearing() const;
|
||||||
? 0x7FFF
|
QFixed f_width() const;
|
||||||
: (rbearing.value() < -0x7FFF ? -0x7FFF : rbearing.value()))
|
QFixed f_rpadding() const;
|
||||||
, _width(width)
|
void add_rpadding(QFixed padding);
|
||||||
, _rpadding(rpadding) {
|
|
||||||
}
|
|
||||||
uint16 from() const {
|
|
||||||
return _from;
|
|
||||||
}
|
|
||||||
QFixed f_rbearing() const {
|
|
||||||
return QFixed::fromFixed(_rbearing);
|
|
||||||
}
|
|
||||||
QFixed f_width() const {
|
|
||||||
return _width;
|
|
||||||
}
|
|
||||||
QFixed f_rpadding() const {
|
|
||||||
return _rpadding;
|
|
||||||
}
|
|
||||||
void add_rpadding(QFixed padding) {
|
|
||||||
_rpadding += padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16 _from = 0;
|
uint16 _from = 0;
|
||||||
|
|
@ -153,9 +131,7 @@ public:
|
||||||
uint16 spoilerIndex);
|
uint16 spoilerIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFixed real_f_rbearing() const {
|
QFixed real_f_rbearing() const;
|
||||||
return _words.isEmpty() ? 0 : _words.back().f_rbearing();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<TextWord> _words;
|
QVector<TextWord> _words;
|
||||||
|
|
||||||
|
|
@ -197,16 +173,9 @@ public:
|
||||||
int32 w,
|
int32 w,
|
||||||
int32 h,
|
int32 h,
|
||||||
uint16 lnkIndex,
|
uint16 lnkIndex,
|
||||||
uint16 spoilerIndex)
|
uint16 spoilerIndex);
|
||||||
: AbstractBlock(font, str, from, 1, 0, lnkIndex, spoilerIndex)
|
|
||||||
, _height(h) {
|
|
||||||
_flags |= ((TextBlockTSkip & 0x0F) << 8);
|
|
||||||
_width = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
int height() const {
|
int height() const;
|
||||||
return _height;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _height = 0;
|
int _height = 0;
|
||||||
|
|
@ -219,94 +188,12 @@ private:
|
||||||
|
|
||||||
class Block final {
|
class Block final {
|
||||||
public:
|
public:
|
||||||
Block() {
|
Block();
|
||||||
Unexpected("Should not be called.");
|
Block(const Block &other);
|
||||||
}
|
Block(Block &&other);
|
||||||
Block(const Block &other) {
|
Block &operator=(const Block &other);
|
||||||
switch (other->type()) {
|
Block &operator=(Block &&other);
|
||||||
case TextBlockTNewline:
|
~Block();
|
||||||
emplace<NewlineBlock>(other.unsafe<NewlineBlock>());
|
|
||||||
break;
|
|
||||||
case TextBlockTText:
|
|
||||||
emplace<TextBlock>(other.unsafe<TextBlock>());
|
|
||||||
break;
|
|
||||||
case TextBlockTEmoji:
|
|
||||||
emplace<EmojiBlock>(other.unsafe<EmojiBlock>());
|
|
||||||
break;
|
|
||||||
case TextBlockTSkip:
|
|
||||||
emplace<SkipBlock>(other.unsafe<SkipBlock>());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Unexpected("Bad text block type in Block(const Block&).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Block(Block &&other) {
|
|
||||||
switch (other->type()) {
|
|
||||||
case TextBlockTNewline:
|
|
||||||
emplace<NewlineBlock>(std::move(other.unsafe<NewlineBlock>()));
|
|
||||||
break;
|
|
||||||
case TextBlockTText:
|
|
||||||
emplace<TextBlock>(std::move(other.unsafe<TextBlock>()));
|
|
||||||
break;
|
|
||||||
case TextBlockTEmoji:
|
|
||||||
emplace<EmojiBlock>(std::move(other.unsafe<EmojiBlock>()));
|
|
||||||
break;
|
|
||||||
case TextBlockTSkip:
|
|
||||||
emplace<SkipBlock>(std::move(other.unsafe<SkipBlock>()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Unexpected("Bad text block type in Block(Block&&).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Block &operator=(const Block &other) {
|
|
||||||
if (&other == this) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
destroy();
|
|
||||||
switch (other->type()) {
|
|
||||||
case TextBlockTNewline:
|
|
||||||
emplace<NewlineBlock>(other.unsafe<NewlineBlock>());
|
|
||||||
break;
|
|
||||||
case TextBlockTText:
|
|
||||||
emplace<TextBlock>(other.unsafe<TextBlock>());
|
|
||||||
break;
|
|
||||||
case TextBlockTEmoji:
|
|
||||||
emplace<EmojiBlock>(other.unsafe<EmojiBlock>());
|
|
||||||
break;
|
|
||||||
case TextBlockTSkip:
|
|
||||||
emplace<SkipBlock>(other.unsafe<SkipBlock>());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Unexpected("Bad text block type in operator=(const Block&).");
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Block &operator=(Block &&other) {
|
|
||||||
if (&other == this) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
destroy();
|
|
||||||
switch (other->type()) {
|
|
||||||
case TextBlockTNewline:
|
|
||||||
emplace<NewlineBlock>(std::move(other.unsafe<NewlineBlock>()));
|
|
||||||
break;
|
|
||||||
case TextBlockTText:
|
|
||||||
emplace<TextBlock>(std::move(other.unsafe<TextBlock>()));
|
|
||||||
break;
|
|
||||||
case TextBlockTEmoji:
|
|
||||||
emplace<EmojiBlock>(std::move(other.unsafe<EmojiBlock>()));
|
|
||||||
break;
|
|
||||||
case TextBlockTSkip:
|
|
||||||
emplace<SkipBlock>(std::move(other.unsafe<SkipBlock>()));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Unexpected("Bad text block type in operator=(Block&&).");
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~Block() {
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] static Block Newline(
|
[[nodiscard]] static Block Newline(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
|
|
@ -315,9 +202,7 @@ public:
|
||||||
uint16 length,
|
uint16 length,
|
||||||
uchar flags,
|
uchar flags,
|
||||||
uint16 lnkIndex,
|
uint16 lnkIndex,
|
||||||
uint16 spoilerIndex) {
|
uint16 spoilerIndex);
|
||||||
return New<NewlineBlock>(font, str, from, length, flags, lnkIndex, spoilerIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] static Block Text(
|
[[nodiscard]] static Block Text(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
|
|
@ -327,17 +212,7 @@ public:
|
||||||
uint16 length,
|
uint16 length,
|
||||||
uchar flags,
|
uchar flags,
|
||||||
uint16 lnkIndex,
|
uint16 lnkIndex,
|
||||||
uint16 spoilerIndex) {
|
uint16 spoilerIndex);
|
||||||
return New<TextBlock>(
|
|
||||||
font,
|
|
||||||
str,
|
|
||||||
minResizeWidth,
|
|
||||||
from,
|
|
||||||
length,
|
|
||||||
flags,
|
|
||||||
lnkIndex,
|
|
||||||
spoilerIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] static Block Emoji(
|
[[nodiscard]] static Block Emoji(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
|
|
@ -347,17 +222,7 @@ public:
|
||||||
uchar flags,
|
uchar flags,
|
||||||
uint16 lnkIndex,
|
uint16 lnkIndex,
|
||||||
uint16 spoilerIndex,
|
uint16 spoilerIndex,
|
||||||
EmojiPtr emoji) {
|
EmojiPtr emoji);
|
||||||
return New<EmojiBlock>(
|
|
||||||
font,
|
|
||||||
str,
|
|
||||||
from,
|
|
||||||
length,
|
|
||||||
flags,
|
|
||||||
lnkIndex,
|
|
||||||
spoilerIndex,
|
|
||||||
emoji);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] static Block Skip(
|
[[nodiscard]] static Block Skip(
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
|
|
@ -366,9 +231,7 @@ public:
|
||||||
int32 w,
|
int32 w,
|
||||||
int32 h,
|
int32 h,
|
||||||
uint16 lnkIndex,
|
uint16 lnkIndex,
|
||||||
uint16 spoilerIndex) {
|
uint16 spoilerIndex);
|
||||||
return New<SkipBlock>(font, str, from, w, h, lnkIndex, spoilerIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FinalBlock>
|
template <typename FinalBlock>
|
||||||
[[nodiscard]] FinalBlock &unsafe() {
|
[[nodiscard]] FinalBlock &unsafe() {
|
||||||
|
|
@ -380,29 +243,14 @@ public:
|
||||||
return *reinterpret_cast<const FinalBlock*>(&_data);
|
return *reinterpret_cast<const FinalBlock*>(&_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] AbstractBlock *get() {
|
[[nodiscard]] AbstractBlock *get();
|
||||||
return &unsafe<AbstractBlock>();
|
[[nodiscard]] const AbstractBlock *get() const;
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const AbstractBlock *get() const {
|
[[nodiscard]] AbstractBlock *operator->();
|
||||||
return &unsafe<AbstractBlock>();
|
[[nodiscard]] const AbstractBlock *operator->() const;
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] AbstractBlock *operator->() {
|
[[nodiscard]] AbstractBlock &operator*();
|
||||||
return get();
|
[[nodiscard]] const AbstractBlock &operator*() const;
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const AbstractBlock *operator->() const {
|
|
||||||
return get();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] AbstractBlock &operator*() {
|
|
||||||
return *get();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const AbstractBlock &operator*() const {
|
|
||||||
return *get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Tag {
|
struct Tag {
|
||||||
|
|
@ -423,24 +271,7 @@ private:
|
||||||
new (&_data) FinalType(std::forward<Args>(args)...);
|
new (&_data) FinalType(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy();
|
||||||
switch (get()->type()) {
|
|
||||||
case TextBlockTNewline:
|
|
||||||
unsafe<NewlineBlock>().~NewlineBlock();
|
|
||||||
break;
|
|
||||||
case TextBlockTText:
|
|
||||||
unsafe<TextBlock>().~TextBlock();
|
|
||||||
break;
|
|
||||||
case TextBlockTEmoji:
|
|
||||||
unsafe<EmojiBlock>().~EmojiBlock();
|
|
||||||
break;
|
|
||||||
case TextBlockTSkip:
|
|
||||||
unsafe<SkipBlock>().~SkipBlock();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Unexpected("Bad text block type in Block(Block&&).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static_assert(sizeof(NewlineBlock) <= sizeof(TextBlock));
|
static_assert(sizeof(NewlineBlock) <= sizeof(TextBlock));
|
||||||
static_assert(alignof(NewlineBlock) <= alignof(void*));
|
static_assert(alignof(NewlineBlock) <= alignof(void*));
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue