首页 > 其他分享 >实现一个 std::optional

实现一个 std::optional

时间:2024-03-10 22:23:24浏览次数:27  
标签:std const 实现 auto value constexpr other optional

实现一个 std::optional

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

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

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>
  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_;
};

标签:std,const,实现,auto,value,constexpr,other,optional
From: https://www.cnblogs.com/FlandreScarlet/p/18064986

相关文章

  • C++单例 singleton的实现
     在这个单例模式的实现中,使用了静态局部变量来确保只有一个实例。 静态局部变量只会在第一次调用函数时初始化,并且在程序的整个生命周期内保持其值不变。这意味着,无论多少次调用getInstance()方法,都只会在第一次调用时创建一个实例,后续的调用会返回同一个实例。 具体来......
  • dolphinscheduler 实现master宕机故障转移能力源码分析
    DS(dolphinscheduler)的master是去中心化的,而故障转移能力是由master完成的,那么是多个master同时干故障转移,还是选举出一个master来干这件事情呢?回归到源码进行分析1.master启动方法@PostConstructpublicvoidrun()throwsSchedulerException{....this.failoverE......
  • 分布式锁实现——Redis
    分布式锁分布式锁的视线方式Redis实现分布式锁Zookeeper实现分布式锁MySQL实现分布式锁Etcd实现分布式锁实现分布式锁注意的点互斥性可重入性锁超时,防死锁锁释放正确,防误删阻塞和非阻塞公平和非公平Redis实现分布式锁的特点Redis是高性能的内存数据库,满足高......
  • Python简单实现查重
    使用Python实现查重这个作业属于哪个课程软件工程这个作业要求在哪里个人项目这个作业的目标初步认识软件开发流程,独立培养开发能力,熟悉PSP记录开发过程你可以在GitHub上找到本项目并下载额外三种算法代码Slave前言作为开发人员,不幸的是此前未曾接触熟悉过......
  • flnkcdc+datastream实现mysql到mysql数据同步
    一、maven依赖<dependency><groupId>org.apache.flink</groupId><artifactId>flink-clients</artifactId><version>1.18.1</version></dependency><dependency>......
  • java springboot拦截器的实现及用法
     1.前景,有时候我们在不同的地方需要使用用户的信息,我们可以使用threadLocal存储信息,这样我们在在这个线程随时使用用户信息了,不用自己在写一段冗余代码了,这时候使用拦截器就很不错 2.实现1.实现HandlerInterceptor2.重写实现方法  preHandle:在业务处理器处理请......
  • python实现批量运行命令行
    python实现批量运行命令行背景:对于不同参数设置来调用同一个接口,如果手动一条条修改再运行非常慢且容易出错。尤其是这次参数非常多且长。比如之前都是输入nohuppython-uexe.py>>../log/exp3.log2>&1&来运行一次,在exe中会设置参数并调用接口运行preditction_uni(input_f......
  • 要确保请求在一次会话中被转发到相同的后端服务器上,可以使用 Nginx 的 ip_hash 或 sti
    要确保请求在一次会话中被转发到相同的后端服务器上,可以使用Nginx的ip_hash或sticky模块来实现。ip_hash模块:ip_hash 模块使用客户端IP地址作为哈希键,将同一IP地址的请求始终转发到相同的后端服务器。要启用 ip_hash 模块,只需在Nginx配置文件的 http 块或......
  • 实现一个简单的 std::unique_ptr
    实现一个简单的std::unique_ptr简介std::unique_ptr是一个独占资源所有权的智能指针,通过RAII来自动管理资源的构造和析构。在标准库中,std::unique_ptr的通常实现是具有空基类优化。具体来讲,对于std::unique_ptr的删除器是其类型中的一部分,如果没有空基类优化,那么std::u......
  • 基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
    1.算法运行效果图预览RTL图:   仿真图:   导入到matlab显示效果如下:   2.算法运行软件版本matlab2022a vivado2019.2 3.算法理论概述      在计算机视觉领域,基于肤色模型和中值滤波的手部检测方法是一种常见的初步定位策略。该方法主要分为......