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