diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-06-02 13:32:47 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-06-02 13:32:47 +0900 |
commit | 0dd491fbd189baaabadcab2344a05e3cf3898287 (patch) | |
tree | 13b8ebe63ba8b156ddd6ddab8b0ad2845d7c9c42 /lib/converters.h | |
parent | e7ac6f3480358fd989c8a3090590d665d18e1cec (diff) | |
download | libquotient-0dd491fbd189baaabadcab2344a05e3cf3898287.tar.gz libquotient-0dd491fbd189baaabadcab2344a05e3cf3898287.zip |
csapi: Use Omittable<> container instead of intrusive 'omitted' field
Also: use the latest feature of GTAD, +set/+on, to make gtad.yaml more compact.
Diffstat (limited to 'lib/converters.h')
-rw-r--r-- | lib/converters.h | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/lib/converters.h b/lib/converters.h index fb1da6d7..916124a6 100644 --- a/lib/converters.h +++ b/lib/converters.h @@ -45,6 +45,47 @@ namespace std namespace QMatrixClient { + 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), _omitted(false) { } + Omittable(T&& val) : _value(std::move(val)), _omitted(false) { } + 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; } + + private: + T _value; + bool _omitted; + }; + + // This catches anything implicitly convertible to QJsonValue/Object/Array inline QJsonValue toJson(const QJsonValue& val) { return val; } inline QJsonObject toJson(const QJsonObject& o) { return o; } @@ -99,6 +140,16 @@ namespace QMatrixClient return json; } + template <typename T> + inline auto toJson(const Omittable<T>& omittable) + -> decltype(toJson(omittable.value())) + { + if (omittable) + return toJson(omittable.value()); + + return {}; + } + #if 0 template <typename T> inline auto toJson(const optional<T>& optVal) @@ -287,16 +338,4 @@ namespace QMatrixClient _impl::AddNode<std::conditional_t<Force, QJsonValue, decltype(json)>> ::impl(o, std::move(key), std::move(json)); } - - /** Construct an "omitted" value of a given type - * This is a workaround for the time being while we're not C++17 and - * cannot use `optional`. - */ - template <typename T> - inline T omitted() - { - T val; - val.omitted = true; - return val; - } } // namespace QMatrixClient |