#include <string>
#include <vector>
+#include <memory>
#include <cassert>
#include <glib.h>
template<typename T>
void visit(const std::string& name, T& value)
{
- GVariant* child = g_variant_iter_next_value(mIter);
- if (child == NULL) {
+ auto child = makeUnique(g_variant_iter_next_value(mIter));
+ if (!child) {
throw config::ConfigException(
"GVariant doesn't match with config. Can't set '" + name + "'");
}
- fromGVariant(child, value);
- g_variant_unref(child);
+ fromGVariant(child.get(), value);
}
private:
GVariantIter* mIter;
- explicit FromGVariantVisitor(GVariant* variant, bool isUnion)
+ static std::unique_ptr<GVariant, decltype(&g_variant_unref)> makeUnique(GVariant* variant)
{
- if (isUnion) {
- checkType(variant, G_VARIANT_TYPE_VARIANT);
- variant = g_variant_get_variant(variant);
- }
- checkType(variant, G_VARIANT_TYPE_TUPLE);
- mIter = g_variant_iter_new(variant);
+ return std::unique_ptr<GVariant, decltype(&g_variant_unref)>(variant, g_variant_unref);
}
static void checkType(GVariant* object, const GVariantType* type)
}
}
- static void fromGVariant(GVariant* object, int& value)
+ static void fromGVariant(GVariant* object, std::int32_t& value)
{
checkType(object, G_VARIANT_TYPE_INT32);
value = g_variant_get_int32(object);
value = g_variant_get_int64(object);
}
+ static void fromGVariant(GVariant* object, std::uint32_t& value)
+ {
+ checkType(object, G_VARIANT_TYPE_UINT32);
+ value = g_variant_get_uint32(object);
+ }
+
+ static void fromGVariant(GVariant* object, std::uint64_t& value)
+ {
+ checkType(object, G_VARIANT_TYPE_UINT64);
+ value = g_variant_get_uint64(object);
+ }
+
static void fromGVariant(GVariant* object, bool& value)
{
checkType(object, G_VARIANT_TYPE_BOOLEAN);
int length = g_variant_iter_n_children(&iter);
value.resize(static_cast<size_t>(length));
for (int i = 0; i < length; ++i) {
- GVariant* child = g_variant_iter_next_value(&iter);
- assert(child != NULL);
- fromGVariant(child, value[static_cast<size_t>(i)]);
- g_variant_unref(child);
+ auto child = makeUnique(g_variant_iter_next_value(&iter));
+ assert(child);
+ fromGVariant(child.get(), value[static_cast<size_t>(i)]);
}
}
template<typename T>
- static typename std::enable_if<isVisitable<T>::value>::type
+ static typename std::enable_if<isUnion<T>::value>::type
+ fromGVariant(GVariant* object, T& value)
+ {
+ checkType(object, G_VARIANT_TYPE_VARIANT);
+ auto inner = makeUnique(g_variant_get_variant(object));
+
+ FromGVariantVisitor visitor(inner.get());
+ value.accept(visitor);
+ }
+
+ template<typename T>
+ static typename std::enable_if<isVisitable<T>::value && !isUnion<T>::value>::type
fromGVariant(GVariant* object, T& value)
{
- FromGVariantVisitor visitor(object, isUnion<T>::value);
+ FromGVariantVisitor visitor(object);
value.accept(visitor);
}