1 /* === S Y N F I G ========================================================= */
3 ** \brief Template Header
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === S T A R T =========================================================== */
26 #ifndef __SYNFIG_VALUE_H
27 #define __SYNFIG_VALUE_H
29 /* === H E A D E R S ======================================================= */
38 #include <ETL/trivial>
41 //#include "gradient.h"
42 #include "blinepoint.h"
43 #include "exception.h"
46 #include <OpenEXR/half.h>
49 #ifndef SYNFIG_NO_ANGLE
53 #include <ETL/ref_count>
55 /* === M A C R O S ========================================================= */
57 /* === T Y P E D E F S ===================================================== */
59 /* === C L A S S E S & S T R U C T S ======================================= */
77 -- ** -- T Y P E S -----------------------------------------------------------
85 TYPE_NIL=0, //!< Represents an empty value
89 TYPE_ANGLE, //!< Angle
91 // All types after this point are larger than 32 bits
96 // All types after this point are larger than 64 bits
98 TYPE_VECTOR, //!< Vector
99 TYPE_COLOR, //!< Color
100 TYPE_SEGMENT, //!< Segment
101 TYPE_BLINEPOINT, //!< BLinePoint
103 // All types after this point require construction/destruction
106 TYPE_CANVAS, //!< Canvas
107 TYPE_STRING, //!< String
108 TYPE_GRADIENT, //!< Color Gradient
110 TYPE_END //!< Not a valid type, used for sanity checks
115 typedef std::vector<ValueBase> list_type;
118 -- ** -- D A T A -------------------------------------------------------------
125 etl::reference_counter ref_count;
129 -- ** -- C O N S T R U C T O R S -----------------------------------
138 template <typename T>
139 ValueBase(const T &x, bool loop_=false):
140 type(TYPE_NIL),data(0),ref_count(0),loop_(loop_)
150 -- ** -- O P E R A T O R S ---------------------------------------------------
156 template <class T> ValueBase& operator=(const T& x)
157 { set(x); return *this; }
160 ValueBase& operator=(const ValueBase& x);
163 bool operator==(const ValueBase& rhs)const;
166 bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
168 //! Constant index operator for when value is of type TYPE_LIST
169 const ValueBase &operator[](int index)const
170 { assert(type==TYPE_LIST); assert(index>0); return get_list()[index]; }
173 -- ** -- M E M B E R F U N C T I O N S -------------------------------------
182 bool get_loop()const { return loop_; }
185 void set_loop(bool x) { loop_=x; }
191 Type get_contained_type()const;
193 //! Returns true if the contained value is defined and valid.
194 bool is_valid()const;
196 //! Returns a string containing the name of the type
197 String type_name()const { return type_name(type); }
199 //! Returns the type of the contained value
200 const Type & get_type()const { return type; }
202 //! Checks the type of the parameter against itself. Returns true if they are of the same type.
203 template <class T> bool
204 same_type_as(const T &x)const
206 const Type testtype(get_type(x));
208 return same_type_as(type, testtype);
211 bool same_type_as(const Type testtype)const
213 return same_type_as(type, testtype);
216 //! Compares two types. Returns true if they are the same type.
217 static bool same_type_as(const Type type1, const Type type2)
219 if (type1 == type2) return true;
220 if ((type1 == TYPE_REAL || type1 == TYPE_TIME) &&
221 (type2 == TYPE_REAL || type2 == TYPE_TIME))
227 // === GET MEMBERS ========================================================
228 template <typename T>
229 const T &get(const T& x __attribute__ ((unused)))const
231 assert(is_valid() && same_type_as(x));
232 return *static_cast<const T*>(data);
234 float get(const float &)const { return get(Real()); }
235 etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
236 { return get(etl::loose_handle<Canvas>()); }
237 etl::loose_handle<Canvas> get(Canvas*)const
238 { return get(etl::loose_handle<Canvas>()); }
239 const char* get(const char*)const;
240 const list_type& get_list()const { return get(list_type()); }
243 String get_string() const;
245 // ========================================================================
249 // === PUT MEMBERS ========================================================
250 template <typename T>
253 assert(same_type_as(*x));
254 *x=*static_cast<const T*>(data);
256 void put(float* x)const { *x=get(Real()); }
257 void put(char** x)const;
258 // ========================================================================
262 // === SET MEMBERS ========================================================
263 template <typename T> void set(const T& x) { _set(x); }
264 void set(const float &x) { _set(Real(x)); }
265 void set(const list_type &x);
266 void set(const char* x);
269 void set(etl::loose_handle<Canvas> x);
270 void set(etl::handle<Canvas> x);
271 template <class T> void set(const std::vector<T> &x)
272 { _set(list_type(x.begin(),x.end())); }
273 template <class T> void set(const std::list<T> &x)
274 { _set(list_type(x.begin(),x.end())); }
275 // ========================================================================
279 -- ** -- S T A T I C F U N C T I O N S -------------------------------------
284 //! Returns a string containing the name of the given Type
285 static String type_name(Type id);
287 //! Returns a string containing the translated name of the given Type
288 static String type_local_name(Type id);
290 //! Returns a the corresponding Type of the described type
291 static Type ident_type(const String &str);
294 // === GET TYPE MEMBERS ===================================================
295 static Type get_type(bool) { return TYPE_BOOL; }
296 static Type get_type(int) { return TYPE_INTEGER; }
297 static Type get_type(const Time&) { return TYPE_TIME; }
298 static Type get_type(const Real&) { return TYPE_REAL; }
299 static Type get_type(const float&) { return TYPE_REAL; }
300 static Type get_type(const Vector&) { return TYPE_VECTOR; }
301 static Type get_type(const Color&) { return TYPE_COLOR; }
302 static Type get_type(const Segment&) { return TYPE_SEGMENT; }
303 static Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
304 static Type get_type(const String&) { return TYPE_STRING; }
305 static Type get_type(const Gradient&) { return TYPE_GRADIENT; }
306 static Type get_type(Canvas*) { return TYPE_CANVAS; }
307 static Type get_type(const etl::handle<Canvas>&)
308 { return TYPE_CANVAS; }
309 static Type get_type(const etl::loose_handle<Canvas>&)
310 { return TYPE_CANVAS; }
311 static Type get_type(const list_type&) { return TYPE_LIST; }
312 template <class T> static Type get_type(const std::vector<T> &/*x*/)
313 { return TYPE_LIST; }
314 template <class T> static Type get_type(const std::list<T> &/*x*/)
315 { return TYPE_LIST; }
316 // ========================================================================
320 -- ** -- C A S T O P E R A T O R S -----------------------------------------
325 operator const list_type&()const { return get_list(); }
326 //operator const Color&()const { return get(Color()); }
327 operator const Real&()const { return get(Real()); }
328 //operator const Time&()const { return get(Time()); }
330 operator const Vector&()const { return get(Vector()); }
331 operator const BLinePoint&()const { return get(BLinePoint()); }
332 //operator const int&()const { return get(int()); }
333 //operator const String&()const { return get(String()); }
334 //operator const char *()const { return get(String()).c_str(); }
335 operator const Segment&()const { return get(Segment()); }
339 -- ** -- O T H E R -----------------------------------------------------------
345 half get(const half &)const { return get(Real()); }
346 void put(half*x)const { *x=get(Real()); }
347 void set(const half &x) { _set(Real(x)); }
348 static Type get_type(const half&) { return TYPE_REAL; }
349 operator half()const { return get(Real()); }
352 #ifndef SYNFIG_NO_ANGLE
353 operator const Angle&()const { return get(Angle()); }
354 static Type get_type(const Angle&) { return TYPE_ANGLE; }
358 operator std::list<T>()const
360 assert(type==TYPE_LIST);
361 std::list<T> ret(get_list().begin(),get_list().end());
365 operator std::vector<T>()const
367 assert(type==TYPE_LIST);
368 std::vector<T> ret(get_list().begin(),get_list().end());
375 template <typename T> void
378 const Type newtype(get_type(x));
380 assert(newtype!=TYPE_NIL);
384 if(ref_count.unique())
386 *reinterpret_cast<T*>(data)=x;
397 }; // END of class ValueBase
404 class Value : public ValueBase
407 Value(const T &x):ValueBase(x)
411 Value(const ValueBase &x):ValueBase(x)
413 if(!x.same_type_as(T()))
414 throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
421 T get()const { return ValueBase::get(T()); }
423 void put(T* x)const { ValueBase::put(x); }
425 void set(const T& x) { ValueBase::operator=(x); }
427 Value<T>& operator=(const T& x) { set(x); return *this; }
429 Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
431 Value<T>& operator=(const ValueBase& x)
433 if(!x.same_type_as(T()))
434 throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
435 return ValueBase::operator=(x);
438 }; // END of class Value
442 class Value< std::list<CT> > : public ValueBase
445 Value(const T &x):ValueBase(x)
448 Value(const ValueBase &x):ValueBase(x)
450 if(!x.same_type_as(T()))
451 throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
457 T get()const { return ValueBase::get(T()); }
459 void put(T* x)const { ValueBase::put(x); }
461 void set(const T& x) { ValueBase::operator=(x); }
463 Value<T>& operator=(const T& x) { set(x); return *this; }
465 Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
467 Value<T>& operator=(const ValueBase& x)
469 if(!x.same_type_as(T()))
470 throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
471 return ValueBase::operator=(x);
474 }; // END of class Value
477 }; // END of namespace synfig
479 /* === E N D =============================================================== */