X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FOptional.h;h=ee94228e8169593a1e6689323b31de67f8a268e6;hb=d08270e6cbc374ef67b55f21beed0cfcc359d0e1;hp=f85fbf6b600a2e949d985292848cb824727d16e7;hpb=22afce906d7e98d95f8c45c3301072d9fd891d41;p=folly.git diff --git a/folly/Optional.h b/folly/Optional.h index f85fbf6b..ee94228e 100644 --- a/folly/Optional.h +++ b/folly/Optional.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,13 +54,14 @@ * cout << *v << endl; * } */ -#include #include #include #include +#include #include +#include namespace folly { @@ -112,15 +113,17 @@ class Optional { } } - /* implicit */ Optional(const None&) + /* implicit */ Optional(const None&) noexcept : hasValue_(false) { } - /* implicit */ Optional(Value&& newValue) { + /* implicit */ Optional(Value&& newValue) + noexcept(std::is_nothrow_move_constructible::value) { construct(std::move(newValue)); } - /* implicit */ Optional(const Value& newValue) { + /* implicit */ Optional(const Value& newValue) + noexcept(std::is_nothrow_copy_constructible::value) { construct(newValue); } @@ -133,11 +136,13 @@ class Optional { } void assign(Optional&& src) { - if (src.hasValue()) { - assign(std::move(src.value())); - src.clear(); - } else { - clear(); + if (this != &src) { + if (src.hasValue()) { + assign(std::move(src.value())); + src.clear(); + } else { + clear(); + } } } @@ -220,6 +225,17 @@ class Optional { const Value* operator->() const { return &value(); } Value* operator->() { return &value(); } + // Return a copy of the value if set, or a given default if not. + template + Value value_or(U&& dflt) const& { + return hasValue_ ? value_ : std::forward(dflt); + } + + template + Value value_or(U&& dflt) && { + return hasValue_ ? std::move(value_) : std::forward(dflt); + } + private: template void construct(Args&&... args) { @@ -265,11 +281,27 @@ Opt make_optional(T&& v) { return Opt(std::forward(v)); } +/////////////////////////////////////////////////////////////////////////////// +// Comparisons. + template -bool operator< (const Optional& a, const Optional& b) { - if (a.hasValue() != b.hasValue()) { return a.hasValue() < b.hasValue(); } - if (a.hasValue()) { return a.value() < b.value(); } - return false; +bool operator==(const Optional& a, const V& b) { + return a.hasValue() && a.value() == b; +} + +template +bool operator!=(const Optional& a, const V& b) { + return !(a == b); +} + +template +bool operator==(const V& a, const Optional& b) { + return b.hasValue() && b.value() == a; +} + +template +bool operator!=(const V& a, const Optional& b) { + return !(a == b); } template @@ -279,19 +311,16 @@ bool operator==(const Optional& a, const Optional& b) { return true; } -template -bool operator<=(const Optional& a, const Optional& b) { - return !(b < a); -} - template bool operator!=(const Optional& a, const Optional& b) { - return !(b == a); + return !(a == b); } template -bool operator>=(const Optional& a, const Optional& b) { - return !(a < b); +bool operator< (const Optional& a, const Optional& b) { + if (a.hasValue() != b.hasValue()) { return a.hasValue() < b.hasValue(); } + if (a.hasValue()) { return a.value() < b.value(); } + return false; } template @@ -299,20 +328,28 @@ bool operator> (const Optional& a, const Optional& b) { return b < a; } -// To supress comparability of Optional with T, despite implicit conversion. +template +bool operator<=(const Optional& a, const Optional& b) { + return !(b < a); +} + +template +bool operator>=(const Optional& a, const Optional& b) { + return !(a < b); +} + +// Suppress comparability of Optional with T, despite implicit conversion. template bool operator< (const Optional&, const V& other) = delete; template bool operator<=(const Optional&, const V& other) = delete; -template bool operator==(const Optional&, const V& other) = delete; -template bool operator!=(const Optional&, const V& other) = delete; template bool operator>=(const Optional&, const V& other) = delete; template bool operator> (const Optional&, const V& other) = delete; template bool operator< (const V& other, const Optional&) = delete; template bool operator<=(const V& other, const Optional&) = delete; -template bool operator==(const V& other, const Optional&) = delete; -template bool operator!=(const V& other, const Optional&) = delete; template bool operator>=(const V& other, const Optional&) = delete; template bool operator> (const V& other, const Optional&) = delete; +/////////////////////////////////////////////////////////////////////////////// + } // namespace folly -#endif//FOLLY_OPTIONAL_H_ +#endif // FOLLY_OPTIONAL_H_