From 6ac825fe586b36c73abcadb6300a252c1da7b45a Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 26 Jul 2018 16:04:13 +0900 Subject: Omittable<>: use std::decay<>, add assertion ...against unwrapping omitted values (the release build will return a default-constructed value). --- lib/util.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'lib/util.h') 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 class Omittable { + static_assert(!std::is_reference::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& operator=(const T& val) + Omittable(NoneTag) : _value(std::decay_t{}), _omitted(true) { } + Omittable(const std::decay_t& val) : _value(val) { } + Omittable(std::decay_t&& val) : _value(std::move(val)) { } + Omittable& operator=(const std::decay_t& val) { _value = val; _omitted = false; return *this; } - Omittable& operator=(T&& val) + Omittable& operator=(std::decay_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& value() const { Q_ASSERT(!_omitted); return _value; } + std::decay_t& value() { Q_ASSERT(!_omitted); return _value; } + std::decay_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* operator->() const { return &value(); } + std::decay_t* operator->() { return &value(); } + const std::decay_t& operator*() const { return value(); } + std::decay_t& operator*() { return value(); } private: T _value; -- cgit v1.2.3