summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcppdap/include/dap/optional.h
diff options
context:
space:
mode:
authorGlen Chung <kuchung@microsoft.com>2023-05-26 13:33:57 (GMT)
committerBrad King <brad.king@kitware.com>2023-05-26 13:36:03 (GMT)
commit3381e6bd5cbfa1694f07c97a19747adda10b06f2 (patch)
treea99c177695b41b4f6576f74a7a59a7721de96687 /Utilities/cmcppdap/include/dap/optional.h
parentbd58bc7817e9546cb6726a52657f54b1cde59b0c (diff)
parent1daeefc37856c209718b406dcb86d44519393dd1 (diff)
downloadCMake-3381e6bd5cbfa1694f07c97a19747adda10b06f2.zip
CMake-3381e6bd5cbfa1694f07c97a19747adda10b06f2.tar.gz
CMake-3381e6bd5cbfa1694f07c97a19747adda10b06f2.tar.bz2
Merge branch 'upstream-cppdap' into import-cppdap
* upstream-cppdap: cppdap 2023-05-26 (03cc1867)
Diffstat (limited to 'Utilities/cmcppdap/include/dap/optional.h')
-rw-r--r--Utilities/cmcppdap/include/dap/optional.h263
1 files changed, 263 insertions, 0 deletions
diff --git a/Utilities/cmcppdap/include/dap/optional.h b/Utilities/cmcppdap/include/dap/optional.h
new file mode 100644
index 0000000..9a3d216
--- /dev/null
+++ b/Utilities/cmcppdap/include/dap/optional.h
@@ -0,0 +1,263 @@
+// 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