Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <utility>
- struct BadOptionalAccess {
- };
- template <typename T>
- class Optional {
- private:
- // alignas нужен для правильного выравнивания блока памяти
- alignas(T) unsigned char data[sizeof(T)];
- bool defined;
- public:
- Optional(): defined(false) {}
- Optional(const T& elem): defined(true) {
- new (data) T(elem);
- }
- Optional(T && elem): defined(true) {
- new (data) T(std::move(elem));
- }
- Optional(const Optional& other): defined(other.has_value()) {
- if (other.has_value())
- new (data) T(other.value());
- }
- Optional& operator=(const Optional& other) {
- if (other.has_value()) {
- if (!defined)
- new (data) T(other.value());
- else
- (**this) = other.value();
- defined = true;
- } else {
- reset();
- }
- return *this;
- }
- Optional& operator=(const T& elem) {
- if (!defined)
- new (data) T(elem);
- else
- (**this) = elem;
- defined = true;
- return *this;
- }
- Optional& operator=(T&& elem) {
- if (!defined)
- new (data) T(std::move(elem));
- else
- (**this) = std::move(elem);
- defined = true;
- return *this;
- }
- bool has_value() const {
- return defined;
- }
- T& operator*() {
- return *reinterpret_cast<T*>(data);
- }
- const T& operator*() const {
- return *reinterpret_cast<const T*>(data);
- }
- T* operator->() {
- return reinterpret_cast<T*>(data);
- }
- const T* operator->() const {
- return reinterpret_cast<const T*>(data);
- }
- T& value() {
- if (!defined)
- throw BadOptionalAccess();
- return (**this);
- }
- const T& value() const {
- if (!defined)
- throw BadOptionalAccess();
- return (**this);
- }
- void reset() {
- if (defined)
- reinterpret_cast<T*>(data)->~T();
- defined = false;
- }
- ~Optional() {
- reset();
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement