// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/utils/common.h" #include "td/utils/Status.h" #include #include namespace td { template ::value> class optional { public: optional() = default; template , optional>::value && std::is_constructible::value, int> = 0> optional(T1 &&t) : impl_(std::forward(t)) { } optional(const optional &other) { if (other) { impl_ = Result(other.value()); } } optional &operator=(const optional &other) { if (this == &other) { return *this; } if (other) { impl_ = Result(other.value()); } else { impl_ = Result(); } return *this; } optional(optional &&) = default; optional &operator=(optional &&) = default; ~optional() = default; explicit operator bool() const noexcept { return impl_.is_ok(); } T &value() { DCHECK(*this); return impl_.ok_ref(); } const T &value() const { DCHECK(*this); return impl_.ok_ref(); } T &operator*() { return value(); } const T &operator*() const { return value(); } T unwrap() { CHECK(*this); auto res = std::move(value()); impl_ = {}; return res; } optional copy() const { if (*this) { return value(); } return {}; } template void emplace(ArgsT &&...args) { impl_.emplace(std::forward(args)...); } private: Result impl_; }; template struct optional : optional { optional() = default; using optional::optional; optional(const optional &) = delete; optional &operator=(const optional &) = delete; optional(optional &&) = default; optional &operator=(optional &&) = default; ~optional() = default; }; } // namespace td