aboutsummaryrefslogtreecommitdiff
path: root/lib/converters.h
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-06-02 13:32:47 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-06-02 13:32:47 +0900
commit0dd491fbd189baaabadcab2344a05e3cf3898287 (patch)
tree13b8ebe63ba8b156ddd6ddab8b0ad2845d7c9c42 /lib/converters.h
parente7ac6f3480358fd989c8a3090590d665d18e1cec (diff)
downloadlibquotient-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.h63
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