aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-07-26 16:04:13 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-07-27 12:16:14 +0900
commit6ac825fe586b36c73abcadb6300a252c1da7b45a (patch)
treea97efbf3ec08fa1493e4407cec7b9841002b07d9
parent61e0c0401afe937698c65903e6b43f1c78518f8d (diff)
downloadlibquotient-6ac825fe586b36c73abcadb6300a252c1da7b45a.tar.gz
libquotient-6ac825fe586b36c73abcadb6300a252c1da7b45a.zip
Omittable<>: use std::decay<>, add assertion
...against unwrapping omitted values (the release build will return a default-constructed value).
-rw-r--r--lib/util.h26
1 files changed, 14 insertions, 12 deletions
diff --git a/lib/util.h b/lib/util.h
index aa44893f..c5363054 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -74,18 +74,20 @@ namespace QMatrixClient
template <typename T>
class Omittable
{
+ static_assert(!std::is_reference<T>::value,
+ "You cannot make an Omittable<> with a reference type");
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)
+ Omittable(NoneTag) : _value(std::decay_t<T>{}), _omitted(true) { }
+ Omittable(const std::decay_t<T>& val) : _value(val) { }
+ Omittable(std::decay_t<T>&& val) : _value(std::move(val)) { }
+ Omittable<T>& operator=(const std::decay_t<T>& val)
{
_value = val;
_omitted = false;
return *this;
}
- Omittable<T>& operator=(T&& val)
+ Omittable<T>& operator=(std::decay_t<T>&& val)
{
_value = std::move(val);
_omitted = false;
@@ -93,15 +95,15 @@ namespace QMatrixClient
}
bool omitted() const { return _omitted; }
- const T& value() const { return _value; }
- T& value() { return _value; }
- T&& release() { _omitted = true; return std::move(_value); }
+ const std::decay_t<T>& value() const { Q_ASSERT(!_omitted); return _value; }
+ std::decay_t<T>& value() { Q_ASSERT(!_omitted); return _value; }
+ std::decay_t<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; }
+ const std::decay<T>* operator->() const { return &value(); }
+ std::decay_t<T>* operator->() { return &value(); }
+ const std::decay_t<T>& operator*() const { return value(); }
+ std::decay_t<T>& operator*() { return value(); }
private:
T _value;