Path: blob/master/Utilities/cmcppdap/include/dap/optional.h
3158 views
// Copyright 2019 Google LLC1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// https://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314#ifndef dap_optional_h15#define dap_optional_h1617#include <assert.h>18#include <type_traits>19#include <utility> // std::move, std::forward2021namespace dap {2223// optional holds an 'optional' contained value.24// This is similar to C++17's std::optional.25template <typename T>26class optional {27template <typename U>28using IsConvertibleToT =29typename std::enable_if<std::is_convertible<U, T>::value>::type;3031public:32using value_type = T;3334// constructors35inline optional() = default;36inline optional(const optional& other);37inline optional(optional&& other);38template <typename U>39inline optional(const optional<U>& other);40template <typename U>41inline optional(optional<U>&& other);42template <typename U = value_type, typename = IsConvertibleToT<U>>43inline optional(U&& value);4445// value() returns the contained value.46// If the optional does not contain a value, then value() will assert.47inline T& value();48inline const T& value() const;4950// value() returns the contained value, or defaultValue if the optional does51// not contain a value.52inline const T& value(const T& defaultValue) const;5354// operator bool() returns true if the optional contains a value.55inline explicit operator bool() const noexcept;5657// has_value() returns true if the optional contains a value.58inline bool has_value() const;5960// assignment61inline optional& operator=(const optional& other);62inline optional& operator=(optional&& other) noexcept;63template <typename U = T, typename = IsConvertibleToT<U>>64inline optional& operator=(U&& value);65template <typename U>66inline optional& operator=(const optional<U>& other);67template <typename U>68inline optional& operator=(optional<U>&& other);6970// value access71inline const T* operator->() const;72inline T* operator->();73inline const T& operator*() const;74inline T& operator*();7576private:77T val{};78bool set = false;79};8081template <typename T>82optional<T>::optional(const optional& other) : val(other.val), set(other.set) {}8384template <typename T>85optional<T>::optional(optional&& other)86: val(std::move(other.val)), set(other.set) {}8788template <typename T>89template <typename U>90optional<T>::optional(const optional<U>& other) : set(other.has_value()) {91if (set) {92val = static_cast<T>(other.value());93}94}9596template <typename T>97template <typename U>98optional<T>::optional(optional<U>&& other) : set(other.has_value()) {99if (set) {100val = static_cast<T>(std::move(other.value()));101}102}103104template <typename T>105template <typename U /*= T*/, typename>106optional<T>::optional(U&& value) : val(std::forward<U>(value)), set(true) {}107108template <typename T>109T& optional<T>::value() {110assert(set);111return val;112}113114template <typename T>115const T& optional<T>::value() const {116assert(set);117return val;118}119120template <typename T>121const T& optional<T>::value(const T& defaultValue) const {122if (!has_value()) {123return defaultValue;124}125return val;126}127128template <typename T>129optional<T>::operator bool() const noexcept {130return set;131}132133template <typename T>134bool optional<T>::has_value() const {135return set;136}137138template <typename T>139optional<T>& optional<T>::operator=(const optional& other) {140val = other.val;141set = other.set;142return *this;143}144145template <typename T>146optional<T>& optional<T>::operator=(optional&& other) noexcept {147val = std::move(other.val);148set = other.set;149return *this;150}151152template <typename T>153template <typename U /* = T */, typename>154optional<T>& optional<T>::operator=(U&& value) {155val = std::forward<U>(value);156set = true;157return *this;158}159160template <typename T>161template <typename U>162optional<T>& optional<T>::operator=(const optional<U>& other) {163val = other.val;164set = other.set;165return *this;166}167168template <typename T>169template <typename U>170optional<T>& optional<T>::operator=(optional<U>&& other) {171val = std::move(other.val);172set = other.set;173return *this;174}175176template <typename T>177const T* optional<T>::operator->() const {178assert(set);179return &val;180}181182template <typename T>183T* optional<T>::operator->() {184assert(set);185return &val;186}187188template <typename T>189const T& optional<T>::operator*() const {190assert(set);191return val;192}193194template <typename T>195T& optional<T>::operator*() {196assert(set);197return val;198}199200template <class T, class U>201inline bool operator==(const optional<T>& lhs, const optional<U>& rhs) {202if (!lhs.has_value() && !rhs.has_value()) {203return true;204}205if (!lhs.has_value() || !rhs.has_value()) {206return false;207}208return lhs.value() == rhs.value();209}210211template <class T, class U>212inline bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {213return !(lhs == rhs);214}215216template <class T, class U>217inline bool operator<(const optional<T>& lhs, const optional<U>& rhs) {218if (!rhs.has_value()) {219return false;220}221if (!lhs.has_value()) {222return true;223}224return lhs.value() < rhs.value();225}226227template <class T, class U>228inline bool operator<=(const optional<T>& lhs, const optional<U>& rhs) {229if (!lhs.has_value()) {230return true;231}232if (!rhs.has_value()) {233return false;234}235return lhs.value() <= rhs.value();236}237238template <class T, class U>239inline bool operator>(const optional<T>& lhs, const optional<U>& rhs) {240if (!lhs.has_value()) {241return false;242}243if (!rhs.has_value()) {244return true;245}246return lhs.value() > rhs.value();247}248249template <class T, class U>250inline bool operator>=(const optional<T>& lhs, const optional<U>& rhs) {251if (!rhs.has_value()) {252return true;253}254if (!lhs.has_value()) {255return false;256}257return lhs.value() >= rhs.value();258}259260} // namespace dap261262#endif // dap_optional_h263264265