diff options
author | B Stack <bgstack15@gmail.com> | 2018-09-10 02:46:25 +0000 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2018-09-10 02:46:25 +0000 |
commit | 728d32e6da9ce66968f8eef47a59505d613e2c1b (patch) | |
tree | 0f0441755ff0e6d65e12222d4502c648bffd6a7c /zen/optional.h | |
parent | 10.3 (diff) | |
parent | pull in latest 10.4 from upstream (diff) | |
download | FreeFileSync-10.4.tar.gz FreeFileSync-10.4.tar.bz2 FreeFileSync-10.4.zip |
Merge branch '10.4' into 'master'10.4
pull in latest 10.4 from upstream
See merge request opensource-tracking/FreeFileSync!1
Diffstat (limited to 'zen/optional.h')
-rwxr-xr-x | zen/optional.h | 114 |
1 files changed, 0 insertions, 114 deletions
diff --git a/zen/optional.h b/zen/optional.h deleted file mode 100755 index e4605c5f..00000000 --- a/zen/optional.h +++ /dev/null @@ -1,114 +0,0 @@ -// ***************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 * -// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * -// ***************************************************************************** - -#ifndef OPTIONAL_H_2857428578342203589 -#define OPTIONAL_H_2857428578342203589 - -#include <type_traits> - - -namespace zen -{ -/* -Optional return value without heap memory allocation! - -> interface like a pointer, performance like a value - - Usage: - ------ - Opt<MyEnum> someFunction(); -{ - if (allIsWell) - return enumVal; - else - return NoValue(); -} - - Opt<MyEnum> optValue = someFunction(); - if (optValue) - ... use *optValue ... -*/ - -struct NoValue {}; - -template <class T> -class Opt -{ -public: - Opt() {} - Opt(NoValue) {} - Opt(const T& val) : valid_(true) { new (&rawMem_) T(val); } //throw X - Opt( T&& tmp) : valid_(true) { new (&rawMem_) T(std::move(tmp)); } - - Opt(const Opt& other) : valid_(other.valid_) - { - if (const T* val = other.get()) - new (&rawMem_) T(*val); //throw X - } - - ~Opt() { if (T* val = get()) val->~T(); } - - Opt& operator=(const Opt& other) //strong exception-safety iff T::operator=() is strongly exception-safe - { - if (T* val = get()) - { - if (const T* valOther = other.get()) - *val = *valOther; //throw X - else - { - valid_ = false; - val->~T(); - } - } - else if (const T* valOther = other.get()) - { - new (&rawMem_) T(*valOther); //throw X - valid_ = true; - } - return *this; - } - - Opt& operator=(NoValue) //support assignment to Opt<const T> - { - if (T* val = get()) - { - valid_ = false; - val->~T(); - } - return *this; - } - - explicit operator bool() const { return valid_; } //thank you, C++11!!! - - const T* get() const { return valid_ ? reinterpret_cast<const T*>(&rawMem_) : nullptr; } - T* get() { return valid_ ? reinterpret_cast< T*>(&rawMem_) : nullptr; } - - const T& operator*() const { return *get(); } - /**/ T& operator*() { return *get(); } - - const T* operator->() const { return get(); } - /**/ T* operator->() { return get(); } - -private: - std::aligned_storage_t<sizeof(T), alignof(T)> rawMem_; //don't require T to be default-constructible! - bool valid_ = false; -}; - - -template <class T> inline -bool operator==(const Opt<T>& lhs, const Opt<T>& rhs) -{ - if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) - return false; - if (!lhs) - return true; - return *lhs == *rhs; -} -template <class T> inline -bool operator!=(const Opt<T>& lhs, const Opt<T>& rhs) { return !(lhs == rhs); } - -} - -#endif //OPTIONAL_H_2857428578342203589 |