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