2024-03-10 22:10阅读: 22评论: 0推荐: 0

实现一个 std::optional

实现一个 std::optional

如果写过 c# 或者是 rust ,那么对于里面的可空类型一定是很常用的。在 c++17 中添加了 std::optional ,也就是所谓的可空类型。

不过这里的实现是 placement new 的方式,也是位于栈上。

实现的主要点是申请一块内存空间,由于需要效率,因此这块内存空间的生命周期应当与对象一致,所以这边使用了 std::array 作为代替。

struct NoneOption {
NoneOption() = default;
} None;
template <typename Ty> class Option {
private:
using DataByte = std::array<std::uint8_t, sizeof(Ty)>;
public:
constexpr Option() noexcept : has_value_{false} {}
constexpr Option(NoneOption) noexcept : Option() {}
constexpr Option(const Ty &init) : has_value_{true} {
this->ConstructData(init);
}
constexpr Option(Ty &&init) : has_value_{true} {
this->ConstructData(std::move(init));
}
constexpr Option(const Option &other) : has_value_{other.has_value_} {
if (other.has_value_)
this->ConstructData(*other);
}
constexpr Option(Option &&other) noexcept
: data_(std::move(other.data_)), has_value_{std::move(other.has_value_)} {
other.has_value_ = false;
}
constexpr auto operator=(const Option &other) -> Option & {
this->Reset();
if (other.has_value_)
this->ConstructData(*other);
this->has_value_ = other.has_value_;
}
constexpr auto operator=(Option &&other) noexcept {
this->Reset();
this->data_ = std::move(other.data_);
this->has_value_ = other.has_value_;
other.has_value_ = false;
}
constexpr ~Option() noexcept {
this->ReinterpretCastData()->~Ty();
this->has_value_ = false;
}
public:
constexpr auto HasValue() const noexcept -> bool { return this->has_value_; }
constexpr explicit operator bool() const noexcept { return this->HasValue(); }
public:
constexpr auto operator->() const noexcept -> const Ty * {
return this->ReinterpretCastData();
}
constexpr auto operator->() noexcept -> Ty * {
return this->ReinterpretCastData();
}
constexpr auto operator*() const & noexcept -> const Ty & {
return *this->ReinterpretCastData();
}
constexpr auto operator*() & noexcept -> Ty & {
return *this->ReinterpretCastData();
}
constexpr auto operator*() const && noexcept -> const Ty && {
return std::move(*this->ReinterpretCastData());
}
constexpr auto operator*() && noexcept -> Ty && {
return std::move(*this->ReinterpretCastData());
}
public:
template <typename... Args> constexpr auto Emplace(Args &&...args) -> void {
if (this->has_value_) {
this->Reset();
}
this->ConstructData(std::forward<Args>(args)...);
}
constexpr auto Reset() noexcept -> void {
if (this->has_value_) {
this->ReinterpretCastData()->~Ty();
}
}
constexpr auto Swap(Option &other) noexcept -> void {
std::swap(this->data_, other.data_);
std::swap(this->has_value_, other.has_value_);
}
constexpr auto Value() const & -> const Ty & {
if (this->has_value_) {
return **this;
}
throw std::exception();
}
constexpr auto Value() const && -> const Ty && {
if (this->has_value_) {
return std::move(**this);
}
throw std::exception();
}
template <typename U>
constexpr auto ValueOr(U &&default_value) const & -> Ty {
if (this->has_value_) {
return **this;
}
return static_cast<Ty>(default_value);
}
template <typename U> constexpr auto ValueOr(U &&default_value) && -> Ty {
if (this->has_value_) {
return std::move(**this);
}
return static_cast<Ty>(default_value);
}
private:
template <typename... Args>
requires requires(Args... args) { new Ty(args...); }
constexpr auto ConstructData(Args &&...args) -> void {
new (this->data_.data()) Ty(std::forward<Args>(args)...);
}
constexpr auto ReinterpretCastData() noexcept -> Ty * {
return reinterpret_cast<Ty *>(this->data_.data());
}
constexpr auto ReinterpretCastData() const noexcept -> const Ty * {
return reinterpret_cast<const Ty *>(this->data_.data());
}
private:
DataByte data_;
bool has_value_;
};

本文作者:フランドール·スカーレット

本文链接:https://www.cnblogs.com/FlandreScarlet/p/18064986

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   フランドール·スカーレット  阅读(22)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Scarborough Fair 山田タマル
  2. 2 Faster Than Light Paradox Interactive,Andreas Waldetoft
  3. 3 世界は可愛く出来ている 上海アリス幻樂団
Scarborough Fair - 山田タマル
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : Pual Simon

作曲 : Pual Simon

作词 : イングランド民謡

作曲:加藤达也

Are you going to Scarborough Fair?

Parsley, sage, rosemary and thyme

Remember me to one who lives there

He once was a true love of mine

Tell him to make me a cambric shirt

Tell him to make me a cambric shirt

Parsley, sage, rosemary and thyme

Without no seams nor needlework

Then he'll be a true love of mine.

Tell him to find me an acre of land

Tell him to find me an acre of land

Parsley, sage, rosemary and thyme

Between the salt water and the sea strand

Then he'll be a true love of mine

Are you going to Scarborough Fair?