tizen: kdbus: make i explicitly positive in make_single_header_vector
[platform/upstream/glib.git] / gobject / gparamspecs.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  * Copyright (C) 2010 Christian Persch
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * MT safe
23  */
24
25 #include "config.h"
26
27 #include <string.h>
28
29 #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
30 #define GLIB_DISABLE_DEPRECATION_WARNINGS
31 #endif
32
33 #include "gparamspecs.h"
34 #include "gtype-private.h"
35 #include "gvaluecollector.h"
36
37 #include "gvaluearray.h"
38
39
40 #define G_FLOAT_EPSILON         (1e-30)
41 #define G_DOUBLE_EPSILON        (1e-90)
42
43
44 /* --- param spec functions --- */
45 static void
46 param_char_init (GParamSpec *pspec)
47 {
48   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
49   
50   cspec->minimum = 0x7f;
51   cspec->maximum = 0x80;
52   cspec->default_value = 0;
53 }
54
55 static void
56 param_char_set_default (GParamSpec *pspec,
57                         GValue     *value)
58 {
59   value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
60 }
61
62 static gboolean
63 param_char_is_valid (GParamSpec   *pspec,
64                      const GValue *value)
65 {
66   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
67   gint oval = value->data[0].v_int;
68   
69   return cspec->minimum <= oval && oval <= cspec->maximum;
70 }
71
72 static gboolean
73 param_char_validate (GParamSpec *pspec,
74                      GValue     *value)
75 {
76   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
77   gint oval = value->data[0].v_int;
78   
79   value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
80   
81   return value->data[0].v_int != oval;
82 }
83
84 static void
85 param_uchar_init (GParamSpec *pspec)
86 {
87   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
88   
89   uspec->minimum = 0;
90   uspec->maximum = 0xff;
91   uspec->default_value = 0;
92 }
93
94 static void
95 param_uchar_set_default (GParamSpec *pspec,
96                          GValue     *value)
97 {
98   value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
99 }
100
101 static gboolean
102 param_uchar_is_valid (GParamSpec   *pspec,
103                       const GValue *value)
104 {
105   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
106   guint oval = value->data[0].v_uint;
107   
108   return uspec->minimum <= oval && oval <= uspec->maximum;
109 }
110
111 static gboolean
112 param_uchar_validate (GParamSpec *pspec,
113                       GValue     *value)
114 {
115   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
116   guint oval = value->data[0].v_uint;
117   
118   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
119   
120   return value->data[0].v_uint != oval;
121 }
122
123 static void
124 param_boolean_set_default (GParamSpec *pspec,
125                            GValue     *value)
126 {
127   value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
128 }
129
130 static gboolean
131 param_boolean_is_valid (GParamSpec   *pspec,
132                         const GValue *value)
133 {
134   int oval = value->data[0].v_int;
135
136   return oval == FALSE || oval == TRUE;
137 }
138
139 static gboolean
140 param_boolean_validate (GParamSpec *pspec,
141                         GValue     *value)
142 {
143   gint oval = value->data[0].v_int;
144   
145   value->data[0].v_int = value->data[0].v_int != FALSE;
146   
147   return value->data[0].v_int != oval;
148 }
149
150 static void
151 param_int_init (GParamSpec *pspec)
152 {
153   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
154   
155   ispec->minimum = 0x7fffffff;
156   ispec->maximum = 0x80000000;
157   ispec->default_value = 0;
158 }
159
160 static void
161 param_int_set_default (GParamSpec *pspec,
162                        GValue     *value)
163 {
164   value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
165 }
166
167 static gboolean
168 param_int_is_valid (GParamSpec   *pspec,
169                     const GValue *value)
170 {
171   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
172   int oval = value->data[0].v_int;
173
174   return ispec->minimum <= oval && oval <= ispec->maximum;
175 }
176
177 static gboolean
178 param_int_validate (GParamSpec *pspec,
179                     GValue     *value)
180 {
181   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
182   gint oval = value->data[0].v_int;
183   
184   value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
185   
186   return value->data[0].v_int != oval;
187 }
188
189 static gint
190 param_int_values_cmp (GParamSpec   *pspec,
191                       const GValue *value1,
192                       const GValue *value2)
193 {
194   if (value1->data[0].v_int < value2->data[0].v_int)
195     return -1;
196   else
197     return value1->data[0].v_int > value2->data[0].v_int;
198 }
199
200 static void
201 param_uint_init (GParamSpec *pspec)
202 {
203   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
204   
205   uspec->minimum = 0;
206   uspec->maximum = 0xffffffff;
207   uspec->default_value = 0;
208 }
209
210 static void
211 param_uint_set_default (GParamSpec *pspec,
212                         GValue     *value)
213 {
214   value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
215 }
216
217 static gboolean
218 param_uint_is_valid (GParamSpec   *pspec,
219                      const GValue *value)
220 {
221   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
222   guint oval = value->data[0].v_uint;
223   
224   return uspec->minimum <= oval && oval <= uspec->maximum;
225 }
226
227 static gboolean
228 param_uint_validate (GParamSpec *pspec,
229                      GValue     *value)
230 {
231   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
232   guint oval = value->data[0].v_uint;
233   
234   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
235   
236   return value->data[0].v_uint != oval;
237 }
238
239 static gint
240 param_uint_values_cmp (GParamSpec   *pspec,
241                        const GValue *value1,
242                        const GValue *value2)
243 {
244   if (value1->data[0].v_uint < value2->data[0].v_uint)
245     return -1;
246   else
247     return value1->data[0].v_uint > value2->data[0].v_uint;
248 }
249
250 static void
251 param_long_init (GParamSpec *pspec)
252 {
253   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
254   
255 #if SIZEOF_LONG == 4
256   lspec->minimum = 0x7fffffff;
257   lspec->maximum = 0x80000000;
258 #else /* SIZEOF_LONG != 4 (8) */
259   lspec->minimum = 0x7fffffffffffffff;
260   lspec->maximum = 0x8000000000000000;
261 #endif
262   lspec->default_value = 0;
263 }
264
265 static void
266 param_long_set_default (GParamSpec *pspec,
267                         GValue     *value)
268 {
269   value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
270 }
271
272 static gboolean
273 param_long_is_valid (GParamSpec   *pspec,
274                      const GValue *value)
275 {
276   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
277   glong oval = value->data[0].v_long;
278   
279   return lspec->minimum <= oval && oval <= lspec->maximum;
280 }
281
282 static gboolean
283 param_long_validate (GParamSpec *pspec,
284                      GValue     *value)
285 {
286   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
287   glong oval = value->data[0].v_long;
288   
289   value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
290   
291   return value->data[0].v_long != oval;
292 }
293
294 static gint
295 param_long_values_cmp (GParamSpec   *pspec,
296                        const GValue *value1,
297                        const GValue *value2)
298 {
299   if (value1->data[0].v_long < value2->data[0].v_long)
300     return -1;
301   else
302     return value1->data[0].v_long > value2->data[0].v_long;
303 }
304
305 static void
306 param_ulong_init (GParamSpec *pspec)
307 {
308   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
309   
310   uspec->minimum = 0;
311 #if SIZEOF_LONG == 4
312   uspec->maximum = 0xffffffff;
313 #else /* SIZEOF_LONG != 4 (8) */
314   uspec->maximum = 0xffffffffffffffff;
315 #endif
316   uspec->default_value = 0;
317 }
318
319 static void
320 param_ulong_set_default (GParamSpec *pspec,
321                          GValue     *value)
322 {
323   value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
324 }
325
326 static gboolean
327 param_ulong_is_valid (GParamSpec   *pspec,
328                       const GValue *value)
329 {
330   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
331   gulong oval = value->data[0].v_ulong;
332   
333   return uspec->minimum <= oval && oval <= uspec->maximum;
334 }
335
336 static gboolean
337 param_ulong_validate (GParamSpec *pspec,
338                       GValue     *value)
339 {
340   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
341   gulong oval = value->data[0].v_ulong;
342   
343   value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
344   
345   return value->data[0].v_ulong != oval;
346 }
347
348 static gint
349 param_ulong_values_cmp (GParamSpec   *pspec,
350                         const GValue *value1,
351                         const GValue *value2)
352 {
353   if (value1->data[0].v_ulong < value2->data[0].v_ulong)
354     return -1;
355   else
356     return value1->data[0].v_ulong > value2->data[0].v_ulong;
357 }
358
359 static void
360 param_int64_init (GParamSpec *pspec)
361 {
362   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
363   
364   lspec->minimum = G_MININT64;
365   lspec->maximum = G_MAXINT64;
366   lspec->default_value = 0;
367 }
368
369 static void
370 param_int64_set_default (GParamSpec *pspec,
371                         GValue     *value)
372 {
373   value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
374 }
375
376 static gboolean
377 param_int64_is_valid (GParamSpec   *pspec,
378                       const GValue *value)
379 {
380   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
381   gint64 oval = value->data[0].v_int64;
382   
383   return lspec->minimum <= oval && oval <= lspec->maximum;
384 }
385
386 static gboolean
387 param_int64_validate (GParamSpec *pspec,
388                      GValue     *value)
389 {
390   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
391   gint64 oval = value->data[0].v_int64;
392   
393   value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum);
394   
395   return value->data[0].v_int64 != oval;
396 }
397
398 static gint
399 param_int64_values_cmp (GParamSpec   *pspec,
400                        const GValue *value1,
401                        const GValue *value2)
402 {
403   if (value1->data[0].v_int64 < value2->data[0].v_int64)
404     return -1;
405   else
406     return value1->data[0].v_int64 > value2->data[0].v_int64;
407 }
408
409 static void
410 param_uint64_init (GParamSpec *pspec)
411 {
412   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
413   
414   uspec->minimum = 0;
415   uspec->maximum = G_MAXUINT64;
416   uspec->default_value = 0;
417 }
418
419 static void
420 param_uint64_set_default (GParamSpec *pspec,
421                          GValue     *value)
422 {
423   value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
424 }
425
426 static gboolean
427 param_uint64_is_valid (GParamSpec   *pspec,
428                        const GValue *value)
429 {
430   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
431   guint64 oval = value->data[0].v_uint64;
432   
433   return uspec->minimum <= oval && oval <= uspec->maximum;
434 }
435
436 static gboolean
437 param_uint64_validate (GParamSpec *pspec,
438                       GValue     *value)
439 {
440   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
441   guint64 oval = value->data[0].v_uint64;
442   
443   value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum);
444   
445   return value->data[0].v_uint64 != oval;
446 }
447
448 static gint
449 param_uint64_values_cmp (GParamSpec   *pspec,
450                         const GValue *value1,
451                         const GValue *value2)
452 {
453   if (value1->data[0].v_uint64 < value2->data[0].v_uint64)
454     return -1;
455   else
456     return value1->data[0].v_uint64 > value2->data[0].v_uint64;
457 }
458
459 static void
460 param_unichar_init (GParamSpec *pspec)
461 {
462   GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
463   
464   uspec->default_value = 0;
465 }
466
467 static void
468 param_unichar_set_default (GParamSpec *pspec,
469                          GValue     *value)
470 {
471   value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
472 }
473
474 static gboolean
475 param_unichar_is_valid (GParamSpec   *pspec,
476                         const GValue *value)
477 {
478   return g_unichar_validate (value->data[0].v_uint);
479 }
480
481 static gboolean
482 param_unichar_validate (GParamSpec *pspec,
483                         GValue     *value)
484 {
485   gunichar oval = value->data[0].v_uint;
486   gboolean changed = FALSE;
487
488   if (!g_unichar_validate (oval))
489     {
490       value->data[0].v_uint = 0;
491       changed = TRUE;
492     }
493
494   return changed;
495 }
496
497 static gint
498 param_unichar_values_cmp (GParamSpec   *pspec,
499                         const GValue *value1,
500                         const GValue *value2)
501 {
502   if (value1->data[0].v_uint < value2->data[0].v_uint)
503     return -1;
504   else
505     return value1->data[0].v_uint > value2->data[0].v_uint;
506 }
507
508 static void
509 param_enum_init (GParamSpec *pspec)
510 {
511   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
512   
513   espec->enum_class = NULL;
514   espec->default_value = 0;
515 }
516
517 static void
518 param_enum_finalize (GParamSpec *pspec)
519 {
520   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
521   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
522   
523   if (espec->enum_class)
524     {
525       g_type_class_unref (espec->enum_class);
526       espec->enum_class = NULL;
527     }
528   
529   parent_class->finalize (pspec);
530 }
531
532 static void
533 param_enum_set_default (GParamSpec *pspec,
534                         GValue     *value)
535 {
536   value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
537 }
538
539 static gboolean
540 param_enum_is_valid (GParamSpec   *pspec,
541                      const GValue *value)
542 {
543   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
544   glong oval = value->data[0].v_long;
545   
546   return g_enum_get_value (espec->enum_class, oval) != NULL;
547 }
548
549 static gboolean
550 param_enum_validate (GParamSpec *pspec,
551                      GValue     *value)
552 {
553   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
554   glong oval = value->data[0].v_long;
555   
556   if (!espec->enum_class ||
557       !g_enum_get_value (espec->enum_class, value->data[0].v_long))
558     value->data[0].v_long = espec->default_value;
559   
560   return value->data[0].v_long != oval;
561 }
562
563 static void
564 param_flags_init (GParamSpec *pspec)
565 {
566   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
567   
568   fspec->flags_class = NULL;
569   fspec->default_value = 0;
570 }
571
572 static void
573 param_flags_finalize (GParamSpec *pspec)
574 {
575   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
576   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
577   
578   if (fspec->flags_class)
579     {
580       g_type_class_unref (fspec->flags_class);
581       fspec->flags_class = NULL;
582     }
583   
584   parent_class->finalize (pspec);
585 }
586
587 static void
588 param_flags_set_default (GParamSpec *pspec,
589                          GValue     *value)
590 {
591   value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
592 }
593
594 static gboolean
595 param_flags_is_valid (GParamSpec   *pspec,
596                       const GValue *value)
597 {
598   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
599   gulong oval = value->data[0].v_ulong;
600   
601   return (oval & ~fspec->flags_class->mask) == 0;
602 }
603 static gboolean
604 param_flags_validate (GParamSpec *pspec,
605                       GValue     *value)
606 {
607   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
608   gulong oval = value->data[0].v_ulong;
609   
610   if (fspec->flags_class)
611     value->data[0].v_ulong &= fspec->flags_class->mask;
612   else
613     value->data[0].v_ulong = fspec->default_value;
614   
615   return value->data[0].v_ulong != oval;
616 }
617
618 static void
619 param_float_init (GParamSpec *pspec)
620 {
621   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
622   
623   fspec->minimum = -G_MAXFLOAT;
624   fspec->maximum = G_MAXFLOAT;
625   fspec->default_value = 0;
626   fspec->epsilon = G_FLOAT_EPSILON;
627 }
628
629 static void
630 param_float_set_default (GParamSpec *pspec,
631                          GValue     *value)
632 {
633   value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
634 }
635
636 static gboolean
637 param_float_is_valid (GParamSpec   *pspec,
638                       const GValue *value)
639 {
640   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
641   gfloat oval = value->data[0].v_float;
642   
643   return fspec->minimum <= oval && oval <= fspec->maximum;
644 }
645
646 static gboolean
647 param_float_validate (GParamSpec *pspec,
648                       GValue     *value)
649 {
650   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
651   gfloat oval = value->data[0].v_float;
652   
653   value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
654   
655   return value->data[0].v_float != oval;
656 }
657
658 static gint
659 param_float_values_cmp (GParamSpec   *pspec,
660                         const GValue *value1,
661                         const GValue *value2)
662 {
663   gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
664   
665   if (value1->data[0].v_float < value2->data[0].v_float)
666     return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
667   else
668     return value1->data[0].v_float - value2->data[0].v_float > epsilon;
669 }
670
671 static void
672 param_double_init (GParamSpec *pspec)
673 {
674   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
675   
676   dspec->minimum = -G_MAXDOUBLE;
677   dspec->maximum = G_MAXDOUBLE;
678   dspec->default_value = 0;
679   dspec->epsilon = G_DOUBLE_EPSILON;
680 }
681
682 static void
683 param_double_set_default (GParamSpec *pspec,
684                           GValue     *value)
685 {
686   value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
687 }
688
689 static gboolean
690 param_double_is_valid (GParamSpec   *pspec,
691                        const GValue *value)
692 {
693   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
694   gfloat oval = value->data[0].v_double;
695   
696   return dspec->minimum <= oval && oval <= dspec->maximum;
697 }
698
699 static gboolean
700 param_double_validate (GParamSpec *pspec,
701                        GValue     *value)
702 {
703   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
704   gdouble oval = value->data[0].v_double;
705   
706   value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
707   
708   return value->data[0].v_double != oval;
709 }
710
711 static gint
712 param_double_values_cmp (GParamSpec   *pspec,
713                          const GValue *value1,
714                          const GValue *value2)
715 {
716   gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
717   
718   if (value1->data[0].v_double < value2->data[0].v_double)
719     return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
720   else
721     return value1->data[0].v_double - value2->data[0].v_double > epsilon;
722 }
723
724 static void
725 param_string_init (GParamSpec *pspec)
726 {
727   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
728   
729   sspec->default_value = NULL;
730   sspec->cset_first = NULL;
731   sspec->cset_nth = NULL;
732   sspec->substitutor = '_';
733   sspec->null_fold_if_empty = FALSE;
734   sspec->ensure_non_null = FALSE;
735 }
736
737 static void
738 param_string_finalize (GParamSpec *pspec)
739 {
740   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
741   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
742   
743   g_free (sspec->default_value);
744   g_free (sspec->cset_first);
745   g_free (sspec->cset_nth);
746   sspec->default_value = NULL;
747   sspec->cset_first = NULL;
748   sspec->cset_nth = NULL;
749   
750   parent_class->finalize (pspec);
751 }
752
753 static void
754 param_string_set_default (GParamSpec *pspec,
755                           GValue     *value)
756 {
757   value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
758 }
759
760 static gboolean
761 param_string_validate (GParamSpec *pspec,
762                        GValue     *value)
763 {
764   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
765   gchar *string = value->data[0].v_pointer;
766   guint changed = 0;
767   
768   if (string && string[0])
769     {
770       gchar *s;
771       
772       if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
773         {
774           if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
775             {
776               value->data[0].v_pointer = g_strdup (string);
777               string = value->data[0].v_pointer;
778               value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
779             }
780           string[0] = sspec->substitutor;
781           changed++;
782         }
783       if (sspec->cset_nth)
784         for (s = string + 1; *s; s++)
785           if (!strchr (sspec->cset_nth, *s))
786             {
787               if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
788                 {
789                   value->data[0].v_pointer = g_strdup (string);
790                   s = (gchar*) value->data[0].v_pointer + (s - string);
791                   string = value->data[0].v_pointer;
792                   value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
793                 }
794               *s = sspec->substitutor;
795               changed++;
796             }
797     }
798   if (sspec->null_fold_if_empty && string && string[0] == 0)
799     {
800       if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
801         g_free (value->data[0].v_pointer);
802       else
803         value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
804       value->data[0].v_pointer = NULL;
805       changed++;
806       string = value->data[0].v_pointer;
807     }
808   if (sspec->ensure_non_null && !string)
809     {
810       value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
811       value->data[0].v_pointer = g_strdup ("");
812       changed++;
813       string = value->data[0].v_pointer;
814     }
815
816   return changed;
817 }
818
819 static gboolean
820 param_string_is_valid (GParamSpec   *pspec,
821                        const GValue *value)
822 {
823   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
824   gboolean ret = TRUE;
825
826   if (sspec->cset_first != NULL || sspec->cset_nth != NULL ||
827       sspec->ensure_non_null || sspec->null_fold_if_empty)
828     {
829       GValue tmp_value = G_VALUE_INIT;
830
831       g_value_init (&tmp_value, G_VALUE_TYPE (value));
832       g_value_copy (value, &tmp_value);
833
834       ret = !param_string_validate (pspec, &tmp_value);
835
836       g_value_unset (&tmp_value);
837     }
838
839   return ret;
840 }
841
842 static gint
843 param_string_values_cmp (GParamSpec   *pspec,
844                          const GValue *value1,
845                          const GValue *value2)
846 {
847   if (!value1->data[0].v_pointer)
848     return value2->data[0].v_pointer != NULL ? -1 : 0;
849   else if (!value2->data[0].v_pointer)
850     return value1->data[0].v_pointer != NULL;
851   else
852     return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
853 }
854
855 static void
856 param_param_init (GParamSpec *pspec)
857 {
858   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
859 }
860
861 static void
862 param_param_set_default (GParamSpec *pspec,
863                          GValue     *value)
864 {
865   value->data[0].v_pointer = NULL;
866 }
867
868 static gboolean
869 param_param_is_valid (GParamSpec   *pspec,
870                       const GValue *value)
871 {
872   GParamSpec *param = value->data[0].v_pointer;
873
874   if (param == NULL)
875     return FALSE;
876
877   return g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec));
878 }
879
880 static gboolean
881 param_param_validate (GParamSpec *pspec,
882                       GValue     *value)
883 {
884   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
885   GParamSpec *param = value->data[0].v_pointer;
886   guint changed = 0;
887   
888   if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
889     {
890       g_param_spec_unref (param);
891       value->data[0].v_pointer = NULL;
892       changed++;
893     }
894   
895   return changed;
896 }
897
898 static void
899 param_boxed_init (GParamSpec *pspec)
900 {
901   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
902 }
903
904 static void
905 param_boxed_set_default (GParamSpec *pspec,
906                          GValue     *value)
907 {
908   value->data[0].v_pointer = NULL;
909 }
910
911 static gint
912 param_boxed_values_cmp (GParamSpec    *pspec,
913                          const GValue *value1,
914                          const GValue *value2)
915 {
916   guint8 *p1 = value1->data[0].v_pointer;
917   guint8 *p2 = value2->data[0].v_pointer;
918
919   /* not much to compare here, try to at least provide stable lesser/greater result */
920
921   return p1 < p2 ? -1 : p1 > p2;
922 }
923
924 static void
925 param_pointer_init (GParamSpec *pspec)
926 {
927   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
928 }
929
930 static void
931 param_pointer_set_default (GParamSpec *pspec,
932                            GValue     *value)
933 {
934   value->data[0].v_pointer = NULL;
935 }
936
937 static gint
938 param_pointer_values_cmp (GParamSpec   *pspec,
939                           const GValue *value1,
940                           const GValue *value2)
941 {
942   guint8 *p1 = value1->data[0].v_pointer;
943   guint8 *p2 = value2->data[0].v_pointer;
944
945   /* not much to compare here, try to at least provide stable lesser/greater result */
946
947   return p1 < p2 ? -1 : p1 > p2;
948 }
949
950 static void
951 param_value_array_init (GParamSpec *pspec)
952 {
953   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
954
955   aspec->element_spec = NULL;
956   aspec->fixed_n_elements = 0; /* disable */
957 }
958
959 static inline guint
960 value_array_ensure_size (GValueArray *value_array,
961                          guint        fixed_n_elements)
962 {
963   guint changed = 0;
964
965   if (fixed_n_elements)
966     {
967       while (value_array->n_values < fixed_n_elements)
968         {
969           g_value_array_append (value_array, NULL);
970           changed++;
971         }
972       while (value_array->n_values > fixed_n_elements)
973         {
974           g_value_array_remove (value_array, value_array->n_values - 1);
975           changed++;
976         }
977     }
978   return changed;
979 }
980
981 static void
982 param_value_array_finalize (GParamSpec *pspec)
983 {
984   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
985   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
986
987   if (aspec->element_spec)
988     {
989       g_param_spec_unref (aspec->element_spec);
990       aspec->element_spec = NULL;
991     }
992
993   parent_class->finalize (pspec);
994 }
995
996 static void
997 param_value_array_set_default (GParamSpec *pspec,
998                                GValue     *value)
999 {
1000   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
1001
1002   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
1003     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
1004
1005   if (value->data[0].v_pointer)
1006     {
1007       /* g_value_reset (value);  already done */
1008       value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
1009     }
1010 }
1011
1012 static gboolean
1013 param_value_array_validate (GParamSpec *pspec,
1014                             GValue     *value)
1015 {
1016   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
1017   GValueArray *value_array = value->data[0].v_pointer;
1018   guint changed = 0;
1019
1020   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
1021     value_array = value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
1022
1023   if (value->data[0].v_pointer)
1024     {
1025       /* ensure array size validity */
1026       changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
1027       
1028       /* ensure array values validity against a present element spec */
1029       if (aspec->element_spec)
1030         {
1031           GParamSpec *element_spec = aspec->element_spec;
1032           guint i;
1033           
1034           for (i = 0; i < value_array->n_values; i++)
1035             {
1036               GValue *element = value_array->values + i;
1037               
1038               /* need to fixup value type, or ensure that the array value is initialized at all */
1039               if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
1040                 {
1041                   if (G_VALUE_TYPE (element) != 0)
1042                     g_value_unset (element);
1043                   g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
1044                   g_param_value_set_default (element_spec, element);
1045                   changed++;
1046                 }
1047               else
1048                 {
1049                   /* validate array value against element_spec */
1050                   changed += g_param_value_validate (element_spec, element);
1051                 }
1052             }
1053         }
1054     }
1055
1056   return changed;
1057 }
1058
1059 static gint
1060 param_value_array_values_cmp (GParamSpec   *pspec,
1061                               const GValue *value1,
1062                               const GValue *value2)
1063 {
1064   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
1065   GValueArray *value_array1 = value1->data[0].v_pointer;
1066   GValueArray *value_array2 = value2->data[0].v_pointer;
1067
1068   if (!value_array1 || !value_array2)
1069     return value_array2 ? -1 : value_array1 != value_array2;
1070
1071   if (value_array1->n_values != value_array2->n_values)
1072     return value_array1->n_values < value_array2->n_values ? -1 : 1;
1073   else if (!aspec->element_spec)
1074     {
1075       /* we need an element specification for comparisons, so there's not much
1076        * to compare here, try to at least provide stable lesser/greater result
1077        */
1078       return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
1079     }
1080   else /* value_array1->n_values == value_array2->n_values */
1081     {
1082       guint i;
1083
1084       for (i = 0; i < value_array1->n_values; i++)
1085         {
1086           GValue *element1 = value_array1->values + i;
1087           GValue *element2 = value_array2->values + i;
1088           gint cmp;
1089
1090           /* need corresponding element types, provide stable result otherwise */
1091           if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
1092             return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
1093           cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
1094           if (cmp)
1095             return cmp;
1096         }
1097       return 0;
1098     }
1099 }
1100
1101 static void
1102 param_object_init (GParamSpec *pspec)
1103 {
1104   /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
1105 }
1106
1107 static void
1108 param_object_set_default (GParamSpec *pspec,
1109                           GValue     *value)
1110 {
1111   value->data[0].v_pointer = NULL;
1112 }
1113
1114 static gboolean
1115 param_object_is_valid (GParamSpec   *pspec,
1116                        const GValue *value)
1117 {
1118   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
1119   GObject *object = value->data[0].v_pointer;
1120
1121   return object &&
1122          g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec));
1123 }
1124
1125 static gboolean
1126 param_object_validate (GParamSpec *pspec,
1127                        GValue     *value)
1128 {
1129   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
1130   GObject *object = value->data[0].v_pointer;
1131   guint changed = 0;
1132   
1133   if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
1134     {
1135       g_object_unref (object);
1136       value->data[0].v_pointer = NULL;
1137       changed++;
1138     }
1139   
1140   return changed;
1141 }
1142
1143 static gint
1144 param_object_values_cmp (GParamSpec   *pspec,
1145                          const GValue *value1,
1146                          const GValue *value2)
1147 {
1148   guint8 *p1 = value1->data[0].v_pointer;
1149   guint8 *p2 = value2->data[0].v_pointer;
1150
1151   /* not much to compare here, try to at least provide stable lesser/greater result */
1152
1153   return p1 < p2 ? -1 : p1 > p2;
1154 }
1155
1156 static void
1157 param_override_init (GParamSpec *pspec)
1158 {
1159   /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
1160 }
1161
1162 static void
1163 param_override_finalize (GParamSpec *pspec)
1164 {
1165   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1166   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_OVERRIDE));
1167   
1168   if (ospec->overridden)
1169     {
1170       g_param_spec_unref (ospec->overridden);
1171       ospec->overridden = NULL;
1172     }
1173   
1174   parent_class->finalize (pspec);
1175 }
1176
1177 static void
1178 param_override_set_default (GParamSpec *pspec,
1179                             GValue     *value)
1180 {
1181   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1182
1183   g_param_value_set_default (ospec->overridden, value);
1184 }
1185
1186 static gboolean
1187 param_override_is_valid (GParamSpec   *pspec,
1188                          const GValue *value)
1189 {
1190   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1191
1192   return g_param_value_is_valid (ospec->overridden, value);
1193 }
1194
1195 static gboolean
1196 param_override_validate (GParamSpec *pspec,
1197                          GValue     *value)
1198 {
1199   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1200   
1201   return g_param_value_validate (ospec->overridden, value);
1202 }
1203
1204 static gint
1205 param_override_values_cmp (GParamSpec   *pspec,
1206                            const GValue *value1,
1207                            const GValue *value2)
1208 {
1209   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1210
1211   return g_param_values_cmp (ospec->overridden, value1, value2);
1212 }
1213
1214 static void
1215 param_gtype_init (GParamSpec *pspec)
1216 {
1217 }
1218
1219 static void
1220 param_gtype_set_default (GParamSpec *pspec,
1221                          GValue     *value)
1222 {
1223   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1224
1225   value->data[0].v_pointer = GTYPE_TO_POINTER (tspec->is_a_type);
1226 }
1227
1228 static gboolean
1229 param_gtype_is_valid (GParamSpec   *pspec,
1230                       const GValue *value)
1231 {
1232   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1233   GType gtype = GPOINTER_TO_TYPE (value->data[0].v_pointer);
1234   
1235   return tspec->is_a_type == G_TYPE_NONE ||
1236          g_type_is_a (gtype, tspec->is_a_type);
1237 }
1238
1239 static gboolean
1240 param_gtype_validate (GParamSpec *pspec,
1241                       GValue     *value)
1242 {
1243   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1244   GType gtype = GPOINTER_TO_TYPE (value->data[0].v_pointer);
1245   guint changed = 0;
1246   
1247   if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
1248     {
1249       value->data[0].v_pointer = GTYPE_TO_POINTER (tspec->is_a_type);
1250       changed++;
1251     }
1252   
1253   return changed;
1254 }
1255
1256 static gint
1257 param_gtype_values_cmp (GParamSpec   *pspec,
1258                         const GValue *value1,
1259                         const GValue *value2)
1260 {
1261   GType p1 = GPOINTER_TO_TYPE (value1->data[0].v_pointer);
1262   GType p2 = GPOINTER_TO_TYPE (value2->data[0].v_pointer);
1263
1264   /* not much to compare here, try to at least provide stable lesser/greater result */
1265
1266   return p1 < p2 ? -1 : p1 > p2;
1267 }
1268
1269 static void
1270 param_variant_init (GParamSpec *pspec)
1271 {
1272   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1273
1274   vspec->type = NULL;
1275   vspec->default_value = NULL;
1276 }
1277
1278 static void
1279 param_variant_finalize (GParamSpec *pspec)
1280 {
1281   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1282   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
1283
1284   if (vspec->default_value)
1285     g_variant_unref (vspec->default_value);
1286   g_variant_type_free (vspec->type);
1287
1288   parent_class->finalize (pspec);
1289 }
1290
1291 static void
1292 param_variant_set_default (GParamSpec *pspec,
1293                            GValue     *value)
1294 {
1295   value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value;
1296   value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS;
1297 }
1298
1299 static gboolean
1300 param_variant_is_valid (GParamSpec   *pspec,
1301                         const GValue *value)
1302 {
1303   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1304   GVariant *variant = value->data[0].v_pointer;
1305
1306   if (variant == NULL)
1307     return vspec->default_value == NULL;
1308   else
1309     return g_variant_is_of_type (variant, vspec->type);
1310 }
1311
1312 static gboolean
1313 param_variant_validate (GParamSpec *pspec,
1314                         GValue     *value)
1315 {
1316   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1317   GVariant *variant = value->data[0].v_pointer;
1318
1319   if ((variant == NULL && vspec->default_value != NULL) ||
1320       (variant != NULL && !g_variant_is_of_type (variant, vspec->type)))
1321     {
1322       g_param_value_set_default (pspec, value);
1323       return TRUE;
1324     }
1325
1326   return FALSE;
1327 }
1328
1329 /* g_variant_compare() can only be used with scalar types. */
1330 static gboolean
1331 variant_is_incomparable (GVariant *v)
1332 {
1333   GVariantClass v_class = g_variant_classify (v);
1334
1335   return (v_class == G_VARIANT_CLASS_HANDLE ||
1336           v_class == G_VARIANT_CLASS_VARIANT ||
1337           v_class ==  G_VARIANT_CLASS_MAYBE||
1338           v_class == G_VARIANT_CLASS_ARRAY ||
1339           v_class ==  G_VARIANT_CLASS_TUPLE ||
1340           v_class == G_VARIANT_CLASS_DICT_ENTRY);
1341 }
1342
1343 static gint
1344 param_variant_values_cmp (GParamSpec   *pspec,
1345                           const GValue *value1,
1346                           const GValue *value2)
1347 {
1348   GVariant *v1 = value1->data[0].v_pointer;
1349   GVariant *v2 = value2->data[0].v_pointer;
1350
1351   if (v1 == NULL && v2 == NULL)
1352     return 0;
1353   else if (v1 == NULL && v2 != NULL)
1354     return -1;
1355   else if (v1 != NULL && v2 == NULL)
1356     return 1;
1357
1358   if (!g_variant_type_equal (g_variant_get_type (v1), g_variant_get_type (v2)) ||
1359       variant_is_incomparable (v1) ||
1360       variant_is_incomparable (v2))
1361     return g_variant_equal (v1, v2) ? 0 : (v1 < v2 ? -1 : 1);
1362
1363   return g_variant_compare (v1, v2);
1364 }
1365
1366 /* --- type initialization --- */
1367
1368 #define set_is_valid_vfunc(type,func) { \
1369   GParamSpecClass *class = g_type_class_ref (type); \
1370   class->value_is_valid = func; \
1371   g_type_class_unref (class); \
1372 }
1373
1374 GType *g_param_spec_types = NULL;
1375
1376 void
1377 _g_param_spec_types_init (void) 
1378 {
1379   const guint n_types = 23;
1380   GType type, *spec_types;
1381 #ifndef G_DISABLE_ASSERT
1382   GType *spec_types_bound;
1383 #endif
1384
1385   g_param_spec_types = g_new0 (GType, n_types);
1386   spec_types = g_param_spec_types;
1387 #ifndef G_DISABLE_ASSERT
1388   spec_types_bound = g_param_spec_types + n_types;
1389 #endif
1390   
1391   /* G_TYPE_PARAM_CHAR
1392    */
1393   {
1394     const GParamSpecTypeInfo pspec_info = {
1395       sizeof (GParamSpecChar),  /* instance_size */
1396       16,                       /* n_preallocs */
1397       param_char_init,          /* instance_init */
1398       G_TYPE_CHAR,              /* value_type */
1399       NULL,                     /* finalize */
1400       param_char_set_default,   /* value_set_default */
1401       param_char_validate,      /* value_validate */
1402       param_int_values_cmp,     /* values_cmp */
1403     };
1404     type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info);
1405     set_is_valid_vfunc (type, param_char_is_valid);
1406     *spec_types++ = type;
1407     g_assert (type == G_TYPE_PARAM_CHAR);
1408   }
1409   
1410   /* G_TYPE_PARAM_UCHAR
1411    */
1412   {
1413     const GParamSpecTypeInfo pspec_info = {
1414       sizeof (GParamSpecUChar), /* instance_size */
1415       16,                       /* n_preallocs */
1416       param_uchar_init,         /* instance_init */
1417       G_TYPE_UCHAR,             /* value_type */
1418       NULL,                     /* finalize */
1419       param_uchar_set_default,  /* value_set_default */
1420       param_uchar_validate,     /* value_validate */
1421       param_uint_values_cmp,    /* values_cmp */
1422     };
1423     type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info);
1424     set_is_valid_vfunc (type, param_uchar_is_valid);
1425     *spec_types++ = type;
1426     g_assert (type == G_TYPE_PARAM_UCHAR);
1427   }
1428   
1429   /* G_TYPE_PARAM_BOOLEAN
1430    */
1431   {
1432     const GParamSpecTypeInfo pspec_info = {
1433       sizeof (GParamSpecBoolean), /* instance_size */
1434       16,                         /* n_preallocs */
1435       NULL,                       /* instance_init */
1436       G_TYPE_BOOLEAN,             /* value_type */
1437       NULL,                       /* finalize */
1438       param_boolean_set_default,  /* value_set_default */
1439       param_boolean_validate,     /* value_validate */
1440       param_int_values_cmp,       /* values_cmp */
1441     };
1442     type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info);
1443     set_is_valid_vfunc (type, param_boolean_is_valid);
1444     *spec_types++ = type;
1445     g_assert (type == G_TYPE_PARAM_BOOLEAN);
1446   }
1447   
1448   /* G_TYPE_PARAM_INT
1449    */
1450   {
1451     const GParamSpecTypeInfo pspec_info = {
1452       sizeof (GParamSpecInt),   /* instance_size */
1453       16,                       /* n_preallocs */
1454       param_int_init,           /* instance_init */
1455       G_TYPE_INT,               /* value_type */
1456       NULL,                     /* finalize */
1457       param_int_set_default,    /* value_set_default */
1458       param_int_validate,       /* value_validate */
1459       param_int_values_cmp,     /* values_cmp */
1460     };
1461     type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info);
1462     set_is_valid_vfunc (type, param_int_is_valid);
1463     *spec_types++ = type;
1464     g_assert (type == G_TYPE_PARAM_INT);
1465   }
1466   
1467   /* G_TYPE_PARAM_UINT
1468    */
1469   {
1470     const GParamSpecTypeInfo pspec_info = {
1471       sizeof (GParamSpecUInt),  /* instance_size */
1472       16,                       /* n_preallocs */
1473       param_uint_init,          /* instance_init */
1474       G_TYPE_UINT,              /* value_type */
1475       NULL,                     /* finalize */
1476       param_uint_set_default,   /* value_set_default */
1477       param_uint_validate,      /* value_validate */
1478       param_uint_values_cmp,    /* values_cmp */
1479     };
1480     type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info);
1481     set_is_valid_vfunc (type, param_uint_is_valid);
1482     *spec_types++ = type;
1483     g_assert (type == G_TYPE_PARAM_UINT);
1484   }
1485   
1486   /* G_TYPE_PARAM_LONG
1487    */
1488   {
1489     const GParamSpecTypeInfo pspec_info = {
1490       sizeof (GParamSpecLong),  /* instance_size */
1491       16,                       /* n_preallocs */
1492       param_long_init,          /* instance_init */
1493       G_TYPE_LONG,              /* value_type */
1494       NULL,                     /* finalize */
1495       param_long_set_default,   /* value_set_default */
1496       param_long_validate,      /* value_validate */
1497       param_long_values_cmp,    /* values_cmp */
1498     };
1499     type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info);
1500     set_is_valid_vfunc (type, param_long_is_valid);
1501     *spec_types++ = type;
1502     g_assert (type == G_TYPE_PARAM_LONG);
1503   }
1504   
1505   /* G_TYPE_PARAM_ULONG
1506    */
1507   {
1508     const GParamSpecTypeInfo pspec_info = {
1509       sizeof (GParamSpecULong), /* instance_size */
1510       16,                       /* n_preallocs */
1511       param_ulong_init,         /* instance_init */
1512       G_TYPE_ULONG,             /* value_type */
1513       NULL,                     /* finalize */
1514       param_ulong_set_default,  /* value_set_default */
1515       param_ulong_validate,     /* value_validate */
1516       param_ulong_values_cmp,   /* values_cmp */
1517     };
1518     type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info);
1519     set_is_valid_vfunc (type, param_ulong_is_valid);
1520     *spec_types++ = type;
1521     g_assert (type == G_TYPE_PARAM_ULONG);
1522   }
1523
1524   /* G_TYPE_PARAM_INT64
1525    */
1526   {
1527     const GParamSpecTypeInfo pspec_info = {
1528       sizeof (GParamSpecInt64),  /* instance_size */
1529       16,                       /* n_preallocs */
1530       param_int64_init,         /* instance_init */
1531       G_TYPE_INT64,             /* value_type */
1532       NULL,                     /* finalize */
1533       param_int64_set_default,  /* value_set_default */
1534       param_int64_validate,     /* value_validate */
1535       param_int64_values_cmp,   /* values_cmp */
1536     };
1537     type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info);
1538     set_is_valid_vfunc (type, param_int64_is_valid);
1539     *spec_types++ = type;
1540     g_assert (type == G_TYPE_PARAM_INT64);
1541   }
1542   
1543   /* G_TYPE_PARAM_UINT64
1544    */
1545   {
1546     const GParamSpecTypeInfo pspec_info = {
1547       sizeof (GParamSpecUInt64), /* instance_size */
1548       16,                       /* n_preallocs */
1549       param_uint64_init,        /* instance_init */
1550       G_TYPE_UINT64,            /* value_type */
1551       NULL,                     /* finalize */
1552       param_uint64_set_default, /* value_set_default */
1553       param_uint64_validate,    /* value_validate */
1554       param_uint64_values_cmp,  /* values_cmp */
1555     };
1556     type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info);
1557     set_is_valid_vfunc (type, param_uint64_is_valid);
1558     *spec_types++ = type;
1559     g_assert (type == G_TYPE_PARAM_UINT64);
1560   }
1561
1562   /* G_TYPE_PARAM_UNICHAR
1563    */
1564   {
1565     const GParamSpecTypeInfo pspec_info = {
1566       sizeof (GParamSpecUnichar), /* instance_size */
1567       16,                        /* n_preallocs */
1568       param_unichar_init,        /* instance_init */
1569       G_TYPE_UINT,               /* value_type */
1570       NULL,                      /* finalize */
1571       param_unichar_set_default, /* value_set_default */
1572       param_unichar_validate,    /* value_validate */
1573       param_unichar_values_cmp,  /* values_cmp */
1574     };
1575     type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info);
1576     set_is_valid_vfunc (type, param_unichar_is_valid);
1577     *spec_types++ = type;
1578     g_assert (type == G_TYPE_PARAM_UNICHAR);
1579   }
1580
1581  /* G_TYPE_PARAM_ENUM
1582    */
1583   {
1584     const GParamSpecTypeInfo pspec_info = {
1585       sizeof (GParamSpecEnum),  /* instance_size */
1586       16,                       /* n_preallocs */
1587       param_enum_init,          /* instance_init */
1588       G_TYPE_ENUM,              /* value_type */
1589       param_enum_finalize,      /* finalize */
1590       param_enum_set_default,   /* value_set_default */
1591       param_enum_validate,      /* value_validate */
1592       param_long_values_cmp,    /* values_cmp */
1593     };
1594     type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info);
1595     set_is_valid_vfunc (type, param_enum_is_valid);
1596     *spec_types++ = type;
1597     g_assert (type == G_TYPE_PARAM_ENUM);
1598   }
1599   
1600   /* G_TYPE_PARAM_FLAGS
1601    */
1602   {
1603     const GParamSpecTypeInfo pspec_info = {
1604       sizeof (GParamSpecFlags), /* instance_size */
1605       16,                       /* n_preallocs */
1606       param_flags_init,         /* instance_init */
1607       G_TYPE_FLAGS,             /* value_type */
1608       param_flags_finalize,     /* finalize */
1609       param_flags_set_default,  /* value_set_default */
1610       param_flags_validate,     /* value_validate */
1611       param_ulong_values_cmp,   /* values_cmp */
1612     };
1613     type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info);
1614     set_is_valid_vfunc (type, param_flags_is_valid);
1615     *spec_types++ = type;
1616     g_assert (type == G_TYPE_PARAM_FLAGS);
1617   }
1618   
1619   /* G_TYPE_PARAM_FLOAT
1620    */
1621   {
1622     const GParamSpecTypeInfo pspec_info = {
1623       sizeof (GParamSpecFloat), /* instance_size */
1624       16,                       /* n_preallocs */
1625       param_float_init,         /* instance_init */
1626       G_TYPE_FLOAT,             /* value_type */
1627       NULL,                     /* finalize */
1628       param_float_set_default,  /* value_set_default */
1629       param_float_validate,     /* value_validate */
1630       param_float_values_cmp,   /* values_cmp */
1631     };
1632     type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info);
1633     set_is_valid_vfunc (type, param_float_is_valid);
1634     *spec_types++ = type;
1635     g_assert (type == G_TYPE_PARAM_FLOAT);
1636   }
1637   
1638   /* G_TYPE_PARAM_DOUBLE
1639    */
1640   {
1641     const GParamSpecTypeInfo pspec_info = {
1642       sizeof (GParamSpecDouble),        /* instance_size */
1643       16,                               /* n_preallocs */
1644       param_double_init,                /* instance_init */
1645       G_TYPE_DOUBLE,                    /* value_type */
1646       NULL,                             /* finalize */
1647       param_double_set_default,         /* value_set_default */
1648       param_double_validate,            /* value_validate */
1649       param_double_values_cmp,          /* values_cmp */
1650     };
1651     type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info);
1652     set_is_valid_vfunc (type, param_double_is_valid);
1653     *spec_types++ = type;
1654     g_assert (type == G_TYPE_PARAM_DOUBLE);
1655   }
1656   
1657   /* G_TYPE_PARAM_STRING
1658    */
1659   {
1660     const GParamSpecTypeInfo pspec_info = {
1661       sizeof (GParamSpecString),        /* instance_size */
1662       16,                               /* n_preallocs */
1663       param_string_init,                /* instance_init */
1664       G_TYPE_STRING,                    /* value_type */
1665       param_string_finalize,            /* finalize */
1666       param_string_set_default,         /* value_set_default */
1667       param_string_validate,            /* value_validate */
1668       param_string_values_cmp,          /* values_cmp */
1669     };
1670     type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info);
1671     set_is_valid_vfunc (type, param_string_is_valid);
1672     *spec_types++ = type;
1673     g_assert (type == G_TYPE_PARAM_STRING);
1674   }
1675   
1676   /* G_TYPE_PARAM_PARAM
1677    */
1678   {
1679     const GParamSpecTypeInfo pspec_info = {
1680       sizeof (GParamSpecParam), /* instance_size */
1681       16,                       /* n_preallocs */
1682       param_param_init,         /* instance_init */
1683       G_TYPE_PARAM,             /* value_type */
1684       NULL,                     /* finalize */
1685       param_param_set_default,  /* value_set_default */
1686       param_param_validate,     /* value_validate */
1687       param_pointer_values_cmp, /* values_cmp */
1688     };
1689     type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info);
1690     set_is_valid_vfunc (type, param_param_is_valid);
1691     *spec_types++ = type;
1692     g_assert (type == G_TYPE_PARAM_PARAM);
1693   }
1694   
1695   /* G_TYPE_PARAM_BOXED
1696    */
1697   {
1698     const GParamSpecTypeInfo pspec_info = {
1699       sizeof (GParamSpecBoxed), /* instance_size */
1700       4,                        /* n_preallocs */
1701       param_boxed_init,         /* instance_init */
1702       G_TYPE_BOXED,             /* value_type */
1703       NULL,                     /* finalize */
1704       param_boxed_set_default,  /* value_set_default */
1705       NULL,                     /* value_validate */
1706       param_boxed_values_cmp,   /* values_cmp */
1707     };
1708     type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info);
1709     *spec_types++ = type;
1710     g_assert (type == G_TYPE_PARAM_BOXED);
1711   }
1712
1713   /* G_TYPE_PARAM_POINTER
1714    */
1715   {
1716     const GParamSpecTypeInfo pspec_info = {
1717       sizeof (GParamSpecPointer),  /* instance_size */
1718       0,                           /* n_preallocs */
1719       param_pointer_init,          /* instance_init */
1720       G_TYPE_POINTER,              /* value_type */
1721       NULL,                        /* finalize */
1722       param_pointer_set_default,   /* value_set_default */
1723       NULL,
1724       param_pointer_values_cmp,    /* values_cmp */
1725     };
1726     type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info);
1727     *spec_types++ = type;
1728     g_assert (type == G_TYPE_PARAM_POINTER);
1729   }
1730   
1731   /* G_TYPE_PARAM_VALUE_ARRAY
1732    */
1733   {
1734     /* const */ GParamSpecTypeInfo pspec_info = {
1735       sizeof (GParamSpecValueArray),    /* instance_size */
1736       0,                                /* n_preallocs */
1737       param_value_array_init,           /* instance_init */
1738       0xdeadbeef,                       /* value_type, assigned further down */
1739       param_value_array_finalize,       /* finalize */
1740       param_value_array_set_default,    /* value_set_default */
1741       param_value_array_validate,       /* value_validate */
1742       param_value_array_values_cmp,     /* values_cmp */
1743     };
1744     pspec_info.value_type = G_TYPE_VALUE_ARRAY;
1745     type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info);
1746     *spec_types++ = type;
1747     g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1748   }
1749
1750   /* G_TYPE_PARAM_OBJECT
1751    */
1752   {
1753     const GParamSpecTypeInfo pspec_info = {
1754       sizeof (GParamSpecObject), /* instance_size */
1755       16,                        /* n_preallocs */
1756       param_object_init,         /* instance_init */
1757       G_TYPE_OBJECT,             /* value_type */
1758       NULL,                      /* finalize */
1759       param_object_set_default,  /* value_set_default */
1760       param_object_validate,     /* value_validate */
1761       param_object_values_cmp,   /* values_cmp */
1762     };
1763     type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info);
1764     set_is_valid_vfunc (type, param_object_is_valid);
1765     *spec_types++ = type;
1766     g_assert (type == G_TYPE_PARAM_OBJECT);
1767   }
1768
1769   /* G_TYPE_PARAM_OVERRIDE
1770    */
1771   {
1772     const GParamSpecTypeInfo pspec_info = {
1773       sizeof (GParamSpecOverride), /* instance_size */
1774       16,                        /* n_preallocs */
1775       param_override_init,       /* instance_init */
1776       G_TYPE_NONE,               /* value_type */
1777       param_override_finalize,   /* finalize */
1778       param_override_set_default, /* value_set_default */
1779       param_override_validate,    /* value_validate */
1780       param_override_values_cmp,  /* values_cmp */
1781     };
1782     type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info);
1783     set_is_valid_vfunc (type, param_override_is_valid);
1784     *spec_types++ = type;
1785     g_assert (type == G_TYPE_PARAM_OVERRIDE);
1786   }
1787
1788   /* G_TYPE_PARAM_GTYPE
1789    */
1790   {
1791     GParamSpecTypeInfo pspec_info = {
1792       sizeof (GParamSpecGType), /* instance_size */
1793       0,                        /* n_preallocs */
1794       param_gtype_init,         /* instance_init */
1795       0xdeadbeef,               /* value_type, assigned further down */
1796       NULL,                     /* finalize */
1797       param_gtype_set_default,  /* value_set_default */
1798       param_gtype_validate,     /* value_validate */
1799       param_gtype_values_cmp,   /* values_cmp */
1800     };
1801     pspec_info.value_type = G_TYPE_GTYPE;
1802     type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
1803     set_is_valid_vfunc (type, param_gtype_is_valid);
1804     *spec_types++ = type;
1805     g_assert (type == G_TYPE_PARAM_GTYPE);
1806   }
1807
1808   /* G_TYPE_PARAM_VARIANT
1809    */
1810   {
1811     const GParamSpecTypeInfo pspec_info = {
1812       sizeof (GParamSpecVariant), /* instance_size */
1813       0,                          /* n_preallocs */
1814       param_variant_init,         /* instance_init */
1815       G_TYPE_VARIANT,             /* value_type */
1816       param_variant_finalize,     /* finalize */
1817       param_variant_set_default,  /* value_set_default */
1818       param_variant_validate,     /* value_validate */
1819       param_variant_values_cmp,   /* values_cmp */
1820     };
1821     type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info);
1822     set_is_valid_vfunc (type, param_variant_is_valid);
1823     *spec_types++ = type;
1824     g_assert (type == G_TYPE_PARAM_VARIANT);
1825   }
1826
1827   g_assert (spec_types == spec_types_bound);
1828 }
1829
1830 /* --- GParamSpec initialization --- */
1831
1832 /**
1833  * g_param_spec_char:
1834  * @name: canonical name of the property specified
1835  * @nick: (nullable): nick name for the property specified
1836  * @blurb: (nullable): description of the property specified
1837  * @minimum: minimum value for the property specified
1838  * @maximum: maximum value for the property specified
1839  * @default_value: default value for the property specified
1840  * @flags: flags for the property specified
1841  *
1842  * Creates a new #GParamSpecChar instance specifying a %G_TYPE_CHAR property.
1843  *
1844  * Returns: (transfer full): a newly created parameter specification
1845  */
1846 GParamSpec*
1847 g_param_spec_char (const gchar *name,
1848                    const gchar *nick,
1849                    const gchar *blurb,
1850                    gint8        minimum,
1851                    gint8        maximum,
1852                    gint8        default_value,
1853                    GParamFlags  flags)
1854 {
1855   GParamSpecChar *cspec;
1856
1857   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1858
1859   cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1860                                  name,
1861                                  nick,
1862                                  blurb,
1863                                  flags);
1864   if (cspec == NULL)
1865     return NULL;
1866   
1867   cspec->minimum = minimum;
1868   cspec->maximum = maximum;
1869   cspec->default_value = default_value;
1870   
1871   return G_PARAM_SPEC (cspec);
1872 }
1873
1874 /**
1875  * g_param_spec_uchar:
1876  * @name: canonical name of the property specified
1877  * @nick: (nullable): nick name for the property specified
1878  * @blurb: (nullable): description of the property specified
1879  * @minimum: minimum value for the property specified
1880  * @maximum: maximum value for the property specified
1881  * @default_value: default value for the property specified
1882  * @flags: flags for the property specified
1883  *
1884  * Creates a new #GParamSpecUChar instance specifying a %G_TYPE_UCHAR property.
1885  *
1886  * Returns: (transfer full): a newly created parameter specification
1887  */
1888 GParamSpec*
1889 g_param_spec_uchar (const gchar *name,
1890                     const gchar *nick,
1891                     const gchar *blurb,
1892                     guint8       minimum,
1893                     guint8       maximum,
1894                     guint8       default_value,
1895                     GParamFlags  flags)
1896 {
1897   GParamSpecUChar *uspec;
1898
1899   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1900
1901   uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1902                                  name,
1903                                  nick,
1904                                  blurb,
1905                                  flags);
1906   if (uspec == NULL)
1907     return NULL;
1908   
1909   uspec->minimum = minimum;
1910   uspec->maximum = maximum;
1911   uspec->default_value = default_value;
1912   
1913   return G_PARAM_SPEC (uspec);
1914 }
1915
1916 /**
1917  * g_param_spec_boolean:
1918  * @name: canonical name of the property specified
1919  * @nick: (nullable): nick name for the property specified
1920  * @blurb: (nullable): description of the property specified
1921  * @default_value: default value for the property specified
1922  * @flags: flags for the property specified
1923  *
1924  * Creates a new #GParamSpecBoolean instance specifying a %G_TYPE_BOOLEAN
1925  * property. In many cases, it may be more appropriate to use an enum with
1926  * g_param_spec_enum(), both to improve code clarity by using explicitly named
1927  * values, and to allow for more values to be added in future without breaking
1928  * API.
1929  *
1930  * See g_param_spec_internal() for details on property names.
1931  *
1932  * Returns: (transfer full): a newly created parameter specification
1933  */
1934 GParamSpec*
1935 g_param_spec_boolean (const gchar *name,
1936                       const gchar *nick,
1937                       const gchar *blurb,
1938                       gboolean     default_value,
1939                       GParamFlags  flags)
1940 {
1941   GParamSpecBoolean *bspec;
1942
1943   g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1944
1945   bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1946                                  name,
1947                                  nick,
1948                                  blurb,
1949                                  flags);
1950   if (bspec == NULL)
1951     return NULL;
1952   
1953   bspec->default_value = default_value;
1954   
1955   return G_PARAM_SPEC (bspec);
1956 }
1957
1958 /**
1959  * g_param_spec_int:
1960  * @name: canonical name of the property specified
1961  * @nick: (nullable): nick name for the property specified
1962  * @blurb: (nullable): description of the property specified
1963  * @minimum: minimum value for the property specified
1964  * @maximum: maximum value for the property specified
1965  * @default_value: default value for the property specified
1966  * @flags: flags for the property specified
1967  *
1968  * Creates a new #GParamSpecInt instance specifying a %G_TYPE_INT property.
1969  *
1970  * See g_param_spec_internal() for details on property names.
1971  *
1972  * Returns: (transfer full): a newly created parameter specification
1973  */
1974 GParamSpec*
1975 g_param_spec_int (const gchar *name,
1976                   const gchar *nick,
1977                   const gchar *blurb,
1978                   gint         minimum,
1979                   gint         maximum,
1980                   gint         default_value,
1981                   GParamFlags  flags)
1982 {
1983   GParamSpecInt *ispec;
1984
1985   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1986
1987   ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1988                                  name,
1989                                  nick,
1990                                  blurb,
1991                                  flags);
1992   if (ispec == NULL)
1993     return NULL;
1994   
1995   ispec->minimum = minimum;
1996   ispec->maximum = maximum;
1997   ispec->default_value = default_value;
1998   
1999   return G_PARAM_SPEC (ispec);
2000 }
2001
2002 /**
2003  * g_param_spec_uint:
2004  * @name: canonical name of the property specified
2005  * @nick: (nullable): nick name for the property specified
2006  * @blurb: (nullable): description of the property specified
2007  * @minimum: minimum value for the property specified
2008  * @maximum: maximum value for the property specified
2009  * @default_value: default value for the property specified
2010  * @flags: flags for the property specified
2011  *
2012  * Creates a new #GParamSpecUInt instance specifying a %G_TYPE_UINT property.
2013  *
2014  * See g_param_spec_internal() for details on property names.
2015  *
2016  * Returns: (transfer full): a newly created parameter specification
2017  */
2018 GParamSpec*
2019 g_param_spec_uint (const gchar *name,
2020                    const gchar *nick,
2021                    const gchar *blurb,
2022                    guint        minimum,
2023                    guint        maximum,
2024                    guint        default_value,
2025                    GParamFlags  flags)
2026 {
2027   GParamSpecUInt *uspec;
2028
2029   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2030
2031   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
2032                                  name,
2033                                  nick,
2034                                  blurb,
2035                                  flags);
2036   if (uspec == NULL)
2037     return NULL;
2038   
2039   uspec->minimum = minimum;
2040   uspec->maximum = maximum;
2041   uspec->default_value = default_value;
2042   
2043   return G_PARAM_SPEC (uspec);
2044 }
2045
2046 /**
2047  * g_param_spec_long:
2048  * @name: canonical name of the property specified
2049  * @nick: (nullable): nick name for the property specified
2050  * @blurb: (nullable): description of the property specified
2051  * @minimum: minimum value for the property specified
2052  * @maximum: maximum value for the property specified
2053  * @default_value: default value for the property specified
2054  * @flags: flags for the property specified
2055  *
2056  * Creates a new #GParamSpecLong instance specifying a %G_TYPE_LONG property.
2057  *
2058  * See g_param_spec_internal() for details on property names.
2059  *
2060  * Returns: (transfer full): a newly created parameter specification
2061  */
2062 GParamSpec*
2063 g_param_spec_long (const gchar *name,
2064                    const gchar *nick,
2065                    const gchar *blurb,
2066                    glong        minimum,
2067                    glong        maximum,
2068                    glong        default_value,
2069                    GParamFlags  flags)
2070 {
2071   GParamSpecLong *lspec;
2072
2073   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2074
2075   lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
2076                                  name,
2077                                  nick,
2078                                  blurb,
2079                                  flags);
2080   if (lspec == NULL)
2081     return NULL;
2082   
2083   lspec->minimum = minimum;
2084   lspec->maximum = maximum;
2085   lspec->default_value = default_value;
2086   
2087   return G_PARAM_SPEC (lspec);
2088 }
2089
2090 /**
2091  * g_param_spec_ulong:
2092  * @name: canonical name of the property specified
2093  * @nick: (nullable): nick name for the property specified
2094  * @blurb: (nullable): description of the property specified
2095  * @minimum: minimum value for the property specified
2096  * @maximum: maximum value for the property specified
2097  * @default_value: default value for the property specified
2098  * @flags: flags for the property specified
2099  *
2100  * Creates a new #GParamSpecULong instance specifying a %G_TYPE_ULONG
2101  * property.
2102  *
2103  * See g_param_spec_internal() for details on property names.
2104  *
2105  * Returns: (transfer full): a newly created parameter specification
2106  */
2107 GParamSpec*
2108 g_param_spec_ulong (const gchar *name,
2109                     const gchar *nick,
2110                     const gchar *blurb,
2111                     gulong       minimum,
2112                     gulong       maximum,
2113                     gulong       default_value,
2114                     GParamFlags  flags)
2115 {
2116   GParamSpecULong *uspec;
2117
2118   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2119
2120   uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
2121                                  name,
2122                                  nick,
2123                                  blurb,
2124                                  flags);
2125   if (uspec == NULL)
2126     return NULL;
2127   
2128   uspec->minimum = minimum;
2129   uspec->maximum = maximum;
2130   uspec->default_value = default_value;
2131   
2132   return G_PARAM_SPEC (uspec);
2133 }
2134
2135 /**
2136  * g_param_spec_int64:
2137  * @name: canonical name of the property specified
2138  * @nick: (nullable): nick name for the property specified
2139  * @blurb: (nullable): description of the property specified
2140  * @minimum: minimum value for the property specified
2141  * @maximum: maximum value for the property specified
2142  * @default_value: default value for the property specified
2143  * @flags: flags for the property specified
2144  *
2145  * Creates a new #GParamSpecInt64 instance specifying a %G_TYPE_INT64 property.
2146  *
2147  * See g_param_spec_internal() for details on property names.
2148  *
2149  * Returns: (transfer full): a newly created parameter specification
2150  */
2151 GParamSpec*
2152 g_param_spec_int64 (const gchar *name,
2153                     const gchar *nick,
2154                     const gchar *blurb,
2155                     gint64       minimum,
2156                     gint64       maximum,
2157                     gint64       default_value,
2158                     GParamFlags  flags)
2159 {
2160   GParamSpecInt64 *lspec;
2161   
2162   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2163
2164   lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
2165                                  name,
2166                                  nick,
2167                                  blurb,
2168                                  flags);
2169   if (lspec == NULL)
2170     return NULL;
2171   
2172   lspec->minimum = minimum;
2173   lspec->maximum = maximum;
2174   lspec->default_value = default_value;
2175   
2176   return G_PARAM_SPEC (lspec);
2177 }
2178
2179 /**
2180  * g_param_spec_uint64:
2181  * @name: canonical name of the property specified
2182  * @nick: (nullable): nick name for the property specified
2183  * @blurb: (nullable): description of the property specified
2184  * @minimum: minimum value for the property specified
2185  * @maximum: maximum value for the property specified
2186  * @default_value: default value for the property specified
2187  * @flags: flags for the property specified
2188  *
2189  * Creates a new #GParamSpecUInt64 instance specifying a %G_TYPE_UINT64
2190  * property.
2191  *
2192  * See g_param_spec_internal() for details on property names.
2193  *
2194  * Returns: (transfer full): a newly created parameter specification
2195  */
2196 GParamSpec*
2197 g_param_spec_uint64 (const gchar *name,
2198                      const gchar *nick,
2199                      const gchar *blurb,
2200                      guint64      minimum,
2201                      guint64      maximum,
2202                      guint64      default_value,
2203                      GParamFlags  flags)
2204 {
2205   GParamSpecUInt64 *uspec;
2206   
2207   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2208   
2209   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
2210                                  name,
2211                                  nick,
2212                                  blurb,
2213                                  flags);
2214   if (uspec == NULL)
2215     return NULL;
2216   
2217   uspec->minimum = minimum;
2218   uspec->maximum = maximum;
2219   uspec->default_value = default_value;
2220   
2221   return G_PARAM_SPEC (uspec);
2222 }
2223
2224 /**
2225  * g_param_spec_unichar:
2226  * @name: canonical name of the property specified
2227  * @nick: (nullable): nick name for the property specified
2228  * @blurb: (nullable): description of the property specified
2229  * @default_value: default value for the property specified
2230  * @flags: flags for the property specified
2231  *
2232  * Creates a new #GParamSpecUnichar instance specifying a %G_TYPE_UINT
2233  * property. #GValue structures for this property can be accessed with
2234  * g_value_set_uint() and g_value_get_uint().
2235  *
2236  * See g_param_spec_internal() for details on property names.
2237  *
2238  * Returns: (transfer full): a newly created parameter specification
2239  */
2240 GParamSpec*
2241 g_param_spec_unichar (const gchar *name,
2242                       const gchar *nick,
2243                       const gchar *blurb,
2244                       gunichar     default_value,
2245                       GParamFlags  flags)
2246 {
2247   GParamSpecUnichar *uspec;
2248
2249   uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
2250                                  name,
2251                                  nick,
2252                                  blurb,
2253                                  flags);
2254   if (uspec == NULL)
2255     return NULL;
2256   
2257   uspec->default_value = default_value;
2258   
2259   return G_PARAM_SPEC (uspec);
2260 }
2261
2262 /**
2263  * g_param_spec_enum:
2264  * @name: canonical name of the property specified
2265  * @nick: (nullable): nick name for the property specified
2266  * @blurb: (nullable): description of the property specified
2267  * @enum_type: a #GType derived from %G_TYPE_ENUM
2268  * @default_value: default value for the property specified
2269  * @flags: flags for the property specified
2270  *
2271  * Creates a new #GParamSpecEnum instance specifying a %G_TYPE_ENUM
2272  * property.
2273  *
2274  * See g_param_spec_internal() for details on property names.
2275  *
2276  * Returns: (transfer full): a newly created parameter specification
2277  */
2278 GParamSpec*
2279 g_param_spec_enum (const gchar *name,
2280                    const gchar *nick,
2281                    const gchar *blurb,
2282                    GType        enum_type,
2283                    gint         default_value,
2284                    GParamFlags  flags)
2285 {
2286   GParamSpecEnum *espec;
2287   GEnumClass *enum_class;
2288   
2289   g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
2290
2291   enum_class = g_type_class_ref (enum_type);
2292
2293   g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
2294   
2295   espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
2296                                  name,
2297                                  nick,
2298                                  blurb,
2299                                  flags);
2300   if (espec == NULL)
2301     return NULL;
2302   
2303   espec->enum_class = enum_class;
2304   espec->default_value = default_value;
2305   G_PARAM_SPEC (espec)->value_type = enum_type;
2306   
2307   return G_PARAM_SPEC (espec);
2308 }
2309
2310 /**
2311  * g_param_spec_flags:
2312  * @name: canonical name of the property specified
2313  * @nick: (nullable): nick name for the property specified
2314  * @blurb: (nullable): description of the property specified
2315  * @flags_type: a #GType derived from %G_TYPE_FLAGS
2316  * @default_value: default value for the property specified
2317  * @flags: flags for the property specified
2318  *
2319  * Creates a new #GParamSpecFlags instance specifying a %G_TYPE_FLAGS
2320  * property.
2321  *
2322  * See g_param_spec_internal() for details on property names.
2323  *
2324  * Returns: (transfer full): a newly created parameter specification
2325  */
2326 GParamSpec*
2327 g_param_spec_flags (const gchar *name,
2328                     const gchar *nick,
2329                     const gchar *blurb,
2330                     GType        flags_type,
2331                     guint        default_value,
2332                     GParamFlags  flags)
2333 {
2334   GParamSpecFlags *fspec;
2335   GFlagsClass *flags_class;
2336   
2337   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
2338
2339   flags_class = g_type_class_ref (flags_type);
2340
2341   g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
2342   
2343   fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
2344                                  name,
2345                                  nick,
2346                                  blurb,
2347                                  flags);
2348   if (fspec == NULL)
2349     return NULL;
2350   
2351   fspec->flags_class = flags_class;
2352   fspec->default_value = default_value;
2353   G_PARAM_SPEC (fspec)->value_type = flags_type;
2354   
2355   return G_PARAM_SPEC (fspec);
2356 }
2357
2358 /**
2359  * g_param_spec_float:
2360  * @name: canonical name of the property specified
2361  * @nick: (nullable): nick name for the property specified
2362  * @blurb: (nullable): description of the property specified
2363  * @minimum: minimum value for the property specified
2364  * @maximum: maximum value for the property specified
2365  * @default_value: default value for the property specified
2366  * @flags: flags for the property specified
2367  *
2368  * Creates a new #GParamSpecFloat instance specifying a %G_TYPE_FLOAT property.
2369  *
2370  * See g_param_spec_internal() for details on property names.
2371  *
2372  * Returns: (transfer full): a newly created parameter specification
2373  */
2374 GParamSpec*
2375 g_param_spec_float (const gchar *name,
2376                     const gchar *nick,
2377                     const gchar *blurb,
2378                     gfloat       minimum,
2379                     gfloat       maximum,
2380                     gfloat       default_value,
2381                     GParamFlags  flags)
2382 {
2383   GParamSpecFloat *fspec;
2384
2385   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2386
2387   fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
2388                                  name,
2389                                  nick,
2390                                  blurb,
2391                                  flags);
2392   if (fspec == NULL)
2393     return NULL;
2394   
2395   fspec->minimum = minimum;
2396   fspec->maximum = maximum;
2397   fspec->default_value = default_value;
2398   
2399   return G_PARAM_SPEC (fspec);
2400 }
2401
2402 /**
2403  * g_param_spec_double:
2404  * @name: canonical name of the property specified
2405  * @nick: (nullable): nick name for the property specified
2406  * @blurb: (nullable): description of the property specified
2407  * @minimum: minimum value for the property specified
2408  * @maximum: maximum value for the property specified
2409  * @default_value: default value for the property specified
2410  * @flags: flags for the property specified
2411  *
2412  * Creates a new #GParamSpecDouble instance specifying a %G_TYPE_DOUBLE
2413  * property.
2414  *
2415  * See g_param_spec_internal() for details on property names.
2416  *
2417  * Returns: (transfer full): a newly created parameter specification
2418  */
2419 GParamSpec*
2420 g_param_spec_double (const gchar *name,
2421                      const gchar *nick,
2422                      const gchar *blurb,
2423                      gdouble      minimum,
2424                      gdouble      maximum,
2425                      gdouble      default_value,
2426                      GParamFlags  flags)
2427 {
2428   GParamSpecDouble *dspec;
2429
2430   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2431
2432   dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
2433                                  name,
2434                                  nick,
2435                                  blurb,
2436                                  flags);
2437   if (dspec == NULL)
2438     return NULL;
2439   
2440   dspec->minimum = minimum;
2441   dspec->maximum = maximum;
2442   dspec->default_value = default_value;
2443   
2444   return G_PARAM_SPEC (dspec);
2445 }
2446
2447 /**
2448  * g_param_spec_string:
2449  * @name: canonical name of the property specified
2450  * @nick: (nullable): nick name for the property specified
2451  * @blurb: (nullable): description of the property specified
2452  * @default_value: (nullable): default value for the property specified
2453  * @flags: flags for the property specified
2454  *
2455  * Creates a new #GParamSpecString instance.
2456  *
2457  * See g_param_spec_internal() for details on property names.
2458  *
2459  * Returns: (transfer full): a newly created parameter specification
2460  */
2461 GParamSpec*
2462 g_param_spec_string (const gchar *name,
2463                      const gchar *nick,
2464                      const gchar *blurb,
2465                      const gchar *default_value,
2466                      GParamFlags  flags)
2467 {
2468   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
2469                                                    name,
2470                                                    nick,
2471                                                    blurb,
2472                                                    flags);
2473   if (sspec == NULL)
2474     return NULL;
2475
2476   g_free (sspec->default_value);
2477   sspec->default_value = g_strdup (default_value);
2478   
2479   return G_PARAM_SPEC (sspec);
2480 }
2481
2482 /**
2483  * g_param_spec_param:
2484  * @name: canonical name of the property specified
2485  * @nick: (nullable): nick name for the property specified
2486  * @blurb: (nullable): description of the property specified
2487  * @param_type: a #GType derived from %G_TYPE_PARAM
2488  * @flags: flags for the property specified
2489  *
2490  * Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM
2491  * property.
2492  *
2493  * See g_param_spec_internal() for details on property names.
2494  *
2495  * Returns: (transfer full): a newly created parameter specification
2496  */
2497 GParamSpec*
2498 g_param_spec_param (const gchar *name,
2499                     const gchar *nick,
2500                     const gchar *blurb,
2501                     GType        param_type,
2502                     GParamFlags  flags)
2503 {
2504   GParamSpecParam *pspec;
2505   
2506   g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
2507   
2508   pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
2509                                  name,
2510                                  nick,
2511                                  blurb,
2512                                  flags);
2513   if (pspec == NULL)
2514     return NULL;
2515
2516   G_PARAM_SPEC (pspec)->value_type = param_type;
2517   
2518   return G_PARAM_SPEC (pspec);
2519 }
2520
2521 /**
2522  * g_param_spec_boxed:
2523  * @name: canonical name of the property specified
2524  * @nick: (nullable): nick name for the property specified
2525  * @blurb: (nullable): description of the property specified
2526  * @boxed_type: %G_TYPE_BOXED derived type of this property
2527  * @flags: flags for the property specified
2528  *
2529  * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_BOXED
2530  * derived property.
2531  *
2532  * See g_param_spec_internal() for details on property names.
2533  *
2534  * Returns: (transfer full): a newly created parameter specification
2535  */
2536 GParamSpec*
2537 g_param_spec_boxed (const gchar *name,
2538                     const gchar *nick,
2539                     const gchar *blurb,
2540                     GType        boxed_type,
2541                     GParamFlags  flags)
2542 {
2543   GParamSpecBoxed *bspec;
2544   
2545   g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
2546   g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
2547   
2548   bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
2549                                  name,
2550                                  nick,
2551                                  blurb,
2552                                  flags);
2553   if (bspec == NULL)
2554     return NULL;
2555
2556   G_PARAM_SPEC (bspec)->value_type = boxed_type;
2557   
2558   return G_PARAM_SPEC (bspec);
2559 }
2560
2561 /**
2562  * g_param_spec_pointer:
2563  * @name: canonical name of the property specified
2564  * @nick: (nullable): nick name for the property specified
2565  * @blurb: (nullable): description of the property specified
2566  * @flags: flags for the property specified
2567  *
2568  * Creates a new #GParamSpecPointer instance specifying a pointer property.
2569  * Where possible, it is better to use g_param_spec_object() or
2570  * g_param_spec_boxed() to expose memory management information.
2571  *
2572  * See g_param_spec_internal() for details on property names.
2573  *
2574  * Returns: (transfer full): a newly created parameter specification
2575  */
2576 GParamSpec*
2577 g_param_spec_pointer (const gchar *name,
2578                       const gchar *nick,
2579                       const gchar *blurb,
2580                       GParamFlags  flags)
2581 {
2582   GParamSpecPointer *pspec;
2583   
2584   pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
2585                                  name,
2586                                  nick,
2587                                  blurb,
2588                                  flags);
2589   if (pspec == NULL)
2590     return NULL;
2591
2592   return G_PARAM_SPEC (pspec);
2593 }
2594
2595 /**
2596  * g_param_spec_gtype:
2597  * @name: canonical name of the property specified
2598  * @nick: (nullable): nick name for the property specified
2599  * @blurb: (nullable): description of the property specified
2600  * @is_a_type: a #GType whose subtypes are allowed as values
2601  *  of the property (use %G_TYPE_NONE for any type)
2602  * @flags: flags for the property specified
2603  *
2604  * Creates a new #GParamSpecGType instance specifying a
2605  * %G_TYPE_GTYPE property.
2606  *
2607  * See g_param_spec_internal() for details on property names.
2608  *
2609  * Since: 2.10
2610  *
2611  * Returns: (transfer full): a newly created parameter specification
2612  */
2613 GParamSpec*
2614 g_param_spec_gtype (const gchar *name,
2615                     const gchar *nick,
2616                     const gchar *blurb,
2617                     GType        is_a_type,
2618                     GParamFlags  flags)
2619 {
2620   GParamSpecGType *tspec;
2621   
2622   tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
2623                                  name,
2624                                  nick,
2625                                  blurb,
2626                                  flags);
2627   if (tspec == NULL)
2628     return NULL;
2629
2630   tspec->is_a_type = is_a_type;
2631
2632   return G_PARAM_SPEC (tspec);
2633 }
2634
2635 /**
2636  * g_param_spec_value_array: (skip)
2637  * @name: canonical name of the property specified
2638  * @nick: (nullable): nick name for the property specified
2639  * @blurb: (nullable): description of the property specified
2640  * @element_spec: a #GParamSpec describing the elements contained in
2641  *  arrays of this property, may be %NULL
2642  * @flags: flags for the property specified
2643  *
2644  * Creates a new #GParamSpecValueArray instance specifying a
2645  * %G_TYPE_VALUE_ARRAY property. %G_TYPE_VALUE_ARRAY is a
2646  * %G_TYPE_BOXED type, as such, #GValue structures for this property
2647  * can be accessed with g_value_set_boxed() and g_value_get_boxed().
2648  *
2649  * See g_param_spec_internal() for details on property names.
2650  *
2651  * Returns: a newly created parameter specification
2652  */
2653 GParamSpec*
2654 g_param_spec_value_array (const gchar *name,
2655                           const gchar *nick,
2656                           const gchar *blurb,
2657                           GParamSpec  *element_spec,
2658                           GParamFlags  flags)
2659 {
2660   GParamSpecValueArray *aspec;
2661   
2662   g_return_val_if_fail (element_spec == NULL || G_IS_PARAM_SPEC (element_spec), NULL);
2663   
2664   aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
2665                                  name,
2666                                  nick,
2667                                  blurb,
2668                                  flags);
2669   if (aspec == NULL)
2670     return NULL;
2671
2672   if (element_spec)
2673     {
2674       aspec->element_spec = g_param_spec_ref (element_spec);
2675       g_param_spec_sink (element_spec);
2676     }
2677
2678   return G_PARAM_SPEC (aspec);
2679 }
2680
2681 /**
2682  * g_param_spec_object:
2683  * @name: canonical name of the property specified
2684  * @nick: (nullable): nick name for the property specified
2685  * @blurb: (nullable): description of the property specified
2686  * @object_type: %G_TYPE_OBJECT derived type of this property
2687  * @flags: flags for the property specified
2688  *
2689  * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT
2690  * derived property.
2691  *
2692  * See g_param_spec_internal() for details on property names.
2693  *
2694  * Returns: (transfer full): a newly created parameter specification
2695  */
2696 GParamSpec*
2697 g_param_spec_object (const gchar *name,
2698                      const gchar *nick,
2699                      const gchar *blurb,
2700                      GType        object_type,
2701                      GParamFlags  flags)
2702 {
2703   GParamSpecObject *ospec;
2704   
2705   g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
2706   
2707   ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
2708                                  name,
2709                                  nick,
2710                                  blurb,
2711                                  flags);
2712   if (ospec == NULL)
2713     return NULL;
2714
2715   G_PARAM_SPEC (ospec)->value_type = object_type;
2716   
2717   return G_PARAM_SPEC (ospec);
2718 }
2719
2720 /**
2721  * g_param_spec_override: (skip)
2722  * @name: the name of the property.
2723  * @overridden: The property that is being overridden
2724  *
2725  * Creates a new property of type #GParamSpecOverride. This is used
2726  * to direct operations to another paramspec, and will not be directly
2727  * useful unless you are implementing a new base type similar to GObject.
2728  *
2729  * Since: 2.4
2730  *
2731  * Returns: the newly created #GParamSpec
2732  */
2733 GParamSpec*
2734 g_param_spec_override (const gchar *name,
2735                        GParamSpec  *overridden)
2736 {
2737   GParamSpec *pspec;
2738   
2739   g_return_val_if_fail (name != NULL, NULL);
2740   g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL);
2741   
2742   /* Dereference further redirections for property that was passed in
2743    */
2744   while (TRUE)
2745     {
2746       GParamSpec *indirect = g_param_spec_get_redirect_target (overridden);
2747       if (indirect)
2748         overridden = indirect;
2749       else
2750         break;
2751     }
2752
2753   pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE,
2754                                  name, NULL, NULL,
2755                                  overridden->flags);
2756   if (pspec == NULL)
2757     return NULL;
2758   
2759   pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden);
2760   G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden);
2761
2762   return pspec;
2763 }
2764
2765 /**
2766  * g_param_spec_variant:
2767  * @name: canonical name of the property specified
2768  * @nick: (nullable): nick name for the property specified
2769  * @blurb: (nullable): description of the property specified
2770  * @type: a #GVariantType
2771  * @default_value: (nullable) (transfer full): a #GVariant of type @type to
2772  *                 use as the default value, or %NULL
2773  * @flags: flags for the property specified
2774  *
2775  * Creates a new #GParamSpecVariant instance specifying a #GVariant
2776  * property.
2777  *
2778  * If @default_value is floating, it is consumed.
2779  *
2780  * See g_param_spec_internal() for details on property names.
2781  *
2782  * Returns: (transfer full): the newly created #GParamSpec
2783  *
2784  * Since: 2.26
2785  */
2786 GParamSpec*
2787 g_param_spec_variant (const gchar        *name,
2788                       const gchar        *nick,
2789                       const gchar        *blurb,
2790                       const GVariantType *type,
2791                       GVariant           *default_value,
2792                       GParamFlags         flags)
2793 {
2794   GParamSpecVariant *vspec;
2795
2796   g_return_val_if_fail (type != NULL, NULL);
2797   g_return_val_if_fail (default_value == NULL ||
2798                         g_variant_is_of_type (default_value, type), NULL);
2799
2800   vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT,
2801                                  name,
2802                                  nick,
2803                                  blurb,
2804                                  flags);
2805   if (vspec == NULL)
2806     return NULL;
2807
2808   vspec->type = g_variant_type_copy (type);
2809   if (default_value)
2810     vspec->default_value = g_variant_ref_sink (default_value);
2811
2812   return G_PARAM_SPEC (vspec);
2813 }