Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed_DS28EC20_GPIO
optional.hpp
00001 /******************************************************************************* 00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #ifndef MaximInterface_optional 00034 #define MaximInterface_optional 00035 00036 #include "SafeBool.hpp" 00037 00038 // Include for std::swap. 00039 #include <algorithm> 00040 #include <utility> 00041 00042 namespace MaximInterface { 00043 00044 struct nullopt_t { 00045 explicit nullopt_t(int) {} 00046 }; 00047 00048 static const nullopt_t nullopt(0); 00049 00050 /// @brief Optional value container similar to std::optional. 00051 /// @details 00052 /// To prevent the need for aligned storage, this implementation imposes that 00053 /// types must be DefaultConstructible, CopyConstructible, and CopyAssignable. 00054 /// No exceptions are thrown when accessing a valueless optional. 00055 template <typename T> class optional { 00056 public: 00057 typedef T value_type; 00058 00059 optional() : value_(), has_value_(false) {} 00060 00061 optional(nullopt_t) : value_(), has_value_(false) {} 00062 00063 optional(const T & value) : value_(value), has_value_(true) {} 00064 00065 template <typename U> 00066 explicit optional(const optional<U> & other) 00067 : value_(other.value_), has_value_(other.has_value_) {} 00068 00069 optional & operator=(nullopt_t) { 00070 reset(); 00071 return *this; 00072 } 00073 00074 optional & operator=(const T & value) { 00075 value_ = value; 00076 has_value_ = true; 00077 return *this; 00078 } 00079 00080 template <typename U> optional & operator=(const optional<U> & other) { 00081 if (has_value_ || other.has_value_) { 00082 value_ = other.value_; 00083 has_value_ = other.has_value_; 00084 } 00085 return *this; 00086 } 00087 00088 bool has_value() const { return has_value_; } 00089 00090 operator SafeBool() const { return makeSafeBool(has_value()); } 00091 00092 const T & value() const { return value_; } 00093 00094 T & value() { 00095 return const_cast<T &>(static_cast<const optional &>(*this).value()); 00096 } 00097 00098 const T & operator*() const { return value(); } 00099 00100 T & operator*() { 00101 return const_cast<T &>(static_cast<const optional &>(*this).operator*()); 00102 } 00103 00104 const T * operator->() const { return &value(); } 00105 00106 T * operator->() { 00107 return const_cast<T *>(static_cast<const optional &>(*this).operator->()); 00108 } 00109 00110 const T & value_or(const T & default_value) const { 00111 return has_value() ? value() : default_value; 00112 } 00113 00114 void swap(optional & other) { 00115 if (has_value_ || other.has_value_) { 00116 using std::swap; 00117 swap(value_, other.value_); 00118 swap(has_value_, other.has_value_); 00119 } 00120 } 00121 00122 void reset() { 00123 if (has_value_) { 00124 has_value_ = false; 00125 value_ = T(); 00126 } 00127 } 00128 00129 private: 00130 T value_; 00131 bool has_value_; 00132 }; 00133 00134 template <typename T> optional<T> make_optional(const T & value) { 00135 return value; 00136 } 00137 00138 template <typename T> void swap(optional<T> & lhs, optional<T> & rhs) { 00139 lhs.swap(rhs); 00140 } 00141 00142 template <typename T, typename U> 00143 bool operator==(const optional<T> & lhs, const optional<U> & rhs) { 00144 if (lhs.has_value() != rhs.has_value()) { 00145 return false; 00146 } 00147 if (!lhs.has_value()) { 00148 return true; 00149 } 00150 return lhs.value() == rhs.value(); 00151 } 00152 00153 template <typename T, typename U> 00154 bool operator!=(const optional<T> & lhs, const optional<U> & rhs) { 00155 if (lhs.has_value() != rhs.has_value()) { 00156 return true; 00157 } 00158 if (!lhs.has_value()) { 00159 return false; 00160 } 00161 return lhs.value() != rhs.value(); 00162 } 00163 00164 template <typename T, typename U> 00165 bool operator<(const optional<T> & lhs, const optional<U> & rhs) { 00166 if (!rhs.has_value()) { 00167 return false; 00168 } 00169 if (!lhs.has_value()) { 00170 return true; 00171 } 00172 return lhs.value() < rhs.value(); 00173 } 00174 00175 template <typename T, typename U> 00176 bool operator<=(const optional<T> & lhs, const optional<U> & rhs) { 00177 if (!lhs.has_value()) { 00178 return true; 00179 } 00180 if (!rhs.has_value()) { 00181 return false; 00182 } 00183 return lhs.value() <= rhs.value(); 00184 } 00185 00186 template <typename T, typename U> 00187 bool operator>(const optional<T> & lhs, const optional<U> & rhs) { 00188 if (!lhs.has_value()) { 00189 return false; 00190 } 00191 if (!rhs.has_value()) { 00192 return true; 00193 } 00194 return lhs.value() > rhs.value(); 00195 } 00196 00197 template <typename T, typename U> 00198 bool operator>=(const optional<T> & lhs, const optional<U> & rhs) { 00199 if (!rhs.has_value()) { 00200 return true; 00201 } 00202 if (!lhs.has_value()) { 00203 return false; 00204 } 00205 return lhs.value() >= rhs.value(); 00206 } 00207 00208 template <typename T> bool operator==(const optional<T> & opt, nullopt_t) { 00209 return !opt.has_value(); 00210 } 00211 00212 template <typename T> bool operator==(nullopt_t, const optional<T> & opt) { 00213 return operator==(opt, nullopt); 00214 } 00215 00216 template <typename T> bool operator!=(const optional<T> & opt, nullopt_t) { 00217 return !operator==(opt, nullopt); 00218 } 00219 00220 template <typename T> bool operator!=(nullopt_t, const optional<T> & opt) { 00221 return operator!=(opt, nullopt); 00222 } 00223 00224 template <typename T> bool operator<(const optional<T> &, nullopt_t) { 00225 return false; 00226 } 00227 00228 template <typename T> bool operator<(nullopt_t, const optional<T> & opt) { 00229 return opt.has_value(); 00230 } 00231 00232 template <typename T> bool operator<=(const optional<T> & opt, nullopt_t) { 00233 return !operator>(opt, nullopt); 00234 } 00235 00236 template <typename T> bool operator<=(nullopt_t, const optional<T> & opt) { 00237 return !operator>(nullopt, opt); 00238 } 00239 00240 template <typename T> bool operator>(const optional<T> & opt, nullopt_t) { 00241 return operator<(nullopt, opt); 00242 } 00243 00244 template <typename T> bool operator>(nullopt_t, const optional<T> & opt) { 00245 return operator<(opt, nullopt); 00246 } 00247 00248 template <typename T> bool operator>=(const optional<T> & opt, nullopt_t) { 00249 return !operator<(opt, nullopt); 00250 } 00251 00252 template <typename T> bool operator>=(nullopt_t, const optional<T> & opt) { 00253 return !operator<(nullopt, opt); 00254 } 00255 00256 template <typename T, typename U> 00257 bool operator==(const optional<T> & opt, const U & value) { 00258 return opt.has_value() ? opt.value() == value : false; 00259 } 00260 00261 template <typename T, typename U> 00262 bool operator==(const T & value, const optional<U> & opt) { 00263 return operator==(opt, value); 00264 } 00265 00266 template <typename T, typename U> 00267 bool operator!=(const optional<T> & opt, const U & value) { 00268 return opt.has_value() ? opt.value() != value : true; 00269 } 00270 00271 template <typename T, typename U> 00272 bool operator!=(const T & value, const optional<U> & opt) { 00273 return operator!=(opt, value); 00274 } 00275 00276 template <typename T, typename U> 00277 bool operator<(const optional<T> & opt, const U & value) { 00278 return opt.has_value() ? opt.value() < value : true; 00279 } 00280 00281 template <typename T, typename U> 00282 bool operator<(const T & value, const optional<U> & opt) { 00283 return opt.has_value() ? value < opt.value() : false; 00284 } 00285 00286 template <typename T, typename U> 00287 bool operator<=(const optional<T> & opt, const U & value) { 00288 return opt.has_value() ? opt.value() <= value : true; 00289 } 00290 00291 template <typename T, typename U> 00292 bool operator<=(const T & value, const optional<U> & opt) { 00293 return opt.has_value() ? value <= opt.value() : false; 00294 } 00295 00296 template <typename T, typename U> 00297 bool operator>(const optional<T> & opt, const U & value) { 00298 return opt.has_value() ? opt.value() > value : false; 00299 } 00300 00301 template <typename T, typename U> 00302 bool operator>(const T & value, const optional<U> & opt) { 00303 return opt.has_value() ? value > opt.value() : true; 00304 } 00305 00306 template <typename T, typename U> 00307 bool operator>=(const optional<T> & opt, const U & value) { 00308 return opt.has_value() ? opt.value() >= value : false; 00309 } 00310 00311 template <typename T, typename U> 00312 bool operator>=(const T & value, const optional<U> & opt) { 00313 return opt.has_value() ? value >= opt.value() : true; 00314 } 00315 00316 } // namespace MaximInterface 00317 00318 #endif
Generated on Tue Jul 12 2022 23:29:45 by
1.7.2