Prevent compiler warnings about unused parameters.
[synfig.git] / synfig-core / trunk / src / synfig / value.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file value.h
3 **      \brief Template Header
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_VALUE_H
26 #define __SYNFIG_VALUE_H
27
28 /* === H E A D E R S ======================================================= */
29
30 //#include "vector.h"
31 //#include "time.h"
32 #include "segment.h"
33 //#include "color.h"
34 #include "string.h"
35 #include <list>
36 #include <vector>
37 #include <ETL/trivial>
38 #include <ETL/handle>
39 #include "general.h"
40 //#include "gradient.h"
41 #include "blinepoint.h"
42 #include "exception.h"
43
44 #ifdef USE_HALF_TYPE
45 #include <OpenEXR/half.h>
46 #endif
47
48 #ifndef SYNFIG_NO_ANGLE
49 #include "angle.h"
50 #endif
51
52 #include <ETL/ref_count>
53
54 /* === M A C R O S ========================================================= */
55
56 /* === T Y P E D E F S ===================================================== */
57
58 /* === C L A S S E S & S T R U C T S ======================================= */
59
60 namespace synfig {
61
62 class Canvas;
63 class Vector;
64 class Time;
65 class Segment;
66 class Gradient;
67 class BLinePoint;
68 class Color;
69
70 /*!     \class ValueBase
71 **      \todo writeme
72 */
73 class ValueBase
74 {
75         /*
76  --     ** -- T Y P E S -----------------------------------------------------------
77         */
78
79 public:
80
81         //! \writeme
82         enum Type
83         {
84                 TYPE_NIL=0,                     //!< Represents an empty value
85
86                 TYPE_BOOL,
87                 TYPE_INTEGER,
88                 TYPE_ANGLE,                     //!< Angle
89
90                 // All types after this point are larger than 32 bits
91
92                 TYPE_TIME,                      //!< Time
93                 TYPE_REAL,                      //!< Real
94
95                 // All types after this point are larger than 64 bits
96
97                 TYPE_VECTOR,            //!< Vector
98                 TYPE_COLOR,                     //!< Color
99                 TYPE_SEGMENT,           //!< Segment
100                 TYPE_BLINEPOINT,        //!< BLinePoint
101
102                 // All types after this point require construction/destruction
103
104                 TYPE_LIST,                      //!< List
105                 TYPE_CANVAS,            //!< Canvas
106                 TYPE_STRING,            //!< String
107                 TYPE_GRADIENT,          //!< Color Gradient
108
109                 TYPE_END                        //!< Not a valid type, used for sanity checks
110         };
111
112 private:
113
114         typedef std::vector<ValueBase> list_type;
115
116         /*
117  --     ** -- D A T A -------------------------------------------------------------
118         */
119
120 protected:
121
122         Type type;
123         void *data;
124         etl::reference_counter ref_count;
125         bool loop_;
126
127         /*
128  --     ** -- C O N S T R U C T O R S -----------------------------------
129         */
130
131 public:
132
133         //! \writeme
134         ValueBase();
135
136         //! \writeme
137         template <typename T>
138         ValueBase(const T &x, bool loop_=false):
139                 type(TYPE_NIL),data(0),ref_count(0),loop_(loop_)
140                 { set(x); }
141
142         //! \writeme
143         ValueBase(Type x);
144
145         //! \writeme
146         ~ValueBase();
147
148         /*
149  --     ** -- O P E R A T O R S ---------------------------------------------------
150         */
151
152 public:
153
154         //! \writeme
155         template <class T> ValueBase& operator=(const T& x)
156                 { set(x); return *this; }
157
158         //! \writeme
159         ValueBase& operator=(const ValueBase& x);
160
161         //! \writeme
162         bool operator==(const ValueBase& rhs)const;
163
164         //! \writeme
165         bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
166
167         //!     Constant index operator for when value is of type TYPE_LIST
168         const ValueBase &operator[](int index)const
169                 { assert(type==TYPE_LIST); assert(index>0); return get_list()[index]; }
170
171         /*
172  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
173         */
174
175 public:
176
177         //! \writeme
178         void clear();
179
180         //! \writeme
181         bool get_loop()const { return loop_; }
182
183         //! \writeme
184         void set_loop(bool x) { loop_=x; }
185
186         //! \writeme
187         bool empty()const;
188
189         //! \writeme
190         Type get_contained_type()const;
191
192         //! Returns true if the contained value is defined and valid.
193         bool is_valid()const;
194
195         //!     Returns a string containing the name of the type
196         String type_name()const { return type_name(type); }
197
198         //! Returns the type of the contained value
199         const Type & get_type()const { return type; }
200
201         //! Checks the type of the parameter against itself. Returns true if they are of the same type.
202         template <class T> bool
203         same_type_as(const T &x)const
204         {
205                 const Type testtype(get_type(x));
206
207                 return same_type_as(testtype);
208         }
209
210         bool same_type_as(const Type testtype)const
211         {
212                 if(testtype==type)return true;
213                 if(     (type==TYPE_REAL || type==TYPE_TIME) &&
214                         (testtype==TYPE_REAL || testtype==TYPE_TIME) )
215                         return true;
216                 return false;
217         }
218
219
220         // === GET MEMBERS ========================================================
221         template <typename T>
222         const T &get(const T& x)const
223         {
224                 assert(is_valid() && same_type_as(x));
225                 return *static_cast<const T*>(data);
226         }
227         float get(const float &)const { return get(Real()); }
228         etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
229                 { return get(etl::loose_handle<Canvas>()); }
230         etl::loose_handle<Canvas> get(Canvas*)const
231                 { return get(etl::loose_handle<Canvas>()); }
232         const char* get(const char*)const;
233         const list_type& get_list()const { return get(list_type()); }
234         // ========================================================================
235
236
237
238         // === PUT MEMBERS ========================================================
239         template <typename T>
240         void put(T* x)const
241         {
242                 assert(same_type_as(*x));
243                 *x=*static_cast<const T*>(data);
244         }
245         void put(float* x)const { *x=get(Real()); }
246         void put(char** x)const;
247         // ========================================================================
248
249
250
251         // === SET MEMBERS ========================================================
252         template <typename T> void set(const T& x) { _set(x); }
253         void set(const float &x) { _set(Real(x)); }
254         void set(const list_type &x);
255         void set(const char* x);
256         void set(Canvas*x);
257         void set(etl::loose_handle<Canvas> x);
258         void set(etl::handle<Canvas> x);
259         template <class T> void set(const std::vector<T> &x)
260                 { _set(list_type(x.begin(),x.end())); }
261         template <class T> void set(const std::list<T> &x)
262                 { _set(list_type(x.begin(),x.end())); }
263         // ========================================================================
264
265
266         /*
267  --     ** -- S T A T I C   F U N C T I O N S -------------------------------------
268         */
269
270 public:
271
272         //!     Returns a string containing the name of the given Type
273         static String type_name(Type id);
274
275         //!     Returns a the corresponding Type of the described type
276         static Type ident_type(const String &str);
277
278
279         // === GET TYPE MEMBERS ===================================================
280         static const Type get_type(bool) { return TYPE_BOOL; }
281         static const Type get_type(int) { return TYPE_INTEGER; }
282         static const Type get_type(const Time&) { return TYPE_TIME; }
283         static const Type get_type(const Real&) { return TYPE_REAL; }
284         static const Type get_type(const float&) { return TYPE_REAL; }
285         static const Type get_type(const Vector&) { return TYPE_VECTOR; }
286         static const Type get_type(const Color&) { return TYPE_COLOR; }
287         static const Type get_type(const Segment&) { return TYPE_SEGMENT; }
288         static const Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
289         static const Type get_type(const String&) { return TYPE_STRING; }
290         static const Type get_type(const Gradient&) { return TYPE_GRADIENT; }
291         static const Type get_type(Canvas*) { return TYPE_CANVAS; }
292         static const Type get_type(const etl::handle<Canvas>&)
293                 { return TYPE_CANVAS; }
294         static const Type get_type(const etl::loose_handle<Canvas>&)
295                 { return TYPE_CANVAS; }
296         static const Type get_type(const list_type&) { return TYPE_LIST; }
297         template <class T> static const Type get_type(const std::vector<T> &/*x*/)
298                 { return TYPE_LIST; }
299         template <class T> static const Type get_type(const std::list<T> &/*x*/)
300                 { return TYPE_LIST; }
301         // ========================================================================
302
303
304         /*
305  --     ** -- C A S T   O P E R A T O R S -----------------------------------------
306         */
307
308 public:
309
310         operator const list_type&()const { return get_list(); }
311         //operator const Color&()const { return get(Color()); }
312         //operator const Real&()const { return get(Real()); }
313         //operator const Time&()const { return get(Time()); }
314
315         operator const Vector&()const {  return get(Vector()); }
316         operator const BLinePoint&()const {  return get(BLinePoint()); }
317         //operator const int&()const {  return get(int()); }
318         //operator const String&()const {  return get(String()); }
319         //operator const char *()const {  return get(String()).c_str(); }
320         operator const Segment&()const { return get(Segment()); }
321
322
323         /*
324  --     ** -- O T H E R -----------------------------------------------------------
325         */
326
327 public:
328
329 #ifdef USE_HALF_TYPE
330         half get(const half &)const { return get(Real()); }
331         void put(half*x)const { *x=get(Real()); }
332         void set(const half &x) { _set(Real(x)); }
333         static const Type get_type(const half&) { return TYPE_REAL; }
334         operator half()const { return get(Real()); }
335 #endif
336
337 #ifndef SYNFIG_NO_ANGLE
338         operator const Angle&()const { return get(Angle()); }
339         static const Type get_type(const Angle&) { return TYPE_ANGLE; }
340 #endif
341
342         template <class T>
343         operator std::list<T>()const
344         {
345                 assert(type==TYPE_LIST);
346                 std::list<T> ret(get_list().begin(),get_list().end());
347                 return ret;
348         }
349         template <class T>
350         operator std::vector<T>()const
351         {
352                 assert(type==TYPE_LIST);
353                 std::vector<T> ret(get_list().begin(),get_list().end());
354                 return ret;
355         }
356
357
358 private:
359
360         template <typename T> void
361         _set(const T& x)
362         {
363                 const Type newtype(get_type(x));
364
365                 assert(newtype!=TYPE_NIL);
366
367                 if(newtype==type)
368                 {
369                         if(ref_count.unique())
370                         {
371                                 *reinterpret_cast<T*>(data)=x;
372                                 return;
373                         }
374                 }
375
376                 clear();
377
378                 type=newtype;
379                 ref_count.reset();
380                 data=new T(x);
381         }
382 }; // END of class ValueBase
383
384
385 /*!     \class Value
386 **      \todo writeme
387 */
388 template <class T>
389 class Value : public ValueBase
390 {
391 public:
392         Value(const T &x):ValueBase(x)
393         {
394         }
395
396         Value(const ValueBase &x):ValueBase(x)
397         {
398                 if(!x.same_type_as(T()))
399                         throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
400         }
401
402         Value()
403         {
404         }
405
406         T get()const { return ValueBase::get(T()); }
407
408         void put(T* x)const     { ValueBase::put(x); }
409
410         void set(const T& x) { ValueBase::operator=(x); }
411
412         Value<T>& operator=(const T& x) { set(x); return *this; }
413
414         Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
415
416         Value<T>& operator=(const ValueBase& x)
417         {
418                 if(!x.same_type_as(T()))
419                         throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
420                 return ValueBase::operator=(x);
421         }
422
423 }; // END of class Value
424
425 /*
426 template <>
427 class Value< std::list<CT> > : public ValueBase
428 {
429 public:
430         Value(const T &x):ValueBase(x)
431         {
432         }
433         Value(const ValueBase &x):ValueBase(x)
434         {
435                 if(!x.same_type_as(T()))
436                         throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
437         }
438         Value()
439         {
440         }
441
442         T get()const { return ValueBase::get(T()); }
443
444         void put(T* x)const     { ValueBase::put(x); }
445
446         void set(const T& x) { ValueBase::operator=(x); }
447
448         Value<T>& operator=(const T& x) { set(x); return *this; }
449
450         Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
451
452         Value<T>& operator=(const ValueBase& x)
453         {
454                 if(!x.same_type_as(T()))
455                         throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
456                 return ValueBase::operator=(x);
457         }
458
459 }; // END of class Value
460 */
461
462 }; // END of namespace synfig
463
464 /* === E N D =============================================================== */
465
466 #endif