After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 778215 - Variant::get_maybe() for single-value types is missing (moved to VariantContainerBase)
Variant::get_maybe() for single-value types is missing (moved to VariantConta...
Status: RESOLVED INVALID
Product: glibmm
Classification: Bindings
Component: general
2.50.x
Other All
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2017-02-05 19:30 UTC by Daniel Boles
Modified: 2017-02-05 22:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Daniel Boles 2017-02-05 19:30:57 UTC
The changelog for 2.25.5 states:

> Glib:
> * Variant: Added get_maybe(), get_size(), get_data(), store(), and
>   get_n_children().

And yet these methods were _actually_ added to Glib::VariantContainerBase, not Glib::Variant[Base].


It seems that only the latter of those methods is actually for VariantContainerBase. All the others should have been added to VariantBase.

Am I wrong? These seem to be applicable to any Variant, not just container-typed ones. For instance, there seems to be no way to use 'maybe' Variants in glibmm, nor to do serialisation with get_size/data(), etc. (at least not without some horrible trek through loads of const_casts to the C methods)


If I'm right, this is another bug I'll be tagging as API and hoping we get a release of 2.50 that can add features. There's a bunch of these types of bug, which aren't really adding new API... they're fixing misnamed, or wrongly positioned, or etc attempts at adding API from the past. It would be a shame if the final form of 2.50 enforced that users had to wade into C (at best; some things might not even be possible) because of mistakes that were made years ago.
Comment 1 Daniel Boles 2017-02-05 19:40:55 UTC
Huh, get_(size|data) and store() are in the right place. Dunno why I thought they weren't. Sorry!

So it's just really get_maybe() that's the problem. That and get() were moved from VariantBase to VariantContainerBase in commit 2eff97b849a744ad07531f23969abf738edfd99a
albeit without any rationale for why maybe() was included in this. I'm not sure exactly what get() does, but maybe that wasn't the right idea either; I dunno.

Single-value types can be nullable too in GLib itself and should be in glibmm.
Comment 2 Daniel Boles 2017-02-05 21:01:19 UTC
OK, sorry. Going further into actually reading things, I found this in the GVariant documentation:

> Aside from the type information structures stored in read-only memory, there are
> two forms of type information. One is used for container types where there is a
> single element type: arrays and maybe types. The other is used for container
> types where there are multiple element types: tuples and dictionary entries.

Specifically:

> container types where there is a
> single element type: arrays and maybe types.

So, maybe this is totally OK, and I jumped the gun. That's not like me at all... :)
Comment 3 Daniel Boles 2017-02-05 22:07:02 UTC
OK. It works. Eventually! There seems to be a lot of fairly ugly syntax involved in this, but I'm sure the C version wouldn't be any better...

As an example, since I can't find any and this might save other frustrated Googlers hours of trial and error... here is the slimmest I could get my current use case. The goal is to restore windows' positions if they exist in the GSettings, otherwise do nothing. So, the GSettings are type "mi" for maybe-int, and will only ever be "nothing" on the first run on any given machine.

> /* Welcome, to THE house of evil code */
> using maybe_type = Glib::Variant<Glib::VariantBase>;
> // This is actually specialised to derive from VariantContainerBase,
> // and it inherits maybe-ability from the latter.
> 
> void settings_load_window(Glib::ustring const& key_suffix, Gtk::Window& window)
> {
> 	auto const settings_window = s_settings->get_child("window-" + key_suffix); // relocatable schema
> 	maybe_type maybe_x, maybe_y;
> 	settings_window->get_value("x", maybe_x);
> 	settings_window->get_value("y", maybe_y);
> 
> 	Glib::Variant<int> variant_x, variant_y;
> 	if ( maybe_x.get_maybe(variant_x) &&
> 	     maybe_y.get_maybe(variant_y)
> 	) {
> 		window.move( variant_x.get(), variant_y.get() );
> 	}
> }
> 
> void settings_save_window(Gtk::Window& window, Glib::ustring const& key_suffix)
> {
> 	int x, y;
> 	window.get_position(x, y);
> 	auto const maybe_x = maybe_type::create_maybe( Glib::VariantType{"i"}, Glib::Variant<int>::create(x) );
> 	auto const maybe_y = maybe_type::create_maybe( Glib::VariantType{"i"}, Glib::Variant<int>::create(y) );
> 
> 	auto const settings_window = s_settings->get_child("window-" + key_suffix);
> 	settings_window->set_value("x", maybe_x);
> 	settings_window->set_value("y", maybe_y);
> }