/
niceSOFT
/
cmake
Обзор
Документация
Войти
/
niceSOFT
/
cmake
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Utilities/cmcppdap/include/dap/optional.h
263 строки
6 KB
Glen Chung
Merge branch 'upstream-cppdap' into import-cppdap
26 май 2023, 16:36
26 май 2023, 16:36
3381e6b
Код
Авторство
О чём код?
// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef dap_optional_h #define dap_optional_h #include <assert.h> #include <type_traits> #include <utility> // std::move, std::forward namespace dap { // optional holds an 'optional' contained value. // This is similar to C++17's std::optional. template <typename T> class optional { template <typename U> using IsConvertibleToT = typename std::enable_if<std::is_convertible<U, T>::value>::type; public: using value_type = T; // constructors inline optional() = default; inline optional(const optional& other); inline optional(optional&& other); template <typename U> inline optional(const optional<U>& other); template <typename U> inline optional(optional<U>&& other); template <typename U = value_type, typename = IsConvertibleToT<U>> inline optional(U&& value); // value() returns the contained value. // If the optional does not contain a value, then value() will assert. inline T& value(); inline const T& value() const; // value() returns the contained value, or defaultValue if the optional does // not contain a value. inline const T& value(const T& defaultValue) const; // operator bool() returns true if the optional contains a value. inline explicit operator bool() const noexcept; // has_value() returns true if the optional contains a value. inline bool has_value() const; // assignment inline optional& operator=(const optional& other); inline optional& operator=(optional&& other) noexcept; template <typename U = T, typename = IsConvertibleToT<U>> inline optional& operator=(U&& value); template <typename U> inline optional& operator=(const optional<U>& other); template <typename U> inline optional& operator=(optional<U>&& other); // value access inline const T* operator->() const; inline T* operator->(); inline const T& operator*() const; inline T& operator*(); private: T val{}; bool set = false; }; template <typename T> optional<T>::optional(const optional& other) : val(other.val), set(other.set) {} template <typename T> optional<T>::optional(optional&& other) : val(std::move(other.val)), set(other.set) {} template <typename T> template <typename U> optional<T>::optional(const optional<U>& other) : set(other.has_value()) { if (set) { val = static_cast<T>(other.value()); } } template <typename T> template <typename U> optional<T>::optional(optional<U>&& other) : set(other.has_value()) { if (set) { val = static_cast<T>(std::move(other.value())); } } template <typename T> template <typename U /*= T*/, typename> optional<T>::optional(U&& value) : val(std::forward<U>(value)), set(true) {} template <typename T> T& optional<T>::value() { assert(set); return val; } template <typename T> const T& optional<T>::value() const { assert(set); return val; } template <typename T> const T& optional<T>::value(const T& defaultValue) const { if (!has_value()) { return defaultValue; } return val; } template <typename T> optional<T>::operator bool() const noexcept { return set; } template <typename T> bool optional<T>::has_value() const { return set; } template <typename T> optional<T>& optional<T>::operator=(const optional& other) { val = other.val; set = other.set; return *this; } template <typename T> optional<T>& optional<T>::operator=(optional&& other) noexcept { val = std::move(other.val); set = other.set; return *this; } template <typename T> template <typename U /* = T */, typename> optional<T>& optional<T>::operator=(U&& value) { val = std::forward<U>(value); set = true; return *this; } template <typename T> template <typename U> optional<T>& optional<T>::operator=(const optional<U>& other) { val = other.val; set = other.set; return *this; } template <typename T> template <typename U> optional<T>& optional<T>::operator=(optional<U>&& other) { val = std::move(other.val); set = other.set; return *this; } template <typename T> const T* optional<T>::operator->() const { assert(set); return &val; } template <typename T> T* optional<T>::operator->() { assert(set); return &val; } template <typename T> const T& optional<T>::operator*() const { assert(set); return val; } template <typename T> T& optional<T>::operator*() { assert(set); return val; } template <class T, class U> inline bool operator==(const optional<T>& lhs, const optional<U>& rhs) { if (!lhs.has_value() && !rhs.has_value()) { return true; } if (!lhs.has_value() || !rhs.has_value()) { return false; } return lhs.value() == rhs.value(); } template <class T, class U> inline bool operator!=(const optional<T>& lhs, const optional<U>& rhs) { return !(lhs == rhs); } template <class T, class U> inline bool operator<(const optional<T>& lhs, const optional<U>& rhs) { if (!rhs.has_value()) { return false; } if (!lhs.has_value()) { return true; } return lhs.value() < rhs.value(); } template <class T, class U> inline bool operator<=(const optional<T>& lhs, const optional<U>& rhs) { if (!lhs.has_value()) { return true; } if (!rhs.has_value()) { return false; } return lhs.value() <= rhs.value(); } template <class T, class U> inline bool operator>(const optional<T>& lhs, const optional<U>& rhs) { if (!lhs.has_value()) { return false; } if (!rhs.has_value()) { return true; } return lhs.value() > rhs.value(); } template <class T, class U> inline bool operator>=(const optional<T>& lhs, const optional<U>& rhs) { if (!rhs.has_value()) { return true; } if (!lhs.has_value()) { return false; } return lhs.value() >= rhs.value(); } } // namespace dap #endif // dap_optional_h