1 // Generated by gmmproc 2.64.2 -- DO NOT MODIFY!
2 #ifndef _GLIBMM_VARIANT_H
3 #define _GLIBMM_VARIANT_H
4
5
6 /* Copyright 2010 The glibmm Development Team
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22
23 #include <glibmmconfig.h>
24 #include <glibmm/varianttype.h>
25 #include <glibmm/variantiter.h>
26 #include <glibmm/variantdbusstring.h>
27 #include <glibmm/refptr.h>
28 #include <glibmm/ustring.h>
29 #include <glibmm/error.h>
30 #include <utility>
31 #include <vector>
32 #include <map>
33 #include <memory>
34 #include <tuple>
35 #include <stdexcept>
36 #include <typeinfo>
37 #include <cstddef>
38
39 namespace Glib
40 {
41 class Bytes;
42
43 /** @defgroup Variant Variant Data Types
44 *
45 * The Variant classes deal with strongly typed
46 * variant data. A Variant stores a value along with
47 * information about the type of that value. The range of possible
48 * values is determined by the type. The type system used is VariantType.
49 *
50 * See the VariantBase class and its derived types, such as VariantContainerBase,
51 * and the Variant<> template type.
52 *
53 * Variant instances always have a type and a value (which are given
54 * at construction time). The type and value of a Variant
55 * can never change other than by the Variant itself being
56 * destroyed. A Variant cannot contain a pointer.
57 *
58 * Variant is heavily optimised for dealing with data in serialised
59 * form. It works particularly well with data located in memory-mapped
60 * files. It can perform nearly all deserialisation operations in a
61 * small constant time, usually touching only a single memory page.
62 * Serialised Variant data can also be sent over the network.
63 *
64 * Variant is largely compatible with D-Bus. Almost all types of
65 * Variant instances can be sent over D-Bus. See VariantType for
66 * exceptions.
67 *
68 * There is a Python-inspired text language for describing Variant
69 * values. Variant includes a printer for this language and a parser
70 * with type inferencing.
71 */
72
73 //Note: We wrap this because it is thrown by GtkBuilder's functions.
74 // See https://bugzilla.gnome.org/show_bug.cgi?id=708206
75 // It would also be thrown by parse() if we wrap g_variant_parse().
76 // Now (2014-01-30) it's also thrown by Gio::Action::parse_detailed_name().
77 /** %Exception class for Variant parse errors.
78 */
79 class GLIBMM_API VariantParseError : public Glib::Error
80 {
81 public:
82 /** @var Code FAILED
83 * Generic error (unused).
84 *
85 * @var Code BASIC_TYPE_EXPECTED
86 * A non-basic VariantType was given where a basic type was expected.
87 *
88 * @var Code CANNOT_INFER_TYPE
89 * Cannot infer the VariantType.
90 *
91 * @var Code DEFINITE_TYPE_EXPECTED
92 * An indefinite VariantType was given where a definite type was expected.
93 *
94 * @var Code INPUT_NOT_AT_END
95 * Extra data after parsing finished.
96 *
97 * @var Code INVALID_CHARACTER
98 * Invalid character in number or unicode escape.
99 *
100 * @var Code INVALID_FORMAT_STRING
101 * Not a valid Variant format string.
102 *
103 * @var Code INVALID_OBJECT_PATH
104 * Not a valid object path.
105 *
106 * @var Code INVALID_SIGNATURE
107 * Not a valid type signature.
108 *
109 * @var Code INVALID_TYPE_STRING
110 * Not a valid Variant type string.
111 *
112 * @var Code NO_COMMON_TYPE
113 * Could not find a common type for array entries.
114 *
115 * @var Code NUMBER_OUT_OF_RANGE
116 * The numerical value is out of range of the given type.
117 *
118 * @var Code NUMBER_TOO_BIG
119 * The numerical value is out of range for any type.
120 *
121 * @var Code TYPE_ERROR
122 * Cannot parse as variant of the specified type.
123 *
124 * @var Code UNEXPECTED_TOKEN
125 * An unexpected token was encountered.
126 *
127 * @var Code UNKNOWN_KEYWORD
128 * An unknown keyword was encountered.
129 *
130 * @var Code UNTERMINATED_STRING_CONSTANT
131 * Unterminated string constant.
132 *
133 * @var Code VALUE_EXPECTED
134 * No value given.
135 *
136 * @var Code RECURSION
137 * Variant was too deeply nested; Variant is only guaranteed to handle nesting up to 64 levels (Since: 2.64).
138 *
139 * @enum Code
140 *
141 * %Error codes returned by parsing text-format GVariants.
142 */
143 enum Code
144 {
145 FAILED,
146 BASIC_TYPE_EXPECTED,
147 CANNOT_INFER_TYPE,
148 DEFINITE_TYPE_EXPECTED,
149 INPUT_NOT_AT_END,
150 INVALID_CHARACTER,
151 INVALID_FORMAT_STRING,
152 INVALID_OBJECT_PATH,
153 INVALID_SIGNATURE,
154 INVALID_TYPE_STRING,
155 NO_COMMON_TYPE,
156 NUMBER_OUT_OF_RANGE,
157 NUMBER_TOO_BIG,
158 TYPE_ERROR,
159 UNEXPECTED_TOKEN,
160 UNKNOWN_KEYWORD,
161 UNTERMINATED_STRING_CONSTANT,
162 VALUE_EXPECTED,
163 RECURSION
164 };
165
166 VariantParseError(Code error_code, const Glib::ustring& error_message);
167 explicit VariantParseError(GError* gobject);
168 Code code() const;
169
170 #ifndef DOXYGEN_SHOULD_SKIP_THIS
171 private:
172
173 static void throw_func(GError* gobject);
174
175 friend GLIBMM_API void wrap_init(); // uses throw_func()
176
177 #endif //DOXYGEN_SHOULD_SKIP_THIS
178 };
179
180
181 //TODO: Add this documentation from the API if we are confident of it for the C++ wrapper:
182 // #GVariant is completely threadsafe. A #GVariant instance can be
183 // concurrently accessed in any way from any number of threads without
184 // problems.
185 // Note that we don't copy GVariant's documentation about Memory Use because
186 // it seems easy to get out of sync and people can look at that C documentation if necessary.
187
188 /** This is the base class for all Variant types.
189 *
190 * If the actual type is known at compile-time then you should use a specific
191 * Variant<>, such as Variant<int>. Otherwise, you may use get_type(),
192 * is_of_type(), or cast_dynamic().
193 *
194 * @newin{2,28}
195 * @ingroup Variant
196 */
197 class GLIBMM_API VariantBase
198 {
199 public:
200 #ifndef DOXYGEN_SHOULD_SKIP_THIS
201 using CppObjectType = VariantBase;
202 using BaseObjectType = GVariant;
203 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
204
205 /** Constructs an invalid object.
206 * E.g. for output arguments to methods. There is not much you can do with
207 * the object before it has been assigned a valid value.
208 */
209 VariantBase();
210
211 // Use make_a_copy=true when getting it directly from a struct.
212 explicit VariantBase(GVariant* castitem, bool make_a_copy = false);
213
214 VariantBase(const VariantBase& src);
215 VariantBase& operator=(const VariantBase& src);
216
217 VariantBase(VariantBase&& other) noexcept;
218 VariantBase& operator=(VariantBase&& other) noexcept;
219
220 ~VariantBase() noexcept;
221
222 void swap(VariantBase& other) noexcept;
223
gobj()224 GVariant* gobj() { return gobject_; }
gobj()225 const GVariant* gobj() const { return gobject_; }
226
227 ///Provides access to the underlying C instance. The caller is responsible for freeing it. Use when directly setting fields in structs.
228 GVariant* gobj_copy() const;
229
230 protected:
231 GVariant* gobject_;
232
233 private:
234
235
236 public:
237
238 #ifndef GLIBMM_DISABLE_DEPRECATED
239
240 /** This typedef is just to make it more obvious that
241 * our operator const void* should be used like operator bool().
242 *
243 * @deprecated Use the explicit operator bool() instead.
244 */
245 using BoolExpr = const void*;
246
247 /** Test whether the Variant has an underlying instance.
248 *
249 * Mimics usage of pointers:
250 * @code
251 * if (variant)
252 * do_something();
253 * @endcode
254 *
255 * @deprecated Use the explicit operator bool() instead.
256 *
257 * @newin{2,36}
258 */
259 operator BoolExpr() const;
260 #endif // GLIBMM_DISABLE_DEPRECATED
261
262
263 /** Test whether the Variant has an underlying instance.
264 *
265 * @newin{2,50}
266 */
267 explicit operator bool() const;
268
269 /** Replace the underlying GVariant.
270 * This is for use by methods that take a VariantBase& as an output
271 * parameter.
272 *
273 * @param cobject The GVariant* obtained from a C function.
274 * @param take_a_reference Whether this method should take a reference, for
275 * instance if the C function has not given one.
276 */
277 void init(const GVariant* cobject, bool take_a_reference = false);
278
279 // It's necessary to take an extra reference of the 'const GVariantType*'
280 // returned by g_variant_get_type() because it doesn't do that already.
281
282
283 /** Determines the type of @a value.
284 *
285 * The return value is valid for the lifetime of @a value and must not
286 * be freed.
287 *
288 * @newin{2,24}
289 *
290 * @return A VariantType.
291 */
292 VariantType get_type() const;
293
294
295 /** Returns the type string of @a value. Unlike the result of calling
296 * g_variant_type_peek_string(), this string is nul-terminated. This
297 * string belongs to Variant and must not be freed.
298 *
299 * @newin{2,24}
300 *
301 * @return The type string for the type of @a value.
302 */
303 std::string get_type_string() const;
304
305 /** Checks whether @a value has a floating reference count.
306 *
307 * This function should only ever be used to assert that a given variant
308 * is or is not floating, or for debug purposes. To acquire a reference
309 * to a variant that might be floating, always use g_variant_ref_sink()
310 * or g_variant_take_ref().
311 *
312 * See g_variant_ref_sink() for more information about floating reference
313 * counts.
314 *
315 * @newin{2,26}
316 *
317 * @return Whether @a value is floating.
318 */
319 bool is_floating() const;
320
321 /** Checks if a value has a type matching the provided type.
322 *
323 * @newin{2,24}
324 *
325 * @param type A VariantType.
326 * @return <tt>true</tt> if the type of @a value matches @a type.
327 */
328 bool is_of_type(const VariantType& type) const;
329
330 /** Checks if @a value is a container.
331 *
332 * @newin{2,24}
333 *
334 * @return <tt>true</tt> if @a value is a container.
335 */
336 bool is_container() const;
337
338 /** Classifies @a value according to its top-level type.
339 *
340 * @newin{2,24}
341 *
342 * @return The VariantClass of @a value.
343 */
344 GVariantClass classify() const;
345
346
347 /** Determines the number of bytes that would be required to store @a value
348 * with g_variant_store().
349 *
350 * If @a value has a fixed-sized type then this function always returned
351 * that fixed size.
352 *
353 * In the case that @a value is already in serialised form or the size has
354 * already been calculated (ie: this function has been called before)
355 * then this function is O(1). Otherwise, the size is calculated, an
356 * operation which is approximately O(n) in the number of values
357 * involved.
358 *
359 * @newin{2,24}
360 *
361 * @return The serialised size of @a value.
362 */
363 gsize get_size() const;
364
365 #ifndef GLIBMM_DISABLE_DEPRECATED
366
367 /** Returns a pointer to the serialised form of a Variant instance.
368 * The returned data may not be in fully-normalised form if read from an
369 * untrusted source. The returned data must not be freed; it remains
370 * valid for as long as @a value exists.
371 *
372 * If @a value is a fixed-sized value that was deserialised from a
373 * corrupted serialised container then <tt>nullptr</tt> may be returned. In this
374 * case, the proper thing to do is typically to use the appropriate
375 * number of nul bytes in place of @a value. If @a value is not fixed-sized
376 * then <tt>nullptr</tt> is never returned.
377 *
378 * In the case that @a value is already in serialised form, this function
379 * is O(1). If the value is not already in serialised form,
380 * serialisation occurs implicitly and is approximately O(n) in the size
381 * of the result.
382 *
383 * To deserialise the data returned by this function, in addition to the
384 * serialised data, you must know the type of the Variant, and (if the
385 * machine might be different) the endianness of the machine that stored
386 * it. As a result, file formats or network messages that incorporate
387 * serialised Variants must include this information either
388 * implicitly (for instance "the file always contains a
389 * G_VARIANT_TYPE_VARIANT and it is always in little-endian order") or
390 * explicitly (by storing the type and/or endianness in addition to the
391 * serialised data).
392 *
393 * @newin{2,24}
394 *
395 * @deprecated Use the const version instead.
396 *
397 * @return The serialised form of @a value, or <tt>nullptr</tt>.
398 */
399 gconstpointer get_data();
400 #endif // GLIBMM_DISABLE_DEPRECATED
401
402
403 /** Returns a pointer to the serialised form of a Variant instance.
404 * The returned data may not be in fully-normalised form if read from an
405 * untrusted source. The returned data must not be freed; it remains
406 * valid for as long as @a value exists.
407 *
408 * If @a value is a fixed-sized value that was deserialised from a
409 * corrupted serialised container then <tt>nullptr</tt> may be returned. In this
410 * case, the proper thing to do is typically to use the appropriate
411 * number of nul bytes in place of @a value. If @a value is not fixed-sized
412 * then <tt>nullptr</tt> is never returned.
413 *
414 * In the case that @a value is already in serialised form, this function
415 * is O(1). If the value is not already in serialised form,
416 * serialisation occurs implicitly and is approximately O(n) in the size
417 * of the result.
418 *
419 * To deserialise the data returned by this function, in addition to the
420 * serialised data, you must know the type of the Variant, and (if the
421 * machine might be different) the endianness of the machine that stored
422 * it. As a result, file formats or network messages that incorporate
423 * serialised Variants must include this information either
424 * implicitly (for instance "the file always contains a
425 * G_VARIANT_TYPE_VARIANT and it is always in little-endian order") or
426 * explicitly (by storing the type and/or endianness in addition to the
427 * serialised data).
428 *
429 * @newin{2,46}
430 *
431 * @return The serialised form of @a value, or <tt>nullptr</tt>.
432 */
433 gconstpointer get_data() const;
434
435 /** Returns a pointer to the serialised form of a Variant instance.
436 * The semantics of this function are exactly the same as
437 * g_variant_get_data(), except that the returned Bytes holds
438 * a reference to the variant data.
439 *
440 * @newin{2,46}
441 *
442 * @return A new Bytes representing the variant data.
443 */
444 Glib::RefPtr<const Glib::Bytes> get_data_as_bytes() const;
445
446 /** Stores the serialised form of @a value at @a data. @a data should be
447 * large enough. See g_variant_get_size().
448 *
449 * The stored data is in machine native byte order but may not be in
450 * fully-normalised form if read from an untrusted source. See
451 * g_variant_get_normal_form() for a solution.
452 *
453 * As with g_variant_get_data(), to be able to deserialise the
454 * serialised variant successfully, its type and (if the destination
455 * machine might be different) its endianness must also be available.
456 *
457 * This function is approximately O(n) in the size of @a data.
458 *
459 * @newin{2,24}
460 *
461 * @param data The location to store the serialised data at.
462 */
463 void store(gpointer data) const;
464
465
466 /** Pretty-prints @a value in the format understood by g_variant_parse().
467 *
468 * The format is described [here][gvariant-text].
469 *
470 * If @a type_annotate is <tt>true</tt>, then type information is included in
471 * the output.
472 *
473 * @newin{2,24}
474 *
475 * @param type_annotate <tt>true</tt> if type information should be included in
476 * the output.
477 * @return A newly-allocated string holding the result.
478 */
479 Glib::ustring print(bool type_annotate = false) const;
480
481
482 /** Generates a hash value for a Variant instance.
483 *
484 * The output of this function is guaranteed to be the same for a given
485 * value only per-process. It may change between different processor
486 * architectures or even different versions of GLib. Do not use this
487 * function as a basis for building protocols or file formats.
488 *
489 * The type of @a value is #gconstpointer only to allow use of this
490 * function with HashTable. @a value must be a Variant.
491 *
492 * @newin{2,24}
493 *
494 * @return A hash value corresponding to @a value.
495 */
496 guint hash() const;
497
498
499 /** Checks if @a *this and @a other have the same type and value.
500 *
501 * @newin{2,24}
502 *
503 * @param other The Variant to compare with.
504 * @return <tt>true</tt> if @a *this and @a other are equal.
505 */
506 bool equal(const VariantBase& other) const;
507
508 /** Gets a VariantBase instance that has the same value as this variant and
509 * is trusted to be in normal form.
510 *
511 * If this variant is already trusted to be in normal form then a new
512 * reference to the variant is returned.
513 *
514 * If this variant is not already trusted, then it is scanned to check if it
515 * is in normal form. If it is found to be in normal form then it is marked
516 * as trusted and a new reference to it is returned.
517 *
518 * If this variant is found not to be in normal form then a new trusted
519 * VariantBase is created with the same value as this variant.
520 *
521 * It makes sense to call this function if you've received variant data from
522 * untrusted sources and you want to ensure your serialised output is
523 * definitely in normal form.
524 *
525 * @param result A location in which to store the trusted VariantBase.
526 * @newin{2,24}
527 */
528 void get_normal_form(VariantBase& result) const;
529
530
531 /** Checks if @a value is in normal form.
532 *
533 * The main reason to do this is to detect if a given chunk of
534 * serialised data is in normal form: load the data into a Variant
535 * using g_variant_new_from_data() and then use this function to
536 * check.
537 *
538 * If @a value is found to be in normal form then it will be marked as
539 * being trusted. If the value was already marked as being trusted then
540 * this function will immediately return <tt>true</tt>.
541 *
542 * There may be implementation specific restrictions on deeply nested values.
543 * GVariant is guaranteed to handle nesting up to at least 64 levels.
544 *
545 * @newin{2,24}
546 *
547 * @return <tt>true</tt> if @a value is in normal form.
548 */
549 bool is_normal_form() const;
550
551 /** Performs a byteswapping operation on the contents of this variant. The
552 * result is that all multi-byte numeric data contained in the variant is
553 * byteswapped. That includes 16, 32, and 64bit signed and unsigned integers
554 * as well as file handles and double precision floating point values.
555 *
556 * This function is an identity mapping on any value that does not contain
557 * multi-byte numeric data. That include strings, booleans, bytes and
558 * containers containing only these things (recursively).
559 *
560 * The returned value is always in normal form and is marked as trusted.
561 *
562 * @param result A location in which to store the byteswapped form of this
563 * variant.
564 * @newin{2,24}
565 */
566 void byteswap(VariantBase& result) const;
567
568
569 /** Checks if calling g_variant_get() with @a format_string on @a value would
570 * be valid from a type-compatibility standpoint. @a format_string is
571 * assumed to be a valid format string (from a syntactic standpoint).
572 *
573 * If @a copy_only is <tt>true</tt> then this function additionally checks that it
574 * would be safe to call g_variant_unref() on @a value immediately after
575 * the call to g_variant_get() without invalidating the result. This is
576 * only possible if deep copies are made (ie: there are no pointers to
577 * the data inside of the soon-to-be-freed Variant instance). If this
578 * check fails then a g_critical() is printed and <tt>false</tt> is returned.
579 *
580 * This function is meant to be used by functions that wish to provide
581 * varargs accessors to Variant values of uncertain values (eg:
582 * g_variant_lookup() or Glib::menu_model_get_item_attribute()).
583 *
584 * @newin{2,34}
585 *
586 * @param format_string A valid Variant format string.
587 * @param copy_only <tt>true</tt> to ensure the format string makes deep copies.
588 * @return <tt>true</tt> if @a format_string is safe to use.
589 */
590 bool check_format_string(const std::string& format_string, bool copy_only = false) const;
591
592 //Ignore private API from gvariant-core.h:
593
594
595 /** Cast to a specific variant type.
596 * For instance:
597 * @code
598 * Variant<std::string> derived = VariantBase::cast_dynamic< Variant<std::string> >(base);
599 * @endcode
600 *
601 * @param v The variant to cast to a specific type.
602 * @result The variant as a specific type.
603 * @throws std::bad_cast if the Variant was not of the expected type.
604 */
605 template<class V_CastTo>
606 static V_CastTo cast_dynamic(const VariantBase& v);
607
608
609 protected:
610 #ifndef DOXYGEN_SHOULD_SKIP_THIS
611 /** Used by cast_dynamic().
612 * In addition to an exact match, the following casts are possible:
613 * - VARIANT_TYPE_OBJECT_PATH and VARIANT_TYPE_SIGNATURE can be cast to
614 * VARIANT_TYPE_STRING (Glib::ustring).
615 * - VARIANT_TYPE_STRING, VARIANT_TYPE_OBJECT_PATH and VARIANT_TYPE_SIGNATURE
616 * can be cast to VARIANT_TYPE_BYTESTRING (std::string).
617 * - VARIANT_TYPE_HANDLE can be cast to VARIANT_TYPE_INT32.
618 *
619 * These casts are possible also when they are parts of a more complicated type.
620 * E.g. in Variant<std::map<Glib::ustring, std::vector<std::string> > > the map's keys
621 * can be VARIANT_TYPE_OBJECT_PATH and the vector's elements can be VARIANT_TYPE_SIGNATURE.
622 * @newin{2,46}
623 */
624 bool is_castable_to(const VariantType& supertype) const;
625 #endif //DOXYGEN_SHOULD_SKIP_THIS
626
627 private:
628 /** Relational operators are deleted to prevent invalid conversion
629 * to const void*.
630 */
631 bool operator<(const VariantBase& src) const;
632
633 /// See operator<().
634 bool operator<=(const VariantBase& src) const;
635
636 /// See operator<().
637 bool operator>(const VariantBase& src) const;
638
639 /// See operator<().
640 bool operator>=(const VariantBase& src) const;
641
642 /// See operator<().
643 bool operator==(const VariantBase& src) const;
644
645 /// See operator<().
646 bool operator!=(const VariantBase& src) const;
647
648
649 };
650
651 template<class V_CastTo>
cast_dynamic(const VariantBase & v)652 V_CastTo VariantBase::cast_dynamic(const VariantBase& v)
653 {
654 if(!(v.gobj()))
655 {
656 return V_CastTo();
657 }
658 if(v.is_castable_to(V_CastTo::variant_type()))
659 {
660 return V_CastTo(const_cast<GVariant*>(v.gobj()), true);
661 }
662 else
663 {
664 throw std::bad_cast();
665 }
666 }
667
668 /** Base class from which string variant classes derive.
669 * @newin{2,28}
670 * @ingroup Variant
671 */
672 class GLIBMM_API VariantStringBase : public VariantBase
673 {
674 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
675 public:
676 #ifndef DOXYGEN_SHOULD_SKIP_THIS
677 using CppObjectType = VariantStringBase;
678 using BaseObjectType = GVariant;
679 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
680
681 private:
682
683
684 public:
685 using CType = GVariant*;
686 using CppType = VariantStringBase;
687
688 /// Default constructor.
689 VariantStringBase();
690
691 /** GVariant constructor.
692 * @param castitem The GVariant to wrap.
693 * @param take_a_reference Whether to take an extra reference of the
694 * GVariant or not (not taking one could destroy the GVariant with the
695 * wrapper).
696 */
697 explicit VariantStringBase(GVariant* castitem, bool take_a_reference = false);
698
699 /** Creates a D-Bus object path variant with the contents of @a object_path.
700 * @a object_path must be a valid D-Bus object path. Use is_object_path() if unsure.
701 *
702 * @param[out] output A location in which to store the new object path variant
703 * instance.
704 * @param object_path An object path string.
705 * @newin{2,28}
706 */
707 static void create_object_path(VariantStringBase& output,
708 const std::string& object_path);
709
710
711 /** Determines if a given string is a valid D-Bus object path. You
712 * should ensure that a string is a valid D-Bus object path before
713 * passing it to g_variant_new_object_path().
714 *
715 * A valid object path starts with `/` followed by zero or more
716 * sequences of characters separated by `/` characters. Each sequence
717 * must contain only the characters `[A-Z][a-z][0-9]_`. No sequence
718 * (including the one following the final `/` character) may be empty.
719 *
720 * @newin{2,24}
721 *
722 * @param string A normal C nul-terminated string.
723 * @return <tt>true</tt> if @a string is a D-Bus object path.
724 */
725 static bool is_object_path(const std::string& string);
726
727 /** Creates a D-Bus type signature variant with the contents of @a signature.
728 * @a signature must be a valid D-Bus type signature. Use is_signature() if unsure.
729 *
730 * @param[out] output A location in which to store the new signature variant
731 * instance.
732 * @param signature A signature string.
733 * @newin{2,28}
734 */
735 static void create_signature(VariantStringBase& output,
736 const std::string& signature);
737
738
739 /** Determines if a given string is a valid D-Bus type signature. You
740 * should ensure that a string is a valid D-Bus type signature before
741 * passing it to g_variant_new_signature().
742 *
743 * D-Bus type signatures consist of zero or more definite VariantType
744 * strings in sequence.
745 *
746 * @newin{2,24}
747 *
748 * @param string A normal C nul-terminated string.
749 * @return <tt>true</tt> if @a string is a D-Bus type signature.
750 */
751 static bool is_signature(const std::string& string);
752
753
754 };
755
756 /** The base class for multiple-item Variants, such as Variants containing
757 * tuples or arrays, and also for maybe-typed (that is, nullable) Variant types.
758 *
759 * @newin{2,28}
760 * @ingroup Variant
761 */
762 class GLIBMM_API VariantContainerBase : public VariantBase
763 {
764 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
765 public:
766 #ifndef DOXYGEN_SHOULD_SKIP_THIS
767 using CppObjectType = VariantContainerBase;
768 using BaseObjectType = GVariant;
769 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
770
771 private:
772
773
774 public:
775 using CType = GVariant*;
776 using CppType = VariantContainerBase;
777
778 /// Default constructor.
779 VariantContainerBase();
780
781 /** GVariant constructor.
782 * @param castitem The GVariant to wrap.
783 * @param take_a_reference Whether to take an extra reference of the
784 * GVariant or not (not taking one could destroy the GVariant with the
785 * wrapper).
786 */
787 explicit VariantContainerBase(GVariant* castitem, bool take_a_reference = false);
788
789 /** Create a tuple variant from a vector of its variant children.
790 * @param children The vector containing the children of the container.
791 * @return The newly created tuple variant (as a VariantContainerBase).
792 */
793 static VariantContainerBase create_tuple(const std::vector<VariantBase>& children);
794
795 /** Create a tuple variant with a single variant child.
796 * @param child The child variant.
797 * @return The newly created tuple variant (as a VariantContainerBase).
798 */
799 static VariantContainerBase create_tuple(const VariantBase& child);
800
801
802 /** Depending on if @a child is <tt>nullptr</tt>, either wraps @a child inside of a
803 * maybe container or creates a Nothing instance for the given @a type.
804 *
805 * At least one of @a child_type and @a child must be non-<tt>nullptr</tt>.
806 * If @a child_type is non-<tt>nullptr</tt> then it must be a definite type.
807 * If they are both non-<tt>nullptr</tt> then @a child_type must be the type
808 * of @a child.
809 *
810 * If @a child is a floating reference (see g_variant_ref_sink()), the new
811 * instance takes ownership of @a child.
812 *
813 * @newin{2,24}
814 *
815 * @param child_type The VariantType of the child, or <tt>nullptr</tt>.
816 * @param child The child value, or <tt>nullptr</tt>.
817 * @return A floating reference to a new Variant maybe instance.
818 */
819
820 static VariantContainerBase create_maybe(const VariantType& child_type,
821 const VariantBase& child = VariantBase());
822
823
824 /** Determines the number of children in a container Variant instance.
825 * This includes variants, maybes, arrays, tuples and dictionary
826 * entries. It is an error to call this function on any other type of
827 * Variant.
828 *
829 * For variants, the return value is always 1. For values with maybe
830 * types, it is always zero or one. For arrays, it is the length of the
831 * array. For tuples it is the number of tuple items (which depends
832 * only on the type). For dictionary entries, it is always 2
833 *
834 * This function is O(1).
835 *
836 * @newin{2,24}
837 *
838 * @return The number of children in the container.
839 */
840 gsize get_n_children() const;
841
842 /** Reads a child item out of this instance. This method is valid for
843 * variants, maybes, arrays, tuples and dictionary entries.
844 *
845 * It is an error if @a index is greater than the number of child items in
846 * the container. See get_n_children().
847 *
848 * This function is O(1).
849 *
850 * @param index The index of the child to fetch.
851 * @param child A location in which to store the child at the specified
852 * index.
853 * @throw std::out_of_range
854 * @newin{2,28}
855 */
856 void get_child(VariantBase& child, gsize index = 0) const;
857
858
859 /** Reads a child item out of a container Variant instance. This
860 * includes variants, maybes, arrays, tuples and dictionary
861 * entries. It is an error to call this function on any other type of
862 * Variant.
863 *
864 * It is an error if @a index is greater than the number of child items
865 * in the container. See g_variant_n_children().
866 *
867 * The returned value is never floating. You should free it with
868 * g_variant_unref() when you're done with it.
869 *
870 * There may be implementation specific restrictions on deeply nested values,
871 * which would result in the unit tuple being returned as the child value,
872 * instead of further nested children. Variant is guaranteed to handle
873 * nesting up to at least 64 levels.
874 *
875 * This function is O(1).
876 *
877 * @newin{2,24}
878 *
879 * @param index The index of the child to fetch.
880 * @return The child at the specified index.
881 */
882 VariantBase get_child(gsize index = 0);
883
884 /* TODO?:
885 /// A get() method to return the contents of the variant in the container.
886 template <class DataType>
887 DataType get_child(gsize index = 0) const;
888 */
889
890 /** If this is a maybe-typed instance, try to extract its value. If there is
891 * no value (the value is <tt>nothing</tt>), return <tt>false</tt>. Otherwise,
892 * the value is copied to the supplied Variant and <tt>true</tt> is returned.
893 *
894 * @param maybe A place in which to return the value, if it isn’t
895 * <tt>nothing</tt>.
896 * @newin{2,28}
897 */
898 bool get_maybe(VariantBase& maybe) const;
899
900
901 protected:
902 #ifndef DOXYGEN_SHOULD_SKIP_THIS
903 /** Used by get_iter() in the subclasses.
904 * @newin{2,46}
905 */
906 VariantIter get_iter(const VariantType& container_variant_type) const;
907 #endif //DOXYGEN_SHOULD_SKIP_THIS
908
909
910 };
911
912 template<>
913 GLIBMM_API VariantContainerBase VariantBase::cast_dynamic<VariantContainerBase>(const VariantBase& v);
914
915 /** Template class used for the specialization of the Variant<> classes.
916 * @newin{2,28}
917 * @ingroup Variant
918 */
919 template<class T>
920 class Variant : public VariantBase
921 {
922 public:
923 using CppType = T;
924 };
925
926 /****************** Specializations ***********************************/
927
928 /** Specialization of Variant containing a VariantBase.
929 * Perhaps the main use of this is as a maybe-typed (i.e. nullable) Variant, as
930 * it inherits the methods create_maybe() and get_maybe() from
931 * VariantContainerBase, plus get_n_children() to allow checking whether there
932 * is a contained value, i.e. the inner Variant is not <tt>nothing</tt>.
933 *
934 * @newin{2,28}
935 * @ingroup Variant
936 */
937 template<>
938 class GLIBMM_API Variant<VariantBase> : public VariantContainerBase
939 {
940 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
941 public:
942 #ifndef DOXYGEN_SHOULD_SKIP_THIS
943 using CppObjectType = Variant<VariantBase>;
944 using BaseObjectType = GVariant;
945 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
946
947 private:
948
949
950 public:
951 using CType = GVariant*;
952 using CppType = VariantBase;
953 using CppContainerType = Variant<VariantBase>;
954
955 /// Default constructor.
956 Variant<VariantBase>();
957
958 /** GVariant constructor.
959 * @param castitem The GVariant to wrap.
960 * @param take_a_reference Whether to take an extra reference of the
961 * GVariant or not (not taking one could destroy the GVariant with the
962 * wrapper).
963 */
964 explicit Variant<VariantBase>(GVariant* castitem, bool take_a_reference = false);
965
966 /** Gets the VariantType.
967 * @return The VariantType.
968 * @newin{2,28}
969 */
970 static const VariantType& variant_type() G_GNUC_CONST;
971
972 //This must have a create() method because otherwise it would be a copy
973 //constructor.
974 /** Creates a new Variant<VariantBase>.
975 * @param data The value of the new Variant.
976 * @return The new Variant.
977 * @newin{2,28}
978 */
979 static Variant<VariantBase> create(const VariantBase& data);
980
981
982 //TODO: Documentation
983 void get(VariantBase& variant) const;
984
985 //TODO: Deprecate this in favour of get(VariantBase&)?
986
987 /** Unboxes @a value. The result is the Variant instance that was
988 * contained in @a value.
989 *
990 * @newin{2,24}
991 *
992 * @return The item contained in the variant.
993 */
994 VariantBase get() const;
995
996
997 };
998
999 /** Specialization of Variant containing a Variant<T>.
1000 * Perhaps the main use of this is as a maybe-typed (i.e. nullable) Variant, as
1001 * it inherits the methods create_maybe() and get_maybe() from
1002 * VariantContainerBase, plus get_n_children() to allow checking whether there
1003 * is a contained value, i.e. the inner Variant is not <tt>nothing</tt>.
1004 *
1005 * @newin{2,36}
1006 * @ingroup Variant
1007 */
1008 template<class T>
1009 class Variant< Variant<T> > : public VariantContainerBase
1010 {
1011 public:
1012 using CType = GVariant*;
1013 using CppType = Variant<T>;
1014 using CppContainerType = Variant<CppType>;
1015
1016 /// Default constructor.
1017 Variant< Variant<T> >();
1018
1019 /** GVariant constructor.
1020 * @param castitem The GVariant to wrap.
1021 * @param take_a_reference Whether to take an extra reference of the
1022 * GVariant or not (not taking one could destroy the GVariant with the
1023 * wrapper).
1024 * @newin{2,36}
1025 */
1026 explicit Variant< Variant<T> >(GVariant* castitem, bool take_a_reference = false);
1027
1028 /** Gets the VariantType.
1029 * @return The VariantType.
1030 * @newin{2,36}
1031 */
1032 static const VariantType& variant_type() G_GNUC_CONST;
1033
1034 /** Creates a new Variant< Variant<T> >.
1035 * @param data The value of the new Variant.
1036 * @return The new Variant.
1037 * @newin{2,36}
1038 */
1039 static Variant< Variant<T> > create(const Variant<T>& data);
1040
1041 /** Gets the contents of the Variant.
1042 * @return The contents of the Variant.
1043 * @newin{2,36}
1044 */
1045 Variant<T> get() const;
1046 };
1047
1048 /** Specialization of Variant containing a Glib::ustring, for variants of type
1049 * string, object path, or signature.
1050 * @newin{2,28}
1051 * @ingroup Variant
1052 */
1053 template<>
1054 class GLIBMM_API Variant<Glib::ustring> : public VariantStringBase
1055 {
1056 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
1057 public:
1058 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1059 using CppObjectType = Variant<Glib::ustring>;
1060 using BaseObjectType = GVariant;
1061 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1062
1063 private:
1064
1065 public:
1066 using CType = char*;
1067 using CppType = Glib::ustring;
1068
1069 /// Default constructor.
1070 Variant<Glib::ustring>();
1071
1072 /** GVariant constructor.
1073 * @param castitem The GVariant to wrap.
1074 * @param take_a_reference Whether to take an extra reference of the
1075 * GVariant or not (not taking one could destroy the GVariant with the
1076 * wrapper).
1077 */
1078 explicit Variant<Glib::ustring>(GVariant* castitem, bool take_a_reference = false);
1079
1080 /** Gets the VariantType.
1081 * @return The VariantType.
1082 * @newin{2,28}
1083 */
1084 static const VariantType& variant_type() G_GNUC_CONST;
1085
1086 /** Creates a new Variant<Glib::ustring>.
1087 * @param data The value of the new Variant.
1088 * @return The new Variant.
1089 * @newin{2,28}
1090 */
1091 static Variant<Glib::ustring> create(const Glib::ustring& data);
1092
1093 //We can't use WRAP_METHOD() here because g_variant_get_string() takes an extra length parameter.
1094 /** Gets the contents of the Variant.
1095 * @return The contents of the Variant.
1096 * @newin{2,28}
1097 */
1098 Glib::ustring get() const;
1099
1100
1101 };
1102
1103 //TODO: When we can break ABI, remove this template specialization.
1104 template<>
1105 GLIBMM_API Variant<Glib::ustring> VariantBase::cast_dynamic< Variant<Glib::ustring> >(const VariantBase& v);
1106
1107 /** Specialization of Variant containing a Glib::DBusObjectPathString,
1108 * for variants of type object path.
1109 * @newin{2,54}
1110 * @ingroup Variant
1111 */
1112 template<>
1113 class GLIBMM_API Variant<Glib::DBusObjectPathString> : public VariantStringBase
1114 {
1115 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
1116 public:
1117 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1118 using CppObjectType = Variant<Glib::DBusObjectPathString>;
1119 using BaseObjectType = GVariant;
1120 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1121
1122 private:
1123
1124 public:
1125 using CType = char*;
1126 using CppType = Glib::DBusObjectPathString;
1127
1128 /// Default constructor.
1129 Variant();
1130
1131 /** GVariant constructor.
1132 * @param castitem The GVariant to wrap.
1133 * @param take_a_reference Whether to take an extra reference of the
1134 * GVariant or not (not taking one could destroy the GVariant with the
1135 * wrapper).
1136 */
1137 explicit Variant(GVariant* castitem, bool take_a_reference = false);
1138
1139 /** Gets the VariantType.
1140 * @return The VariantType.
1141 * @newin{2,54}
1142 */
1143 static const VariantType& variant_type() G_GNUC_CONST;
1144
1145 /** Creates a new Variant<Glib::DBusObjectPathString>.
1146 * @param data The value of the new Variant.
1147 * @return The new Variant.
1148 * @newin{2,54}
1149 */
1150 static Variant<CppType> create(const CppType& data);
1151
1152 //We can't use WRAP_METHOD() here because g_variant_get_string() takes an extra length parameter.
1153 /** Gets the contents of the Variant.
1154 * @return The contents of the Variant.
1155 * @newin{2,54}
1156 */
1157 CppType get() const;
1158
1159
1160 };
1161
1162 /** Specialization of Variant containing a Glib::DBusSignatureString,
1163 * for variants of type signature.
1164 * @newin{2,54}
1165 * @ingroup Variant
1166 */
1167 template<>
1168 class GLIBMM_API Variant<Glib::DBusSignatureString> : public VariantStringBase
1169 {
1170 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
1171 public:
1172 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1173 using CppObjectType = Variant<Glib::DBusSignatureString>;
1174 using BaseObjectType = GVariant;
1175 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1176
1177 private:
1178
1179 public:
1180 using CType = char*;
1181 using CppType = Glib::DBusSignatureString;
1182
1183 /// Default constructor.
1184 Variant();
1185
1186 /** GVariant constructor.
1187 * @param castitem The GVariant to wrap.
1188 * @param take_a_reference Whether to take an extra reference of the
1189 * GVariant or not (not taking one could destroy the GVariant with the
1190 * wrapper).
1191 */
1192 explicit Variant(GVariant* castitem, bool take_a_reference = false);
1193
1194 /** Gets the VariantType.
1195 * @return The VariantType.
1196 * @newin{2,54}
1197 */
1198 static const VariantType& variant_type() G_GNUC_CONST;
1199
1200 /** Creates a new Variant<Glib::DBusSignatureString>.
1201 * @param data The value of the new Variant.
1202 * @return The new Variant.
1203 * @newin{2,54}
1204 */
1205 static Variant<CppType> create(const CppType& data);
1206
1207 //We can't use WRAP_METHOD() here because g_variant_get_string() takes an extra length parameter.
1208 /** Gets the contents of the Variant.
1209 * @return The contents of the Variant.
1210 * @newin{2,54}
1211 */
1212 CppType get() const;
1213
1214
1215 };
1216
1217 /** Specialization of Variant containing a std::string, for variants of type
1218 * bytestring, string, object path, or signature.
1219 * See also Variant<Glib::ustring> for UTF-8 strings.
1220 * @newin{2,28}
1221 * @ingroup Variant
1222 */
1223 template<>
1224 class GLIBMM_API Variant<std::string> : public VariantStringBase
1225 {
1226 // Trick gmmproc into thinking this is derived from GVariant to wrap some methods.
1227 public:
1228 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1229 using CppObjectType = Variant<std::string>;
1230 using BaseObjectType = GVariant;
1231 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1232
1233 private:
1234
1235 public:
1236 using CType = char* ;
1237 using CppType = std::string;
1238
1239 /// Default constructor.
1240 Variant<std::string>();
1241
1242 /** GVariant constructor.
1243 * @param castitem The GVariant to wrap.
1244 * @param take_a_reference Whether to take an extra reference of the
1245 * GVariant or not (not taking one could destroy the GVariant with the
1246 * wrapper).
1247 */
1248 explicit Variant<std::string>(GVariant* castitem, bool take_a_reference = false);
1249
1250 /** Gets the VariantType.
1251 * @return The VariantType.
1252 * @newin{2,28}
1253 */
1254 static const VariantType& variant_type() G_GNUC_CONST;
1255
1256 /** Creates a new Variant<std::string>.
1257 * @param data The value of the new Variant.
1258 * @return The new Variant.
1259 * @newin{2,28}
1260 */
1261 static Variant<std::string> create(const std::string& data);
1262
1263 //TODO: Documentation.
1264 std::string get() const;
1265
1266
1267 };
1268
1269 //TODO: When we can break ABI, remove this template specialization.
1270 template<>
1271 GLIBMM_API Variant<std::string> VariantBase::cast_dynamic< Variant<std::string> >(const VariantBase& v);
1272
1273 /** Specialization of Variant containing a dictionary entry. See also
1274 * Variant< std::map<K, V> >.
1275 * @newin{2,28}
1276 * @ingroup Variant
1277 */
1278 template<class K, class V>
1279 class Variant< std::pair<K, V> > : public VariantContainerBase
1280 {
1281 public:
1282 using CppType = std::pair<K, V>;
1283 using CppContainerType = Variant<CppType>;
1284
1285 /// Default constructor.
1286 Variant< std::pair<K, V> >()
VariantContainerBase()1287 : VariantContainerBase()
1288 {}
1289
1290 /** GVariant constructor.
1291 * @param castitem The GVariant to wrap.
1292 * @param take_a_reference Whether to take an extra reference of the
1293 * GVariant or not (not taking one could destroy the GVariant with the
1294 * wrapper).
1295 */
1296 explicit Variant< std::pair<K, V> >(GVariant* castitem,
1297 bool take_a_reference = false)
VariantContainerBase(castitem,take_a_reference)1298 : VariantContainerBase(castitem, take_a_reference)
1299 {}
1300
1301 /** Gets the VariantType.
1302 * @return The VariantType.
1303 * @newin{2,28}
1304 */
1305 static const VariantType& variant_type() G_GNUC_CONST;
1306
1307 /** Creates a new Variant< std::pair<K, V> >.
1308 * @param data The value of the new Variant.
1309 * @return The new Variant.
1310 * @newin{2,28}
1311 */
1312 static Variant< std::pair<K, V> > create(const std::pair<K, V>& data);
1313
1314
1315 /** Gets the contents of the Variant.
1316 * @return The contents of the Variant.
1317 * @throw std::out_of_range
1318 * @newin{2,28}
1319 */
1320 std::pair<K, V> get() const;
1321 };
1322
1323 /** Specialization of Variant containing an array of items.
1324 * @newin{2,28}
1325 * @ingroup Variant
1326 */
1327 template<class T>
1328 class Variant< std::vector<T> > : public VariantContainerBase
1329 {
1330 public:
1331 using CppType = T ;
1332 using CppContainerType = std::vector<T>;
1333
1334 /// Default constructor.
1335 Variant< std::vector<T> >()
VariantContainerBase()1336 : VariantContainerBase()
1337 {}
1338
1339 /** GVariant constructor.
1340 * @param castitem The GVariant to wrap.
1341 * @param take_a_reference Whether to take an extra reference of the
1342 * GVariant or not (not taking one could destroy the GVariant with the
1343 * wrapper).
1344 */
1345 explicit Variant< std::vector<T> >(GVariant* castitem,
1346 bool take_a_reference = false)
VariantContainerBase(castitem,take_a_reference)1347 : VariantContainerBase(castitem, take_a_reference)
1348 {}
1349
1350 /** Gets the VariantType.
1351 * @return The VariantType.
1352 * @newin{2,28}
1353 */
1354 static const VariantType& variant_type() G_GNUC_CONST;
1355
1356 /** Creates a new Variant from an array of numeric types.
1357 * @param data The array to use for creation.
1358 * @return The new Variant.
1359 * @newin{2,28}
1360 */
1361 static Variant< std::vector<T> > create(const std::vector<T>& data);
1362
1363
1364 /** Gets a specific element of the array. It is an error if @a index is
1365 * greater than the number of child items in the container. See
1366 * VariantContainerBase::get_n_children().
1367 *
1368 * This function is O(1).
1369 *
1370 * @param index The index of the element.
1371 * @return The element at index @a index.
1372 * @throw std::out_of_range
1373 * @newin{2,28}
1374 */
1375 T get_child(gsize index) const;
1376
1377 /** Gets the vector of the Variant.
1378 * @return The vector.
1379 * @newin{2,28}
1380 */
1381 std::vector<T> get() const;
1382
1383
1384 /** Gets a VariantIter of the Variant.
1385 * @return the VariantIter.
1386 * @newin{2,28}
1387 */
1388 VariantIter get_iter() const;
1389 };
1390
1391 /** Specialization of Variant containing an array of UTF-8 capable
1392 * strings.
1393 * @newin{2,28}
1394 * @ingroup Variant
1395 */
1396 template<>
1397 class GLIBMM_API Variant< std::vector<Glib::ustring> > : public VariantContainerBase
1398 {
1399 public:
1400 using CppType = Glib::ustring ;
1401 using CppContainerType = std::vector<Glib::ustring>;
1402
1403 /// Default constructor.
1404 Variant< std::vector<Glib::ustring> >();
1405
1406 /** GVariant constructor.
1407 * @param castitem The GVariant to wrap.
1408 * @param take_a_reference Whether to take an extra reference of the
1409 * GVariant or not (not taking one could destroy the GVariant with the
1410 * wrapper).
1411 */
1412 explicit Variant< std::vector<Glib::ustring> >(GVariant* castitem, bool take_a_reference = false);
1413
1414 /** Gets the VariantType.
1415 * @return The VariantType.
1416 * @newin{2,28}
1417 */
1418 static const VariantType& variant_type() G_GNUC_CONST;
1419
1420 /** Creates a new Variant from an array of strings.
1421 * @param data The array to use for creation.
1422 * @return The new Variant.
1423 * @newin{2,28}
1424 */
1425 static Variant< std::vector<Glib::ustring> >
1426 create(const std::vector<Glib::ustring>& data);
1427
1428 /** Gets a specific element of the string array. It is an error if @a index
1429 * is greater than the number of child items in the container. See
1430 * VariantContainerBase::get_n_children().
1431 *
1432 * This function is O(1).
1433 *
1434 * @param index The index of the element.
1435 * @return The element at index @a index.
1436 * @throw std::out_of_range
1437 * @newin{2,28}
1438 */
1439 Glib::ustring get_child(gsize index) const;
1440
1441 /** Gets the string vector of the Variant.
1442 * @return The vector.
1443 * @newin{2,28}
1444 */
1445 std::vector<Glib::ustring> get() const;
1446
1447
1448 /** Gets a VariantIter of the Variant.
1449 * @return the VariantIter.
1450 * @newin{2,28}
1451 */
1452 VariantIter get_iter() const;
1453 };
1454
1455 /** Specialization of Variant containing an array of D-Bus object paths.
1456 *
1457 * @newin{2,54}
1458 * @ingroup Variant
1459 */
1460 template<>
1461 class GLIBMM_API Variant<std::vector<Glib::DBusObjectPathString>> : public VariantContainerBase
1462 {
1463 public:
1464 using CppType = Glib::DBusObjectPathString;
1465 using CppContainerType = std::vector<Glib::DBusObjectPathString>;
1466
1467 /// Default constructor.
1468 Variant();
1469
1470 /** GVariant constructor.
1471 * @param castitem The GVariant to wrap.
1472 * @param take_a_reference Whether to take an extra reference of the
1473 * GVariant or not (not taking one could destroy the GVariant with the
1474 * wrapper).
1475 */
1476 explicit Variant(GVariant* castitem, bool take_a_reference = false);
1477
1478 /** Gets the VariantType.
1479 * @return The VariantType.
1480 * @newin{2,54}
1481 */
1482 static const VariantType& variant_type() G_GNUC_CONST;
1483
1484 /** Creates a new Variant from an array of strings.
1485 * @param data The array to use for creation.
1486 * @return The new Variant.
1487 * @newin{2,54}
1488 */
1489 static Variant<CppContainerType> create(const CppContainerType& data);
1490
1491 /** Gets a specific element of the string array. It is an error if @a index
1492 * is greater than the number of child items in the container. See
1493 * VariantContainerBase::get_n_children().
1494 *
1495 * This function is O(1).
1496 *
1497 * @param index The index of the element.
1498 * @return The element at index @a index.
1499 * @throw std::out_of_range
1500 * @newin{2,54}
1501 */
1502 CppType get_child(gsize index) const;
1503
1504 /** Gets the string vector of the Variant.
1505 * @return The vector.
1506 * @newin{2,54}
1507 */
1508 CppContainerType get() const;
1509
1510 /** Gets a VariantIter of the Variant.
1511 * @return the VariantIter.
1512 * @newin{2,54}
1513 */
1514 VariantIter get_iter() const;
1515 };
1516
1517 /** Specialization of Variant containing an array of non-UTF-8 strings
1518 * (byte string arrays).
1519 * @newin{2,28}
1520 * @ingroup Variant
1521 */
1522 template<>
1523 class GLIBMM_API Variant< std::vector<std::string> > : public VariantContainerBase
1524 {
1525 public:
1526 using CppType = std::string ;
1527 using CppContainerType = std::vector<std::string>;
1528
1529 /// Default constructor.
1530 Variant< std::vector<std::string> >();
1531
1532 /** GVariant constructor.
1533 * @param castitem The GVariant to wrap.
1534 * @param take_a_reference Whether to take an extra reference of the
1535 * GVariant or not (not taking one could destroy the GVariant with the
1536 * wrapper).
1537 */
1538 explicit Variant< std::vector<std::string> >(GVariant* castitem, bool take_a_reference = false);
1539
1540 /** Gets the VariantType.
1541 * @return The VariantType.
1542 * @newin{2,28}
1543 */
1544 static const VariantType& variant_type() G_GNUC_CONST;
1545
1546 /** Creates a new Variant from an array of strings.
1547 * @param data The array to use for creation.
1548 * @return The new Variant.
1549 * @newin{2,28}
1550 */
1551 static Variant< std::vector<std::string> >
1552 create(const std::vector<std::string>& data);
1553
1554 /** Creates a new Variant from an array of D-Bus object paths.
1555 * @param paths The array to use for creation.
1556 * @return The new Variant.
1557 * @newin{2,36}
1558 */
1559 static Variant< std::vector<std::string> >
1560 create_from_object_paths(const std::vector<std::string>& paths);
1561
1562 /** Gets a specific element of the string array. It is an error if @a index
1563 * is greater than the number of child items in the container. See
1564 * VariantContainerBase::get_n_children().
1565 *
1566 * This function is O(1).
1567 *
1568 * @param index The index of the element.
1569 * @return The element at index @a index.
1570 * @throw std::out_of_range
1571 * @newin{2,28}
1572 */
1573 std::string get_child(gsize index) const;
1574
1575 /** Gets the string vector of the Variant.
1576 * @return The vector.
1577 * @newin{2,28}
1578 */
1579 std::vector<std::string> get() const;
1580
1581
1582 // Object paths are merely strings so it is possible to get them already with
1583 // the existing get() methods in this class.
1584
1585
1586 /** Gets a VariantIter of the Variant.
1587 * @return the VariantIter.
1588 * @newin{2,28}
1589 */
1590 VariantIter get_iter() const;
1591 };
1592
1593 /** Specialization of Variant containing a dictionary (a map of (key,
1594 * value) elements).
1595 * @newin{2,28}
1596 * @ingroup Variant
1597 */
1598 template<class K, class V>
1599 class Variant< std::map<K, V> >: public VariantContainerBase
1600 {
1601 public:
1602 using CppType = std::pair<K, V>;
1603 using CppContainerType = std::map<K, V>;
1604
1605 /// Default constructor.
1606 Variant< std::map<K, V> >()
VariantContainerBase()1607 : VariantContainerBase()
1608 {}
1609
1610 /** GVariant constructor.
1611 * @param castitem The GVariant to wrap.
1612 * @param take_a_reference Whether to take an extra reference of the
1613 * GVariant or not (not taking one could destroy the GVariant with the
1614 * wrapper).
1615 */
1616 explicit Variant< std::map<K, V> >(GVariant* castitem,
1617 bool take_a_reference = false)
VariantContainerBase(castitem,take_a_reference)1618 : VariantContainerBase(castitem, take_a_reference)
1619 {}
1620
1621 /** Gets the VariantType.
1622 * @return The VariantType.
1623 * @newin{2,28}
1624 */
1625 static const VariantType& variant_type() G_GNUC_CONST;
1626
1627 /** Creates a new Variant containing a dictionary from a map.
1628 * @param data The map to use for creation.
1629 * @return The new Variant holding a dictionary.
1630 * @newin{2,28}
1631 */
1632 static Variant< std::map<K, V> > create(const std::map<K, V>& data);
1633
1634 /** Gets a specific dictionary entry from the string array. It is an error
1635 * if @a index is greater than the number of child items in the container.
1636 * See VariantContainerBase::get_n_children().
1637 *
1638 * This function is O(1).
1639 *
1640 * @param index The index of the element.
1641 * @return The dictionary entry at index @a index.
1642 * @throw std::out_of_range
1643 * @newin{2,28}
1644 */
1645 std::pair<K, V> get_child(gsize index) const;
1646
1647 /** Looks up a value in a dictionary Variant.
1648 * @param key The key to look up.
1649 * @param value A location in which to store the value if found.
1650 * @return <tt>true</tt> if the key is found, <tt>false</tt> otherwise.
1651 */
1652 bool lookup(const K& key, V& value) const;
1653
1654
1655 /** Gets the map (the dictionary) of the Variant.
1656 * @return The vector.
1657 * @newin{2,28}
1658 */
1659 std::map<K, V> get() const;
1660
1661 /** Gets a VariantIter of the Variant.
1662 * @return the VariantIter.
1663 * @newin{2,28}
1664 */
1665 VariantIter get_iter() const;
1666 };
1667
1668 /** Specialization of Variant containing a tuple.
1669 * @newin{2,54}
1670 * @ingroup Variant
1671 */
1672 template <class... Types>
1673 class Variant<std::tuple<Types...>> : public VariantContainerBase
1674 {
1675 public:
1676 using CppContainerType = std::tuple<Types...>;
1677
1678 /// Default constructor
1679 Variant<std::tuple<Types...>>()
VariantContainerBase()1680 : VariantContainerBase()
1681 {}
1682
1683 /** GVariant constructor.
1684 * @param castitem The GVariant to wrap.
1685 * @param take_a_reference Whether to take an extra reference of the GVariant
1686 * or not (not taking one could destroy the GVariant with the wrapper).
1687 */
1688 explicit Variant<std::tuple<Types...>>(GVariant* castitem, bool take_a_reference = false)
VariantContainerBase(castitem,take_a_reference)1689 : VariantContainerBase(castitem, take_a_reference)
1690 {}
1691
1692 /** Creates a new Variant containing a tuple.
1693 * @param data The tuple to use for creation.
1694 * @return The new Variant holding a tuple.
1695 * @newin{2,54}
1696 */
1697 static Variant<std::tuple<Types...>> create(const std::tuple<Types...>& data);
1698
1699 /** Gets the VariantType.
1700 * @return The VariantType.
1701 * @newin{2,54}
1702 */
1703 static const VariantType& variant_type() G_GNUC_CONST;
1704
1705 /** Gets a specific element from the tuple.
1706 * It is an error if @a index is greater than or equal to the number of
1707 * elements in the tuple. See VariantContainerBase::get_n_children().
1708 *
1709 * @param index The index of the element.
1710 * @return The tuple element at index @a index.
1711 * @throw std::out_of_range
1712 * @newin{2,54}
1713 */
1714 template<class T>
1715 T get_child(gsize index) const;
1716
1717 template<class T>
1718 Variant<T> get_child_variant(gsize index) const;
1719
1720 /** Gets the tuple of the Variant.
1721 * @return The tuple.
1722 * @newin{2,54}
1723 */
1724 std::tuple<Types...> get() const;
1725
1726 /** Gets a VariantIter of the Variant.
1727 * @return The VariantIter.
1728 * @newin{2,54}
1729 */
1730 VariantIter get_iter() const;
1731 };
1732
1733 } // namespace Glib
1734
1735
1736 //We ignore g_variant_get_*() methods that are wrapped by Variant<> specializations, such as in variant_basictypes.h.m4.
1737
1738
1739 /* Include generated specializations of Variant<> for fundamental types:
1740 */
1741 #define _GLIBMM_VARIANT_H_INCLUDE_VARIANT_BASICTYPES_H
1742 #include <glibmm/variant_basictypes.h>
1743 #undef _GLIBMM_VARIANT_H_INCLUDE_VARIANT_BASICTYPES_H
1744
1745 namespace Glib
1746 {
1747
1748 /*--------------------Variant< Variant<T> >---------------------*/
1749
1750 template<class T>
Variant()1751 Variant< Variant<T> >::Variant()
1752 : VariantContainerBase()
1753 {
1754 }
1755
1756 template<class T>
Variant(GVariant * castitem,bool take_a_reference)1757 Variant< Variant<T> >::Variant(GVariant* castitem, bool take_a_reference)
1758 : VariantContainerBase(castitem, take_a_reference)
1759 {
1760 }
1761
1762 // static
1763 template<class T>
variant_type()1764 const VariantType& Variant< Variant<T> >::variant_type()
1765 {
1766 return VARIANT_TYPE_VARIANT;
1767 }
1768
1769 template<class T>
create(const Variant<T> & data)1770 Variant< Variant<T> > Variant< Variant<T> >::create(const Variant<T>& data)
1771 {
1772 Variant< Variant<T> > result = Variant< Variant<T> >(
1773 g_variant_new_variant(const_cast<GVariant*>(data.gobj())));
1774 return result;
1775 }
1776
1777 template<class T>
get()1778 Variant<T> Variant< Variant<T> >::get() const
1779 {
1780 GVariant* const gvariant = g_variant_get_variant(gobject_);
1781 return Variant<T>(gvariant);
1782 }
1783
1784 /*--------------------Variant< std::pair<K, V> >---------------------*/
1785
1786 // static
1787 template<class K, class V>
variant_type()1788 const VariantType& Variant< std::pair<K, V> >::variant_type()
1789 {
1790 static VariantType type(
1791 g_variant_type_new_dict_entry(Variant<K>::variant_type().gobj(),
1792 Variant<V>::variant_type().gobj()));
1793
1794 return type;
1795 }
1796
1797 template<class K, class V>
1798 Variant< std::pair<K, V> >
create(const std::pair<K,V> & data)1799 Variant< std::pair<K, V> >::create(const std::pair<K, V>& data)
1800 {
1801 Variant<K> key = Variant<K>::create(data.first);
1802 Variant<V> value = Variant<V>::create(data.second);
1803
1804 Variant< std::pair<K, V> > result = Variant< std::pair<K, V> >(
1805 g_variant_new_dict_entry(key.gobj(), value.gobj()));
1806
1807 return result;
1808 }
1809
1810 template<class K, class V>
get()1811 std::pair<K, V> Variant< std::pair<K, V> >::get() const
1812 {
1813 // Get the key (the first element of this VariantContainerBase).
1814 Variant<K> key;
1815 VariantContainerBase::get_child(key, 0);
1816
1817 // Get the value (the second element of this VariantContainerBase).
1818 Variant<V> value;
1819 VariantContainerBase::get_child(value, 1);
1820
1821 std::pair<K, V> result(key.get(), value.get());
1822
1823 return result;
1824 }
1825
1826 /*---------------------Variant< std::vector<T> >---------------------*/
1827
1828 // static
1829 template<class T>
variant_type()1830 const VariantType& Variant< std::vector<T> >::variant_type()
1831 {
1832 static VariantType type =
1833 VariantType::create_array(Variant<T>::variant_type());
1834
1835 return type;
1836 }
1837
1838 template<class T>
1839 Variant< std::vector<T> >
create(const std::vector<T> & data)1840 Variant< std::vector<T> >::create(const std::vector<T>& data)
1841 {
1842 // Get the variant type of the array.
1843 VariantType array_variant_type = Variant< std::vector<T> >::variant_type();
1844
1845 // Create a GVariantBuilder to build the array.
1846 GVariantBuilder* builder = g_variant_builder_new(array_variant_type.gobj());
1847
1848 // Add the elements of the vector into the builder.
1849 for(const auto& element : data)
1850 {
1851 Glib::Variant<T> variant = Glib::Variant<T>::create(element);
1852 g_variant_builder_add_value(builder, variant.gobj());
1853 }
1854
1855 // Create the variant using the builder.
1856 Variant< std::vector<T> > result =
1857 Variant< std::vector<T> >(g_variant_new(
1858 reinterpret_cast<const gchar*>(array_variant_type.gobj()), builder));
1859
1860 g_variant_builder_unref(builder);
1861
1862 return result;
1863 }
1864
1865 template<class T>
get_child(gsize index)1866 T Variant< std::vector<T> >::get_child(gsize index) const
1867 {
1868 if (index >= get_n_children())
1869 throw std::out_of_range(
1870 "Variant< std::vector<T> >::get_child(): Index out of bounds.");
1871
1872 Glib::Variant<T> variant;
1873
1874 GVariant* gvariant =
1875 g_variant_get_child_value(const_cast<GVariant*>(gobj()), index);
1876
1877 variant.init(gvariant);
1878 return variant.get();
1879 }
1880
1881 template<class T>
get()1882 std::vector<T> Variant< std::vector<T> >::get() const
1883 {
1884 std::vector<T> result;
1885
1886 for (gsize i = 0, n_children = get_n_children(); i < n_children; ++i)
1887 {
1888 Glib::Variant<T> variant;
1889
1890 GVariant* gvariant =
1891 g_variant_get_child_value(const_cast<GVariant*>(gobj()), i);
1892
1893 variant.init(gvariant);
1894 result.emplace_back(variant.get());
1895 }
1896
1897 return result;
1898 }
1899
1900 template<class T>
get_iter()1901 VariantIter Variant< std::vector<T> >::get_iter() const
1902 {
1903 return VariantContainerBase::get_iter(variant_type());
1904 }
1905
1906 /*---------------------Variant< std::map<K, V> > --------------------*/
1907
1908 // static
1909 template<class K, class V>
variant_type()1910 const VariantType& Variant< std::map<K, V> >::variant_type()
1911 {
1912 static VariantType type =
1913 VariantType::create_array(Variant< std::pair<K, V> >::variant_type());
1914
1915 return type;
1916 }
1917
1918 template<class K, class V>
1919 Variant< std::map<K, V> >
create(const std::map<K,V> & data)1920 Variant< std::map<K, V> >::create(const std::map<K, V>& data)
1921 {
1922 // Get the variant type of the elements.
1923 VariantType element_variant_type =
1924 Variant< std::pair<K, V> >::variant_type();
1925
1926 // Get the variant type of the array.
1927 VariantType array_variant_type = Variant< std::map<K, V> >::variant_type();
1928
1929 // Create a GVariantBuilder to build the array.
1930 GVariantBuilder* builder = g_variant_builder_new(array_variant_type.gobj());
1931
1932 // Add the elements of the map into the builder.
1933 for(const auto& element : data)
1934 {
1935 auto dict_entry =
1936 Variant< std::pair<K, V> >::create(element);
1937
1938 g_variant_builder_add_value(builder, dict_entry.gobj());
1939 }
1940
1941 // Create the variant using the builder.
1942 Variant< std::map<K, V> > result = Variant< std::map<K, V> >(g_variant_new(
1943 reinterpret_cast<const gchar*>(array_variant_type.gobj()), builder));
1944
1945 g_variant_builder_unref(builder);
1946
1947 return result;
1948 }
1949
1950 template<class K, class V>
1951 std::pair<K, V>
get_child(gsize index)1952 Variant< std::map<K, V> >::get_child(gsize index) const
1953 {
1954 Variant< std::pair<K, V> > dict_entry;
1955 VariantContainerBase::get_child(dict_entry, index);
1956 return dict_entry.get();
1957 }
1958
1959 template<class K, class V>
lookup(const K & key,V & value)1960 bool Variant< std::map<K, V> >::lookup(const K& key, V& value) const
1961 {
1962 // The code in this method pretty much reflects the g_variant_lookup_value()
1963 // function except that it's more general to deal with keys that are not
1964 // just strings.
1965 VariantIter iter = get_iter();
1966
1967 Variant< std::pair<K, V> > entry;
1968
1969 while(iter.next_value(entry))
1970 {
1971 std::pair<K, V> element = entry.get();
1972
1973 if(element.first == key)
1974 {
1975 value = element.second;
1976 return true;
1977 }
1978 }
1979
1980 return false;
1981 }
1982
1983 template<class K, class V>
get()1984 std::map<K, V> Variant< std::map<K, V> >::get() const
1985 {
1986 std::map<K, V> result;
1987 VariantIter iter = get_iter();
1988 Variant< std::pair<K, V> > entry;
1989
1990 while(iter.next_value(entry))
1991 {
1992 result.insert(entry.get());
1993 }
1994
1995 return result;
1996 }
1997
1998 template<class K, class V>
get_iter()1999 VariantIter Variant< std::map<K, V> >::get_iter() const
2000 {
2001 return VariantContainerBase::get_iter(variant_type());
2002 }
2003
2004 /*---------------------Variant<std::tuple<class... Types>> --------------------*/
2005
2006 // static
2007 template <class... Types>
variant_type()2008 const VariantType& Variant<std::tuple<Types...>>::variant_type()
2009 {
2010 std::vector<VariantType> types;
2011 auto expander = [&types](const VariantType &type) mutable -> int
2012 {
2013 types.push_back(type);
2014 return 0;
2015 };
2016
2017 // expands the variadic template parameters
2018 using swallow = int[]; // ensures left to right order
2019 (void)swallow{(expander(Variant<Types>::variant_type()))...};
2020 static auto type = VariantType::create_tuple(types);
2021
2022 return type;
2023 }
2024
2025 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2026 namespace detail
2027 {
2028 // std::index_sequence and std::index_sequence_for are new in C++14,
2029 // but this version of glibmm requires only C++11.
2030 // The following code replaces std::index_sequence and std::index_sequence_for
2031 // until we can require C++14 support.
2032 // See https://bugzilla.gnome.org/show_bug.cgi?id=787648
2033
2034 /// Class template integer_sequence
2035 template<typename T, T... Idx>
2036 struct integer_sequence
2037 {
2038 typedef T value_type;
sizeinteger_sequence2039 static constexpr std::size_t size() { return sizeof...(Idx); }
2040 };
2041
2042 // Concatenates two integer_sequences.
2043 template<typename Iseq1, typename Iseq2> struct iseq_cat;
2044
2045 template<typename T, std::size_t... Ind1, std::size_t... Ind2>
2046 struct iseq_cat<integer_sequence<T, Ind1...>, integer_sequence<T, Ind2...>>
2047 {
2048 using type = integer_sequence<T, Ind1..., (Ind2 + sizeof...(Ind1))...>;
2049 };
2050
2051 // Builds an integer_sequence<T, 0, 1, 2, ..., Num-1>.
2052 template<typename T, std::size_t Num>
2053 struct make_intseq
2054 : iseq_cat<typename make_intseq<T, Num / 2>::type,
2055 typename make_intseq<T, Num - Num / 2>::type>
2056 { };
2057
2058 template<typename T>
2059 struct make_intseq<T, 1>
2060 {
2061 typedef integer_sequence<T, 0> type;
2062 };
2063
2064 template<typename T>
2065 struct make_intseq<T, 0>
2066 {
2067 typedef integer_sequence<T> type;
2068 };
2069
2070 /// Alias template make_integer_sequence
2071 template<typename T, T Num>
2072 using make_integer_sequence = typename make_intseq<T, Num>::type;
2073
2074 /// Alias template index_sequence
2075 template<std::size_t... Idx>
2076 using index_sequence = integer_sequence<std::size_t, Idx...>;
2077
2078 /// Alias template make_index_sequence
2079 template<std::size_t Num>
2080 using make_index_sequence = make_integer_sequence<std::size_t, Num>;
2081
2082 /// Alias template index_sequence_for
2083 template<typename... Types>
2084 using index_sequence_for = make_index_sequence<sizeof...(Types)>;
2085
2086 // End of code that replaces std::index_sequence and std::index_sequence_for
2087
2088 template <class Tuple, std::size_t... Is>
2089 void expand_tuple(std::vector<VariantBase> &variants, const Tuple & t,
2090 detail::index_sequence<Is...>)
2091 {
2092 using swallow = int[]; // ensures left to right order
2093 auto expander = [&variants](const VariantBase &variant) -> int
2094 {
2095 variants.push_back(variant);
2096 return 0;
2097 };
2098 (void)swallow {(expander(Variant<typename std::tuple_element<Is, Tuple>::type>::create(std::get<Is>(t))))...};
2099 }
2100 } // namespace detail
2101 #endif // DOXYGEN_SHOULD_SKIP_THIS
2102
2103 template <class... Types>
2104 Variant<std::tuple<Types...>>
2105 Variant<std::tuple<Types...>>::create(const std::tuple<Types...>& data)
2106 {
2107 // create a vector containing all tuple values as variants
2108 std::vector<Glib::VariantBase> variants;
2109 detail::expand_tuple(variants, data, detail::index_sequence_for<Types...>{});
2110
2111 using var_ptr = GVariant*;
2112 std::unique_ptr<var_ptr[]> var_array(new var_ptr[sizeof... (Types)]);
2113
2114 for (std::vector<VariantBase>::size_type i = 0; i < variants.size(); i++)
2115 var_array[i] = const_cast<GVariant*>(variants[i].gobj());
2116
2117 Variant<std::tuple<Types...>> result = Variant<std::tuple<Types...>>(
2118 g_variant_new_tuple(var_array.get(), variants.size()));
2119
2120 return result;
2121 }
2122
2123 template <class... Types>
2124 template <class T>
2125 T Variant<std::tuple<Types...>>::get_child(gsize index) const
2126 {
2127 Variant<T> entry;
2128 VariantContainerBase::get_child(entry, index);
2129 return entry.get();
2130 }
2131
2132 template <class... Types>
2133 template <class T>
2134 Variant<T> Variant<std::tuple<Types...>>::get_child_variant(gsize index) const
2135 {
2136 Variant<T> entry;
2137 VariantContainerBase::get_child(entry, index);
2138 return entry;
2139 }
2140
2141 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2142 namespace detail
2143 {
2144 // swallows any argument
2145 template <class T>
2146 constexpr int any_arg(T&& /* arg */)
2147 {
2148 return 0;
2149 }
2150
2151 template <class Tuple, std::size_t... Is>
2152 void assign_tuple(std::vector<VariantBase> &variants, Tuple & t, detail::index_sequence<Is...>)
2153 {
2154 int i = 0;
2155 using swallow = int[]; // ensures left to right order
2156 (void)swallow {(any_arg(std::get<Is>(t) = VariantBase::cast_dynamic<Variant<typename std::tuple_element<Is, Tuple>::type > >(variants[i++]).get()))...};
2157 }
2158 } // namespace detail
2159 #endif // DOXYGEN_SHOULD_SKIP_THIS
2160
2161 template <class... Types>
2162 std::tuple<Types...> Variant<std::tuple<Types...>>::get() const
2163 {
2164 std::tuple<Types...> data;
2165 int i = 0;
2166
2167 std::vector<VariantBase> variants;
2168 using swallow = int[]; // ensures left to right order
2169 auto expander = [&variants, &i](const VariantBase &variant) -> int
2170 {
2171 variants.push_back(variant);
2172 return i++;
2173 };
2174 (void)swallow{(expander(get_child_variant<Types>(i)))...};
2175 detail::assign_tuple(variants, data, detail::index_sequence_for<Types...>{});
2176
2177 return data;
2178 }
2179
2180 template< class... Types>
2181 VariantIter Variant<std::tuple<Types...>>::get_iter() const
2182 {
2183 const auto type = variant_type();
2184 return VariantContainerBase::get_iter(type);
2185 }
2186
2187 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2188 // This is needed so Glib::VariantBase can be used with
2189 // Glib::Value and _WRAP_PROPERTY in Gio::Action and elsewhere.
2190 template <>
2191 class GLIBMM_API Value<Glib::VariantBase> : public ValueBase_Variant
2192 {
2193 public:
2194 using CppType = Glib::VariantBase;
2195
2196 void set(CppType data);
2197 CppType get() const;
2198 };
2199 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
2200
2201 } // namespace Glib
2202
2203
2204 namespace Glib
2205 {
2206
2207 /** @relates Glib::VariantBase
2208 * @param lhs The left-hand side
2209 * @param rhs The right-hand side
2210 */
2211 inline void swap(VariantBase& lhs, VariantBase& rhs) noexcept
2212 { lhs.swap(rhs); }
2213
2214 } // namespace Glib
2215
2216 namespace Glib
2217 {
2218
2219 /** A Glib::wrap() method for this object.
2220 *
2221 * @param object The C instance.
2222 * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
2223 * @result A C++ instance that wraps this C instance.
2224 *
2225 * @relates Glib::VariantBase
2226 */
2227 GLIBMM_API
2228 Glib::VariantBase wrap(GVariant* object, bool take_copy = false);
2229
2230 } // namespace Glib
2231
2232
2233 #endif /* _GLIBMM_VARIANT_H */
2234
2235