diff options
Diffstat (limited to 'gdb/common/gdb_optional.h')
-rw-r--r-- | gdb/common/gdb_optional.h | 219 |
1 files changed, 0 insertions, 219 deletions
diff --git a/gdb/common/gdb_optional.h b/gdb/common/gdb_optional.h deleted file mode 100644 index 7ca5725..0000000 --- a/gdb/common/gdb_optional.h +++ /dev/null @@ -1,219 +0,0 @@ -/* An optional object. - - Copyright (C) 2017-2019 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef COMMON_GDB_OPTIONAL_H -#define COMMON_GDB_OPTIONAL_H - -#include "common/traits.h" - -namespace gdb -{ - -struct in_place_t -{ - explicit in_place_t () = default; -}; - -constexpr gdb::in_place_t in_place {}; - -/* This class attempts to be a compatible subset of std::optional, - which is slated to be available in C++17. This class optionally - holds an object of some type -- by default it is constructed not - holding an object, but later the object can be "emplaced". This is - similar to using std::unique_ptr, but in-object allocation is - guaranteed. - - Unlike std::optional, we currently only support copy/move - construction/assignment of an optional<T> from either exactly - optional<T> or T. I.e., we don't support copy/move - construction/assignment from optional<U> or U, when U is a type - convertible to T. Making that work depending on the definitions of - T and U is somewhat complicated, and currently the users of this - class don't need it. */ - -template<typename T> -class optional -{ -public: - - constexpr optional () - : m_dummy () - {} - - template<typename... Args> - constexpr optional (in_place_t, Args &&... args) - : m_item (std::forward<Args> (args)...), - m_instantiated (true) - {} - - ~optional () - { this->reset (); } - - /* Copy and move constructors. */ - - optional (const optional &other) - { - if (other.m_instantiated) - this->emplace (other.get ()); - } - - optional (optional &&other) - noexcept(std::is_nothrow_move_constructible<T> ()) - { - if (other.m_instantiated) - this->emplace (std::move (other.get ())); - } - - constexpr optional (const T &other) - : m_item (other), - m_instantiated (true) - {} - - constexpr optional (T &&other) - noexcept (std::is_nothrow_move_constructible<T> ()) - : m_item (std::move (other)), - m_instantiated (true) - {} - - /* Assignment operators. */ - - optional & - operator= (const optional &other) - { - if (m_instantiated && other.m_instantiated) - this->get () = other.get (); - else - { - if (other.m_instantiated) - this->emplace (other.get ()); - else - this->reset (); - } - - return *this; - } - - optional & - operator= (optional &&other) - noexcept (And<std::is_nothrow_move_constructible<T>, - std::is_nothrow_move_assignable<T>> ()) - { - if (m_instantiated && other.m_instantiated) - this->get () = std::move (other.get ()); - else - { - if (other.m_instantiated) - this->emplace (std::move (other.get ())); - else - this->reset (); - } - return *this; - } - - optional & - operator= (const T &other) - { - if (m_instantiated) - this->get () = other; - else - this->emplace (other); - return *this; - } - - optional & - operator= (T &&other) - noexcept (And<std::is_nothrow_move_constructible<T>, - std::is_nothrow_move_assignable<T>> ()) - { - if (m_instantiated) - this->get () = std::move (other); - else - this->emplace (std::move (other)); - return *this; - } - - template<typename... Args> - T &emplace (Args &&... args) - { - this->reset (); - new (&m_item) T (std::forward<Args>(args)...); - m_instantiated = true; - return this->get (); - } - - /* Observers. */ - constexpr const T *operator-> () const - { return std::addressof (this->get ()); } - - T *operator-> () - { return std::addressof (this->get ()); } - - constexpr const T &operator* () const & - { return this->get (); } - - T &operator* () & - { return this->get (); } - - T &&operator* () && - { return std::move (this->get ()); } - - constexpr const T &&operator* () const && - { return std::move (this->get ()); } - - constexpr explicit operator bool () const noexcept - { return m_instantiated; } - - constexpr bool has_value () const noexcept - { return m_instantiated; } - - /* 'reset' is a 'safe' operation with no precondition. */ - void reset () noexcept - { - if (m_instantiated) - this->destroy (); - } - -private: - - /* Destroy the object. */ - void destroy () - { - gdb_assert (m_instantiated); - m_instantiated = false; - m_item.~T (); - } - - /* The get operations have m_instantiated as a precondition. */ - T &get () noexcept { return m_item; } - constexpr const T &get () const noexcept { return m_item; } - - /* The object. */ - union - { - struct { } m_dummy; - T m_item; - }; - - /* True if the object was ever emplaced. */ - bool m_instantiated = false; -}; - -} - -#endif /* COMMON_GDB_OPTIONAL_H */ |