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