More gracefully handle type mismatch errors when doing playlist things (just ignore...
[ardour.git] / libs / glibmm2 / glib / glibmm / value.h
1 // -*- c++ -*-
2 #ifndef _GLIBMM_VALUE_H
3 #define _GLIBMM_VALUE_H
4 /* $Id: value.h 292 2006-05-14 12:12:41Z murrayc $ */
5
6 /* Copyright 2002 The gtkmm Development Team
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include <glib-object.h>
24 #include <glibmm/refptr.h>
25 #include <glibmm/ustring.h>
26
27
28 namespace Glib
29 {
30
31 class ObjectBase;
32 class Object;
33
34 /** @defgroup glibmmValue Generic Values
35  *
36  * Glib::Value<> is specialized for almost any type used within
37  * the glibmm and gtkmm libraries.
38  *
39  * - Basic types like <tt>int</tt>, <tt>char</tt>, <tt>bool</tt>, etc., also <tt>void*</tt>.
40  * - Glib::ustring and std::string.
41  * - Pointers to classes derived from Glib::Object.
42  * - Glib::RefPtr<> pointer types, which are assumed to be Glib::Object pointers.
43  * - All flags and enum types used within the gtkmm libraries.
44  *
45  * If a type doesn't fit into any of these categories, then a generic
46  * implementation for custom types will be used.  The requirements imposed
47  * on custom types are described in the Glib::Value class documentation.
48  */
49
50 /**
51  * @ingroup glibmmValue
52  */
53 class ValueBase
54 {
55 public:
56   /** Initializes the GValue, but without a type.  You have to
57    * call init() before using the set(), get(), or reset() methods.
58    */
59   ValueBase();
60
61   ValueBase(const ValueBase& other);
62   ValueBase& operator=(const ValueBase& other);
63
64   ~ValueBase();
65
66   /** Setup the GValue for storing the specified @a type.
67    * The contents will be initialized to the default value for this type.
68    * Note that init() should never be called twice.
69    *
70    * init() is not implemented as constructor, to avoid the necessity
71    * to implement a forward constructor in each derived class.
72    *
73    * @param type The type that the Value should hold.
74    */
75   void init(GType type);
76
77   /** Setup the GValue storing the type and value of the specified @a value.
78    * Note that init() should never be called twice.
79    *
80    * init() is not implemented as constructor, to avoid the necessity
81    * to implement a forward constructor in each derived class.
82    *
83    * @param value The existing GValue.
84    */
85   void init(const GValue* value);
86
87   /** Reset contents to the default value of its type.
88    */
89   void reset();
90
91   GValue*       gobj()       { return &gobject_; }
92   const GValue* gobj() const { return &gobject_; }
93
94 protected:
95   GValue gobject_;
96 };
97
98 /**
99  * @ingroup glibmmValue
100  */
101 class ValueBase_Boxed : public ValueBase
102 {
103 public:
104   static GType value_type() G_GNUC_CONST;
105
106 #ifndef DOXYGEN_SHOULD_SKIP_THIS
107   GParamSpec* create_param_spec(const Glib::ustring& name) const;
108 #endif
109
110 protected:
111   void  set_boxed(const void* data);
112   void* get_boxed() const; // doesn't copy  
113 };
114
115
116 /**
117  * @ingroup glibmmValue
118  */
119 class ValueBase_Object : public ValueBase
120 {
121 public:
122   static GType value_type() G_GNUC_CONST;
123
124 #ifndef DOXYGEN_SHOULD_SKIP_THIS
125   GParamSpec* create_param_spec(const Glib::ustring& name) const;
126 #endif
127
128 protected:
129   void set_object(Glib::ObjectBase* data);
130   Glib::ObjectBase* get_object() const;
131   Glib::RefPtr<Glib::ObjectBase> get_object_copy() const;
132 };
133
134
135 /**
136  * @ingroup glibmmValue
137  */
138 class ValueBase_Enum : public ValueBase
139 {
140 public:
141   typedef gint CType;
142   static GType value_type() G_GNUC_CONST;
143
144 #ifndef DOXYGEN_SHOULD_SKIP_THIS
145   GParamSpec* create_param_spec(const Glib::ustring& name) const;
146 #endif
147
148 protected:
149   void set_enum(int data);
150   int  get_enum() const;
151 };
152
153
154 /**
155  * @ingroup glibmmValue
156  */
157 class ValueBase_Flags : public ValueBase
158 {
159 public:
160   typedef guint CType;
161   static GType value_type() G_GNUC_CONST;
162
163 #ifndef DOXYGEN_SHOULD_SKIP_THIS
164   GParamSpec* create_param_spec(const Glib::ustring& name) const;
165 #endif
166
167 protected:
168   void set_flags(unsigned int data);
169   unsigned int get_flags() const;
170 };
171
172
173 /**
174  * @ingroup glibmmValue
175  */
176 class ValueBase_String : public ValueBase
177 {
178 public:
179   typedef const gchar* CType;
180   static GType value_type() G_GNUC_CONST;
181
182 #ifndef DOXYGEN_SHOULD_SKIP_THIS
183   GParamSpec* create_param_spec(const Glib::ustring& name) const;
184 #endif
185
186 protected:
187   void set_cstring(const char* data);
188   const char* get_cstring() const; // never returns 0
189 };
190
191 } // namespace Glib
192
193
194 /* Include generic Glib::Value<> template, before any specializations:
195  */
196 #define _GLIBMM_VALUE_H_INCLUDE_VALUE_CUSTOM_H
197 #include <glibmm/value_custom.h>
198 #undef _GLIBMM_VALUE_H_INCLUDE_VALUE_CUSTOM_H
199
200
201 namespace Glib
202 {
203
204 /**
205  * @ingroup glibmmValue
206  */
207 template <class T>
208 class Value_Boxed : public ValueBase_Boxed
209 {
210 public:
211   typedef T                           CppType;
212   typedef typename T::BaseObjectType* CType;
213
214   static GType value_type() { return T::get_type(); }
215
216   void set(const CppType& data) { set_boxed(data.gobj()); }
217   CppType get() const           { return CppType(static_cast<CType>(get_boxed())); }
218 };
219
220 //More spec-compliant compilers (such as Tru64) need this to be near Glib::Object instead.
221 #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
222
223 /** Partial specialization for RefPtr<> to Glib::Object.
224  * @ingroup glibmmValue
225  */
226 template <class T>
227 class Value< Glib::RefPtr<T> > : public ValueBase_Object
228 {
229 public:
230   typedef Glib::RefPtr<T>             CppType;
231   typedef typename T::BaseObjectType* CType;
232
233   static GType value_type() { return T::get_base_type(); }
234
235   void set(const CppType& data) { set_object(data.operator->()); }
236   CppType get() const           { return Glib::RefPtr<T>::cast_dynamic(get_object_copy()); }
237 };
238
239 //The SUN Forte Compiler has a problem with this: 
240 #ifdef GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
241
242 /** Partial specialization for RefPtr<> to const Glib::Object.
243  * @ingroup glibmmValue
244  */
245 template <class T>
246 class Value< Glib::RefPtr<const T> > : public ValueBase_Object
247 {
248 public:
249   typedef Glib::RefPtr<const T>       CppType;
250   typedef typename T::BaseObjectType* CType;
251
252   static GType value_type() { return T::get_base_type(); }
253
254   void set(const CppType& data) { set_object(const_cast<T*>(data.operator->())); }
255   CppType get() const           { return Glib::RefPtr<T>::cast_dynamic(get_object_copy()); }
256 };
257 #endif //GLIBMM_HAVE_DISAMBIGUOUS_CONST_TEMPLATE_SPECIALIZATIONS
258
259 #endif //GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
260
261 } // namespace Glib
262
263
264 /* Include generated specializations of Glib::Value<> for fundamental types:
265  */
266 #define _GLIBMM_VALUE_H_INCLUDE_VALUE_BASICTYPES_H
267 #include <glibmm/value_basictypes.h>
268 #undef _GLIBMM_VALUE_H_INCLUDE_VALUE_BASICTYPES_H
269
270
271 namespace Glib
272 {
273
274 /** Specialization for strings.
275  * @ingroup glibmmValue
276  */
277 template <>
278 class Value<std::string> : public ValueBase_String
279 {
280 public:
281   typedef std::string CppType;
282
283   void set(const std::string& data);
284   std::string get() const { return get_cstring(); }
285 };
286
287 /** Specialization for UTF-8 strings.
288  * @ingroup glibmmValue
289  */
290 template <>
291 class Value<Glib::ustring> : public ValueBase_String
292 {
293 public:
294   typedef Glib::ustring CppType;
295
296   void set(const Glib::ustring& data);
297   Glib::ustring get() const { return get_cstring(); }
298 };
299
300
301 /** Base class of Glib::Value<T> specializations for enum types.
302  * @ingroup glibmmValue
303  */
304 template <class T>
305 class Value_Enum : public ValueBase_Enum
306 {
307 public:
308   typedef T CppType;
309
310   void set(CppType data) { set_enum(data); }
311   CppType get() const    { return CppType(get_enum()); }
312 };
313
314 /** Base class of Glib::Value<T> specializations for flags types.
315  * @ingroup glibmmValue
316  */
317 template <class T>
318 class Value_Flags : public ValueBase_Flags
319 {
320 public:
321   typedef T CppType;
322
323   void set(CppType data) { set_flags(data); }
324   CppType get() const    { return CppType(get_flags()); }
325 };
326
327 } // namespace Glib
328
329
330 #endif /* _GLIBMM_VALUE_H */
331