/* An optional object. Copyright (C) 2017 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 . */ #ifndef GDB_OPTIONAL_H #define GDB_OPTIONAL_H namespace gdb { /* 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. */ template class optional { public: optional () : m_instantiated (false) { } ~optional () { if (m_instantiated) destroy (); } /* These aren't deleted in std::optional, but it was simpler to delete them here, because currently the users of this class don't need them, and making them depend on the definition of T is somewhat complicated. */ optional (const optional &other) = delete; optional &operator= (const optional &other) = delete; template void emplace (Args &&... args) { if (m_instantiated) destroy (); new (&m_item) T (std::forward(args)...); m_instantiated = true; } private: /* Destroy the object. */ void destroy () { gdb_assert (m_instantiated); m_instantiated = false; m_item.~T (); } /* The object. */ union { struct { } m_dummy; T m_item; }; /* True if the object was ever emplaced. */ bool m_instantiated; }; } #endif /* GDB_OPTIONAL_H */