aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-01-19 13:58:23 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-01-19 13:58:23 +0200
commit06f409edcbf653aa008ac0383609f13624bce9f7 (patch)
tree06121aced02ca8577d7456274ba2d426b3f7ad41
parent0047a9fdfc83c8fbd40fd235514f46cebc61df95 (diff)
Improve optional (has_value(), operator<>, std::hash<> specialization)
-rw-r--r--butl/optional35
1 files changed, 34 insertions, 1 deletions
diff --git a/butl/optional b/butl/optional
index 0877f52..f6cc15e 100644
--- a/butl/optional
+++ b/butl/optional
@@ -5,7 +5,8 @@
#ifndef BUTL_OPTIONAL
#define BUTL_OPTIONAL
-#include <utility> // move()
+#include <utility> // move()
+#include <functional> // hash
namespace butl
{
@@ -38,6 +39,7 @@ namespace butl
T& operator* () {return value_;}
const T& operator* () const {return value_;}
+ bool has_value () const {return !null_;}
explicit operator bool () const {return !null_;}
private:
@@ -58,6 +60,37 @@ namespace butl
{
return !(x == y);
}
+
+ template <typename T>
+ inline auto
+ operator< (const optional<T>& x, const optional<T>& y) -> decltype (*x < *y)
+ {
+ bool px (x), py (y);
+ return px < py || (px && py && *x < *y);
+ }
+
+ template <typename T>
+ inline auto
+ operator> (const optional<T>& x, const optional<T>& y) -> decltype (*x > *y)
+ {
+ return y < x;
+ }
+}
+
+namespace std
+{
+ template <typename T>
+ struct hash<butl::optional<T>>: hash<T>
+ {
+ using argument_type = butl::optional<T>;
+
+ size_t
+ operator() (const butl::optional<T>& o) const
+ noexcept (noexcept (hash<T> {} (*o)))
+ {
+ return o ? hash<T>::operator() (*o) : static_cast<size_t> (-3333);
+ }
+ };
}
#endif // BUTL_OPTIONAL