diff --git a/simgear/misc/CMakeLists.txt b/simgear/misc/CMakeLists.txt index 33cc4a52..f623903b 100644 --- a/simgear/misc/CMakeLists.txt +++ b/simgear/misc/CMakeLists.txt @@ -20,6 +20,7 @@ set(HEADERS texcoord.hxx test_macros.hxx lru_cache.hxx + simgear_optional.hxx ) set(SOURCES diff --git a/simgear/misc/simgear_optional.hxx b/simgear/misc/simgear_optional.hxx new file mode 100644 index 00000000..07ad6789 --- /dev/null +++ b/simgear/misc/simgear_optional.hxx @@ -0,0 +1,95 @@ +// -*- coding: utf-8 -*- +// +// simgear_optional.hxx --- Mimic std::optional until we can use C++14 +// Copyright (C) 2020 James Turner +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +// MA 02110-1301 USA. + + +#pragma once + +#include + +namespace simgear +{ + +/** + * Inefficient version of std::optional. It requires a default-constructable, + * copyable T type, unlike the real version. + */ + +template +class optional +{ +public: + using value_type = T; + + optional() = default; + + optional(const T& v) : + _value(v), + _haveValue(true) + {} + + optional(const optional& other) : + _value(other._value), + _haveValue(other._haveValue) + {} + + optional& operator=(const optional& other) + { + _haveValue = other._haveValue; + _value = other._value; + return *this; + } + + explicit operator bool() const + { + return _haveValue; + } + + bool has_value() const + { + return _haveValue; + } + + const T& value() const + { + if (!_haveValue) { + throw sg_exception("No value in optional"); + } + return _value; + } + + T& value() + { + if (!_haveValue) { + throw sg_exception("No value in optional"); + } + return _value; + } + + void reset() + { + _haveValue = false; + _value = {}; + } +private: + T _value = {}; + bool _haveValue = false; +}; + +} // of namespace simgear