Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/util/MultiType.h @ 1853

Last change on this file since 1853 was 1791, checked in by landauf, 16 years ago

added comments to all my classes in util

  • Property svn:eol-style set to native
File size: 52.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program 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
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file MultiType.h
31    @brief Declaration of the MultiType and some helper constructs.
32
33    The MultiType can hold a value of one of the following types:
34     - all primitives
35     - all pointers
36     - string
37     - Vector2, Vector3, Vector4
38     - Quaternion
39     - ColourValue
40     - Radian, Degree
41
42    The MultiType has a "type" determined by the first assigned value, either through
43     - the constructor,
44     - the assignment operator= or
45     - setValue(value).
46    If you assign another value of another type, the MultiType keeps "it's" type and
47    converts the new value to this type.
48
49    If you want to change the type, there are three possibilities:
50     - convert<T>() set's the type to T and converts the currently assigned value
51     - setType<T>() set's the type to T and resets the value
52     - setValue<T>(value) assigns a new value and changes the type to T.
53
54    @example
55    MultiType a = 10;;         // a has now the type int and the value 10
56    a.setValue("3.14");        // a has still the type int and "3.14" gets converted, therefore the value is now 3
57    a.setValue<float>("3.14"); // a has now the type float and "3.14" gets converted to 3.14
58    a.convert<bool>();         // converts 3.14 to bool, which is true
59    a = false;                 // assigns false, this is equivalent to a.setValue(false)
60*/
61
62#ifndef _MultiType_H__
63#define _MultiType_H__
64
65#include "UtilPrereqs.h"
66
67#include <boost/static_assert.hpp>
68
69#include "Math.h"
70
71/**
72    @brief Enum of all possible types of a MultiType.
73*/
74enum MT_Type
75{
76    MT_null,
77    MT_char,
78    MT_uchar,
79    MT_short,
80    MT_ushort,
81    MT_int,
82    MT_uint,
83    MT_long,
84    MT_ulong,
85    MT_longlong,
86    MT_ulonglong,
87    MT_float,
88    MT_double,
89    MT_longdouble,
90    MT_bool,
91    MT_void,
92    MT_string,
93    MT_vector2,
94    MT_vector3,
95    MT_vector4,
96    MT_colourvalue,
97    MT_quaternion,
98    MT_radian,
99    MT_degree
100};
101
102/**
103    @brief The MultiType can hold a value of many possible types and convert them to other types.
104
105    The following types are supported by the MultiType:
106     - all primitves
107     - all pointers
108     - string
109     - Vector2, Vector3, Vector4
110     - Quaternion
111     - ColourValue
112     - Radian, Degree
113
114    The internal type of a MultiType is determined by the first assigned value, but can be
115    changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned
116    the normal way (operator=, setValue(value)), the value gets converted to the current internal
117    type of the MultiType.
118*/
119class _UtilExport MultiType
120{
121    _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
122    template <typename T> friend struct MT_Value;
123
124    /**
125        @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType.
126        This class is only used within the MultiType.
127    */
128    struct _UtilExport MT_ValueBase
129    {
130        MT_ValueBase(MT_Type type) : type_(type) {}
131        virtual ~MT_ValueBase() {}
132
133        virtual MT_ValueBase* clone() const = 0;
134
135        virtual void reset() = 0;
136        virtual void assimilate(const MultiType& other) = 0;
137
138        /** @brief Returns the type of the current value. */
139        const MT_Type& getType() const { return this->type_; }
140
141        virtual void setValue(const char& value)                 = 0;
142        virtual void setValue(const unsigned char& value)        = 0;
143        virtual void setValue(const short& value)                = 0;
144        virtual void setValue(const unsigned short& value)       = 0;
145        virtual void setValue(const int& value)                  = 0;
146        virtual void setValue(const unsigned int& value)         = 0;
147        virtual void setValue(const long& value)                 = 0;
148        virtual void setValue(const unsigned long& value)        = 0;
149        virtual void setValue(const long long& value)            = 0;
150        virtual void setValue(const unsigned long long& value)   = 0;
151        virtual void setValue(const float& value)                = 0;
152        virtual void setValue(const double& value)               = 0;
153        virtual void setValue(const long double& value)          = 0;
154        virtual void setValue(const bool& value)                 = 0;
155        virtual void setValue(      void* const& value)          = 0;
156        virtual void setValue(const std::string& value)          = 0;
157        virtual void setValue(const orxonox::Vector2& value)     = 0;
158        virtual void setValue(const orxonox::Vector3& value)     = 0;
159        virtual void setValue(const orxonox::Vector4& value)     = 0;
160        virtual void setValue(const orxonox::ColourValue& value) = 0;
161        virtual void setValue(const orxonox::Quaternion& value)  = 0;
162        virtual void setValue(const orxonox::Radian& value)      = 0;
163        virtual void setValue(const orxonox::Degree& value)      = 0;
164
165        virtual operator char()                 const = 0;
166        virtual operator unsigned char()        const = 0;
167        virtual operator short()                const = 0;
168        virtual operator unsigned short()       const = 0;
169        virtual operator int()                  const = 0;
170        virtual operator unsigned int()         const = 0;
171        virtual operator long()                 const = 0;
172        virtual operator unsigned long()        const = 0;
173        virtual operator long long()            const = 0;
174        virtual operator unsigned long long()   const = 0;
175        virtual operator float()                const = 0;
176        virtual operator double()               const = 0;
177        virtual operator long double()          const = 0;
178        virtual operator bool()                 const = 0;
179        virtual operator void*()                const = 0;
180        virtual operator std::string()          const = 0;
181        virtual operator orxonox::Vector2()     const = 0;
182        virtual operator orxonox::Vector3()     const = 0;
183        virtual operator orxonox::Vector4()     const = 0;
184        virtual operator orxonox::ColourValue() const = 0;
185        virtual operator orxonox::Quaternion()  const = 0;
186        virtual operator orxonox::Radian()      const = 0;
187        virtual operator orxonox::Degree()      const = 0;
188
189        virtual void toString(std::ostream& outstream) const = 0;
190
191        MT_Type type_; //! The type of the current value
192    };
193
194    public:
195        inline MultiType()                                  : value_(0) {}                                      /** @brief Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value. */
196        inline MultiType(const char& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
197        inline MultiType(const unsigned char& value)        : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
198        inline MultiType(const short& value)                : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
199        inline MultiType(const unsigned short& value)       : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
200        inline MultiType(const int& value)                  : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
201        inline MultiType(const unsigned int& value)         : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
202        inline MultiType(const long& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
203        inline MultiType(const unsigned long& value)        : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
204        inline MultiType(const long long& value)            : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
205        inline MultiType(const unsigned long long& value)   : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
206        inline MultiType(const float& value)                : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
207        inline MultiType(const double& value)               : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
208        inline MultiType(const long double& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
209        inline MultiType(const bool& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
210        inline MultiType(      void* const& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
211        inline MultiType(const std::string& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
212        inline MultiType(const orxonox::Vector2& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
213        inline MultiType(const orxonox::Vector3& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
214        inline MultiType(const orxonox::Vector4& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
215        inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
216        inline MultiType(const orxonox::Quaternion& value)  : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
217        inline MultiType(const orxonox::Radian& value)      : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
218        inline MultiType(const orxonox::Degree& value)      : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
219        inline MultiType(const char* value)                 : value_(0) { this->setValue(std::string(value)); } /** @brief Constructor: Converts the char array to a std::string, assigns the value and sets the type. */
220        inline MultiType(const MultiType& other)            : value_(0) { this->setValue(other); }              /** @brief Copyconstructor: Assigns value and type of the other MultiType. */
221        inline MultiType(MT_Type type)                      : value_(0) { this->setType(type); }                /** @brief Constructor: Sets the type, the next assignment will determine the value. */
222
223        /** @brief Destructor: Deletes the MT_Value. */
224        inline ~MultiType() { if (this->value_) { delete this->value_; } }
225
226        template <typename V> inline const MultiType& operator=(const V& value)         { this->setValue(value); return (*this); } /** @brief Assigns a new value. The value will be converted to the current type of the MultiType. */
227        template <typename V> inline const MultiType& operator=(V* value)               { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */
228        inline                       const MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } /** @brief Assigns the value of the other MultiType and converts it to the current type of the MultiType. */
229        inline                       const MultiType& operator=(MT_Type type)           { this->setType(type);   return (*this); } /** @brief Resets the value and changes the type. */
230
231        inline void                                   setValue(const char& value);
232        inline void                                   setValue(const unsigned char& value);
233        inline void                                   setValue(const short& value);
234        inline void                                   setValue(const unsigned short& value);
235        inline void                                   setValue(const int& value);
236        inline void                                   setValue(const unsigned int& value);
237        inline void                                   setValue(const long& value);
238        inline void                                   setValue(const unsigned long& value);
239        inline void                                   setValue(const long long& value);
240        inline void                                   setValue(const unsigned long long& value);
241        inline void                                   setValue(const float& value);
242        inline void                                   setValue(const double& value);
243        inline void                                   setValue(const long double& value);
244        inline void                                   setValue(const bool& value);
245        inline void                                   setValue(      void* const& value);
246        inline void                                   setValue(const std::string& value);
247        inline void                                   setValue(const orxonox::Vector2& value);
248        inline void                                   setValue(const orxonox::Vector3& value);
249        inline void                                   setValue(const orxonox::Vector4& value);
250        inline void                                   setValue(const orxonox::ColourValue& value);
251        inline void                                   setValue(const orxonox::Quaternion& value);
252        inline void                                   setValue(const orxonox::Radian& value);
253        inline void                                   setValue(const orxonox::Degree& value);
254        inline void                                   setValue(const char* value);
255        /** @brief Assigns a pointer. */
256        template <typename V> inline void             setValue(V* value)               { if (this->value_) { this->value_->setValue((void*)value); } else { this->assignValue((void*)value); } }
257        /** @brief Assigns the value of the other MultiType and converts it to the current type. */
258        void                                          setValue(const MultiType& other) { if (this->value_) { this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } } }
259        /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */
260        template <typename T, typename V> inline void setValue(const V& value)         { this->setType<T>(); this->setValue(value); }
261
262
263        /** @brief Copies the other MultiType by assigning value and type. */
264        inline void                       copy(const MultiType& other)    { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; }
265
266        template <typename T> inline void convert()                       { this->setValue<T>((T)(*this));  } /** @brief Converts the current value to type T. */
267        inline void                       convert(const MultiType& other) { this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */
268        void                              convert(MT_Type type);
269
270        /** @brief Resets the value to the defaultvalue of the current type. */
271        inline void                       reset()                         { if (this->value_) { delete this->value_; this->value_ = 0; } }
272
273        template <typename T> inline void setType()                       { this->assignValue(T());                            } /** @brief Resets the value and changes the internal type to T. */
274        inline void                       setType(const MultiType& other) { this->setType(other.getType());                    } /** @brief Resets the value and changes the internal type to the type of the other MultiType. */
275        inline void                       setType(MT_Type type)           { this->reset(); this->convert(type); this->reset(); } /** @brief Resets the value and changes the internal type to the given type. */
276
277        /** @brief Returns the current type. */
278        inline MT_Type                    getType()                 const { return (this->value_) ? this->value_->type_ : MT_null; }
279        /** @brief Returns true if the current type equals the given type. */
280        inline bool                       isType(MT_Type type)      const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_null); }
281        /** @brief Returns true if the current type is T. */
282        template <typename T> inline bool isType()                  const { return false; } // Only works for specialized values - see below
283        std::string                       getTypename()             const;
284
285        operator char()                  const;
286        operator unsigned char()         const;
287        operator short()                 const;
288        operator unsigned short()        const;
289        operator int()                   const;
290        operator unsigned int()          const;
291        operator long()                  const;
292        operator unsigned long()         const;
293        operator long long()             const;
294        operator unsigned long long()    const;
295        operator float()                 const;
296        operator double()                const;
297        operator long double()           const;
298        operator bool()                  const;
299        operator void*()                 const;
300        operator std::string()           const;
301        operator orxonox::Vector2()      const;
302        operator orxonox::Vector3()      const;
303        operator orxonox::Vector4()      const;
304        operator orxonox::ColourValue()  const;
305        operator orxonox::Quaternion()   const;
306        operator orxonox::Radian()       const;
307        operator orxonox::Degree()       const;
308        /** @brief Returns the current value, converted to a T* pointer. */
309        template <class T> operator T*() const { return ((T*)this->operator void*()); }
310
311        inline void getValue(char*                 value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
312        inline void getValue(unsigned char*        value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
313        inline void getValue(short*                value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
314        inline void getValue(unsigned short*       value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
315        inline void getValue(int*                  value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
316        inline void getValue(unsigned int*         value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
317        inline void getValue(long*                 value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
318        inline void getValue(unsigned long*        value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
319        inline void getValue(long long*            value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
320        inline void getValue(unsigned long long*   value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
321        inline void getValue(float*                value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
322        inline void getValue(double*               value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
323        inline void getValue(long double*          value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
324        inline void getValue(bool*                 value) const { if (this->value_) { (*value) = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
325        inline void getValue(void*                 value) const { if (this->value_) {   value  = (*this->value_); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
326        inline void getValue(std::string*          value) const { if (this->value_) { (*value) = this->value_->operator std::string();          } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
327        inline void getValue(orxonox::Vector2*     value) const { if (this->value_) { (*value) = this->value_->operator orxonox::Vector2();     } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
328        inline void getValue(orxonox::Vector3*     value) const { if (this->value_) { (*value) = this->value_->operator orxonox::Vector3();     } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
329        inline void getValue(orxonox::Vector4*     value) const { if (this->value_) { (*value) = this->value_->operator orxonox::Vector4();     } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
330        inline void getValue(orxonox::ColourValue* value) const { if (this->value_) { (*value) = this->value_->operator orxonox::ColourValue(); } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
331        inline void getValue(orxonox::Quaternion*  value) const { if (this->value_) { (*value) = this->value_->operator orxonox::Quaternion();  } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
332        inline void getValue(orxonox::Radian*      value) const { if (this->value_) { (*value) = this->value_->operator orxonox::Radian();      } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
333        inline void getValue(orxonox::Degree*      value) const { if (this->value_) { (*value) = this->value_->operator orxonox::Degree();      } } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
334
335        inline char                     getChar()             const { return this->operator char();                 } /** @brief Returns the current value, converted to the requested type. */
336        inline unsigned char            getUnsignedChar()     const { return this->operator unsigned char();        } /** @brief Returns the current value, converted to the requested type. */
337        inline short                    getShort()            const { return this->operator short();                } /** @brief Returns the current value, converted to the requested type. */
338        inline unsigned short           getUnsignedShort()    const { return this->operator unsigned short();       } /** @brief Returns the current value, converted to the requested type. */
339        inline int                      getInt()              const { return this->operator int();                  } /** @brief Returns the current value, converted to the requested type. */
340        inline unsigned int             getUnsignedInt()      const { return this->operator unsigned int();         } /** @brief Returns the current value, converted to the requested type. */
341        inline long                     getLong()             const { return this->operator long();                 } /** @brief Returns the current value, converted to the requested type. */
342        inline unsigned long            getUnsignedLong()     const { return this->operator unsigned long();        } /** @brief Returns the current value, converted to the requested type. */
343        inline long long                getLongLong()         const { return this->operator long long();            } /** @brief Returns the current value, converted to the requested type. */
344        inline unsigned long long       getUnsignedLongLong() const { return this->operator unsigned long long();   } /** @brief Returns the current value, converted to the requested type. */
345        inline float                    getFloat()            const { return this->operator float();                } /** @brief Returns the current value, converted to the requested type. */
346        inline double                   getDouble()           const { return this->operator double();               } /** @brief Returns the current value, converted to the requested type. */
347        inline long double              getLongDouble()       const { return this->operator long double();          } /** @brief Returns the current value, converted to the requested type. */
348        inline bool                     getBool()             const { return this->operator bool();                 } /** @brief Returns the current value, converted to the requested type. */
349        inline void*                    getVoid()             const { return this->operator void*();                } /** @brief Returns the current value, converted to the requested type. */
350        inline std::string              getString()           const { return this->operator std::string();          } /** @brief Returns the current value, converted to the requested type. */
351        inline orxonox::Vector2         getVector2()          const { return this->operator orxonox::Vector2();     } /** @brief Returns the current value, converted to the requested type. */
352        inline orxonox::Vector3         getVector3()          const { return this->operator orxonox::Vector3();     } /** @brief Returns the current value, converted to the requested type. */
353        inline orxonox::Vector4         getVector4()          const { return this->operator orxonox::Vector4();     } /** @brief Returns the current value, converted to the requested type. */
354        inline orxonox::ColourValue     getColourValue()      const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */
355        inline orxonox::Quaternion      getQuaternion()       const { return this->operator orxonox::Quaternion();  } /** @brief Returns the current value, converted to the requested type. */
356        inline orxonox::Radian          getRadian()           const { return this->operator orxonox::Radian();      } /** @brief Returns the current value, converted to the requested type. */
357        inline orxonox::Degree          getDegree()           const { return this->operator orxonox::Degree();      } /** @brief Returns the current value, converted to the requested type. */
358        template <typename T> inline T* getPointer()          const { return ((T*)this->getVoid());                 } /** @brief Returns the current value, converted to a T* pointer. */
359
360    private:
361        inline void assignValue(const char& value)                 { if (this->value_ && this->value_->type_ == MT_char)        { this->value_->setValue(value); } else { this->changeValueContainer<char>(value);                 } } /** @brief Assigns a new value by changing type and creating a new container. */
362        inline void assignValue(const unsigned char& value)        { if (this->value_ && this->value_->type_ == MT_uchar)       { this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value);        } } /** @brief Assigns a new value by changing type and creating a new container. */
363        inline void assignValue(const short& value)                { if (this->value_ && this->value_->type_ == MT_short)       { this->value_->setValue(value); } else { this->changeValueContainer<short>(value);                } } /** @brief Assigns a new value by changing type and creating a new container. */
364        inline void assignValue(const unsigned short& value)       { if (this->value_ && this->value_->type_ == MT_ushort)      { this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value);       } } /** @brief Assigns a new value by changing type and creating a new container. */
365        inline void assignValue(const int& value)                  { if (this->value_ && this->value_->type_ == MT_int)         { this->value_->setValue(value); } else { this->changeValueContainer<int>(value);                  } } /** @brief Assigns a new value by changing type and creating a new container. */
366        inline void assignValue(const unsigned int& value)         { if (this->value_ && this->value_->type_ == MT_uint)        { this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value);         } } /** @brief Assigns a new value by changing type and creating a new container. */
367        inline void assignValue(const long& value)                 { if (this->value_ && this->value_->type_ == MT_long)        { this->value_->setValue(value); } else { this->changeValueContainer<long>(value);                 } } /** @brief Assigns a new value by changing type and creating a new container. */
368        inline void assignValue(const unsigned long& value)        { if (this->value_ && this->value_->type_ == MT_ulong)       { this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value);        } } /** @brief Assigns a new value by changing type and creating a new container. */
369        inline void assignValue(const long long& value)            { if (this->value_ && this->value_->type_ == MT_longlong)    { this->value_->setValue(value); } else { this->changeValueContainer<long long>(value);            } } /** @brief Assigns a new value by changing type and creating a new container. */
370        inline void assignValue(const unsigned long long& value)   { if (this->value_ && this->value_->type_ == MT_ulonglong)   { this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value);   } } /** @brief Assigns a new value by changing type and creating a new container. */
371        inline void assignValue(const float& value)                { if (this->value_ && this->value_->type_ == MT_float)       { this->value_->setValue(value); } else { this->changeValueContainer<float>(value);                } } /** @brief Assigns a new value by changing type and creating a new container. */
372        inline void assignValue(const double& value)               { if (this->value_ && this->value_->type_ == MT_double)      { this->value_->setValue(value); } else { this->changeValueContainer<double>(value);               } } /** @brief Assigns a new value by changing type and creating a new container. */
373        inline void assignValue(const long double& value)          { if (this->value_ && this->value_->type_ == MT_longdouble)  { this->value_->setValue(value); } else { this->changeValueContainer<long double>(value);          } } /** @brief Assigns a new value by changing type and creating a new container. */
374        inline void assignValue(const bool& value)                 { if (this->value_ && this->value_->type_ == MT_bool)        { this->value_->setValue(value); } else { this->changeValueContainer<bool>(value);                 } } /** @brief Assigns a new value by changing type and creating a new container. */
375        inline void assignValue(      void* const& value)          { if (this->value_ && this->value_->type_ == MT_void)        { this->value_->setValue(value); } else { this->changeValueContainer<void*>(value);                } } /** @brief Assigns a new value by changing type and creating a new container. */
376        inline void assignValue(const std::string& value)          { if (this->value_ && this->value_->type_ == MT_string)      { this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value);          } } /** @brief Assigns a new value by changing type and creating a new container. */
377        inline void assignValue(const orxonox::Vector2& value)     { if (this->value_ && this->value_->type_ == MT_vector2)     { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value);     } } /** @brief Assigns a new value by changing type and creating a new container. */
378        inline void assignValue(const orxonox::Vector3& value)     { if (this->value_ && this->value_->type_ == MT_vector3)     { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value);     } } /** @brief Assigns a new value by changing type and creating a new container. */
379        inline void assignValue(const orxonox::Vector4& value)     { if (this->value_ && this->value_->type_ == MT_vector4)     { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value);     } } /** @brief Assigns a new value by changing type and creating a new container. */
380        inline void assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_colourvalue) { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); } } /** @brief Assigns a new value by changing type and creating a new container. */
381        inline void assignValue(const orxonox::Quaternion& value)  { if (this->value_ && this->value_->type_ == MT_quaternion)  { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value);  } } /** @brief Assigns a new value by changing type and creating a new container. */
382        inline void assignValue(const orxonox::Radian& value)      { if (this->value_ && this->value_->type_ == MT_radian)      { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value);      } } /** @brief Assigns a new value by changing type and creating a new container. */
383        inline void assignValue(const orxonox::Degree& value)      { if (this->value_ && this->value_->type_ == MT_degree)      { this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value);      } } /** @brief Assigns a new value by changing type and creating a new container. */
384
385        /** @brief Changes the value container. */
386        template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); }
387        /** @brief Creates a new value container (works only with specialized types). */
388        template <typename T>        void createNewValueContainer(const T& value) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
389
390        MT_ValueBase* value_; //! A pointer to the value container
391};
392
393/** @brief Puts the MultiType on a stream by using the native << operator of the current type. */
394_UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; }
395
396template <> inline bool MultiType::isType<char>()                 const { return (this->value_ && this->value_->type_ == MT_char);        } /** @brief Returns true if the current type equals the given type. */
397template <> inline bool MultiType::isType<unsigned char>()        const { return (this->value_ && this->value_->type_ == MT_uchar);       } /** @brief Returns true if the current type equals the given type. */
398template <> inline bool MultiType::isType<short>()                const { return (this->value_ && this->value_->type_ == MT_short);       } /** @brief Returns true if the current type equals the given type. */
399template <> inline bool MultiType::isType<unsigned short>()       const { return (this->value_ && this->value_->type_ == MT_ushort);      } /** @brief Returns true if the current type equals the given type. */
400template <> inline bool MultiType::isType<int>()                  const { return (this->value_ && this->value_->type_ == MT_int);         } /** @brief Returns true if the current type equals the given type. */
401template <> inline bool MultiType::isType<unsigned int>()         const { return (this->value_ && this->value_->type_ == MT_uint);        } /** @brief Returns true if the current type equals the given type. */
402template <> inline bool MultiType::isType<long>()                 const { return (this->value_ && this->value_->type_ == MT_long);        } /** @brief Returns true if the current type equals the given type. */
403template <> inline bool MultiType::isType<unsigned long>()        const { return (this->value_ && this->value_->type_ == MT_ulong);       } /** @brief Returns true if the current type equals the given type. */
404template <> inline bool MultiType::isType<long long>()            const { return (this->value_ && this->value_->type_ == MT_longlong);    } /** @brief Returns true if the current type equals the given type. */
405template <> inline bool MultiType::isType<unsigned long long>()   const { return (this->value_ && this->value_->type_ == MT_ulonglong);   } /** @brief Returns true if the current type equals the given type. */
406template <> inline bool MultiType::isType<float>()                const { return (this->value_ && this->value_->type_ == MT_float);       } /** @brief Returns true if the current type equals the given type. */
407template <> inline bool MultiType::isType<double>()               const { return (this->value_ && this->value_->type_ == MT_double);      } /** @brief Returns true if the current type equals the given type. */
408template <> inline bool MultiType::isType<long double>()          const { return (this->value_ && this->value_->type_ == MT_longdouble);  } /** @brief Returns true if the current type equals the given type. */
409template <> inline bool MultiType::isType<bool>()                 const { return (this->value_ && this->value_->type_ == MT_bool);        } /** @brief Returns true if the current type equals the given type. */
410template <> inline bool MultiType::isType<void*>()                const { return (this->value_ && this->value_->type_ == MT_void);        } /** @brief Returns true if the current type equals the given type. */
411template <> inline bool MultiType::isType<std::string>()          const { return (this->value_ && this->value_->type_ == MT_string);      } /** @brief Returns true if the current type equals the given type. */
412template <> inline bool MultiType::isType<orxonox::Vector2>()     const { return (this->value_ && this->value_->type_ == MT_vector2);     } /** @brief Returns true if the current type equals the given type. */
413template <> inline bool MultiType::isType<orxonox::Vector3>()     const { return (this->value_ && this->value_->type_ == MT_vector3);     } /** @brief Returns true if the current type equals the given type. */
414template <> inline bool MultiType::isType<orxonox::Vector4>()     const { return (this->value_ && this->value_->type_ == MT_vector4);     } /** @brief Returns true if the current type equals the given type. */
415template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_colourvalue); } /** @brief Returns true if the current type equals the given type. */
416template <> inline bool MultiType::isType<orxonox::Quaternion>()  const { return (this->value_ && this->value_->type_ == MT_quaternion);  } /** @brief Returns true if the current type equals the given type. */
417template <> inline bool MultiType::isType<orxonox::Radian>()      const { return (this->value_ && this->value_->type_ == MT_radian);      } /** @brief Returns true if the current type equals the given type. */
418template <> inline bool MultiType::isType<orxonox::Degree>()      const { return (this->value_ && this->value_->type_ == MT_degree);      } /** @brief Returns true if the current type equals the given type. */
419
420// Specialization to avoid ambiguities with the conversion operator
421template <> inline void MultiType::convert<std::string>()          { this->setValue<std::string>         (this->operator std::string());          } /** @brief Converts the current value to the given type. */
422template <> inline void MultiType::convert<orxonox::Vector2>()     { this->setValue<orxonox::Vector2>    (this->operator orxonox::Vector2());     } /** @brief Converts the current value to the given type. */
423template <> inline void MultiType::convert<orxonox::Vector3>()     { this->setValue<orxonox::Vector3>    (this->operator orxonox::Vector3());     } /** @brief Converts the current value to the given type. */
424template <> inline void MultiType::convert<orxonox::Vector4>()     { this->setValue<orxonox::Vector4>    (this->operator orxonox::Vector4());     } /** @brief Converts the current value to the given type. */
425template <> inline void MultiType::convert<orxonox::ColourValue>() { this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */
426template <> inline void MultiType::convert<orxonox::Quaternion>()  { this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion());  } /** @brief Converts the current value to the given type. */
427template <> inline void MultiType::convert<orxonox::Radian>()      { this->setValue<orxonox::Radian>     (this->operator orxonox::Radian());      } /** @brief Converts the current value to the given type. */
428template <> inline void MultiType::convert<orxonox::Degree>()      { this->setValue<orxonox::Degree>     (this->operator orxonox::Degree());      } /** @brief Converts the current value to the given type. */
429
430// Specialization to avoid ambiguities with the conversion operator
431template <> inline void MultiType::convert<const std::string&>()          { this->convert<std::string>();          } /** @brief Converts the current value to the given type. */
432template <> inline void MultiType::convert<const orxonox::Vector2&>()     { this->convert<orxonox::Vector2>();     } /** @brief Converts the current value to the given type. */
433template <> inline void MultiType::convert<const orxonox::Vector3&>()     { this->convert<orxonox::Vector3>();     } /** @brief Converts the current value to the given type. */
434template <> inline void MultiType::convert<const orxonox::Vector4&>()     { this->convert<orxonox::Vector4>();     } /** @brief Converts the current value to the given type. */
435template <> inline void MultiType::convert<const orxonox::ColourValue&>() { this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */
436template <> inline void MultiType::convert<const orxonox::Quaternion&>()  { this->convert<orxonox::Quaternion>();  } /** @brief Converts the current value to the given type. */
437template <> inline void MultiType::convert<const orxonox::Radian&>()      { this->convert<orxonox::Radian>();      } /** @brief Converts the current value to the given type. */
438template <> inline void MultiType::convert<const orxonox::Degree&>()      { this->convert<orxonox::Degree>();      } /** @brief Converts the current value to the given type. */
439
440template <> void MultiType::createNewValueContainer(const char& value);
441template <> void MultiType::createNewValueContainer(const unsigned char& value);
442template <> void MultiType::createNewValueContainer(const short& value);
443template <> void MultiType::createNewValueContainer(const unsigned short& value);
444template <> void MultiType::createNewValueContainer(const int& value);
445template <> void MultiType::createNewValueContainer(const unsigned int& value);
446template <> void MultiType::createNewValueContainer(const long& value);
447template <> void MultiType::createNewValueContainer(const unsigned long& value);
448template <> void MultiType::createNewValueContainer(const long long& value);
449template <> void MultiType::createNewValueContainer(const unsigned long long& value);
450template <> void MultiType::createNewValueContainer(const float& value);
451template <> void MultiType::createNewValueContainer(const double& value);
452template <> void MultiType::createNewValueContainer(const bool& value);
453template <> void MultiType::createNewValueContainer(const long double& value);
454template <> void MultiType::createNewValueContainer(      void* const& value);
455template <> void MultiType::createNewValueContainer(const std::string& value);
456template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value);
457template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value);
458template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value);
459template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value);
460template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value);
461template <> void MultiType::createNewValueContainer(const orxonox::Radian& value);
462template <> void MultiType::createNewValueContainer(const orxonox::Degree& value);
463
464inline void MultiType::setValue(const char& value)                  { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
465inline void MultiType::setValue(const unsigned char& value)         { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
466inline void MultiType::setValue(const short& value)                 { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
467inline void MultiType::setValue(const unsigned short& value)        { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
468inline void MultiType::setValue(const int& value)                   { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
469inline void MultiType::setValue(const unsigned int& value)          { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
470inline void MultiType::setValue(const long& value)                  { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
471inline void MultiType::setValue(const unsigned long& value)         { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
472inline void MultiType::setValue(const long long& value)             { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
473inline void MultiType::setValue(const unsigned long long& value)    { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
474inline void MultiType::setValue(const float& value)                 { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
475inline void MultiType::setValue(const double& value)                { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
476inline void MultiType::setValue(const long double& value)           { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
477inline void MultiType::setValue(const bool& value)                  { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
478inline void MultiType::setValue(      void* const& value)           { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
479inline void MultiType::setValue(const std::string& value)           { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
480inline void MultiType::setValue(const orxonox::Vector2& value)      { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
481inline void MultiType::setValue(const orxonox::Vector3& value)      { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
482inline void MultiType::setValue(const orxonox::Vector4& value)      { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
483inline void MultiType::setValue(const orxonox::ColourValue& value)  { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
484inline void MultiType::setValue(const orxonox::Quaternion& value)   { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
485inline void MultiType::setValue(const orxonox::Radian& value)       { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
486inline void MultiType::setValue(const orxonox::Degree& value)       { if (this->value_) { this->value_->setValue(value); } else { this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
487
488inline void MultiType::setValue(const char* value)                  { if (this->value_) { this->value_->setValue(std::string(value)); } else { this->assignValue(std::string(value)); } }  /** @brief Assigns the given value and converts it to the current type. */
489
490#endif /* _MultiType_H__ */
Note: See TracBrowser for help on using the repository browser.