aboutsummaryrefslogtreecommitdiff
path: root/lib/util.h
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-07-08 09:02:23 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-07-08 09:02:23 +0900
commitcab30e850847ac221b08c3a8b715d0298bb63ddf (patch)
tree9bb3ccdbef0f706b2bacfe541466aedfe7bbc318 /lib/util.h
parentab1f92a1eea2556f9ee6dd81f343c5b61f1b781c (diff)
downloadlibquotient-cab30e850847ac221b08c3a8b715d0298bb63ddf.tar.gz
libquotient-cab30e850847ac221b08c3a8b715d0298bb63ddf.zip
Move Omittable<> to util.h
Diffstat (limited to 'lib/util.h')
-rw-r--r--lib/util.h44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/util.h b/lib/util.h
index 78d90626..aa44893f 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -64,6 +64,50 @@ namespace QMatrixClient
return std::unique_ptr<T1>(static_cast<T1*>(p.release()));
}
+ struct NoneTag {};
+ constexpr NoneTag none {};
+
+ /** A crude substitute for `optional` while we're not C++17
+ *
+ * Only works with default-constructible types.
+ */
+ template <typename T>
+ class Omittable
+ {
+ public:
+ explicit Omittable() : Omittable(none) { }
+ Omittable(NoneTag) : _omitted(true) { }
+ Omittable(const T& val) : _value(val) { }
+ Omittable(T&& val) : _value(std::move(val)) { }
+ Omittable<T>& operator=(const T& val)
+ {
+ _value = val;
+ _omitted = false;
+ return *this;
+ }
+ Omittable<T>& operator=(T&& val)
+ {
+ _value = std::move(val);
+ _omitted = false;
+ return *this;
+ }
+
+ bool omitted() const { return _omitted; }
+ const T& value() const { return _value; }
+ T& value() { return _value; }
+ T&& release() { _omitted = true; return std::move(_value); }
+
+ operator bool() const { return !omitted(); }
+ const T& operator->() const { return &_value; }
+ T& operator->() { return &_value; }
+ const T& operator*() const { return _value; }
+ T& operator*() { return _value; }
+
+ private:
+ T _value;
+ bool _omitted = false;
+ };
+
/** Determine traits of an arbitrary function/lambda/functor
* This only works with arity of 1 (1-argument) for now but is extendable
* to other cases. Also, doesn't work with generic lambdas and function