Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2119 was 2087, checked in by landauf, 16 years ago

merged objecthierarchy branch back to trunk

  • Property svn:eol-style set to native
File size: 55.5 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    @note
62    Whenever a value gets converted, there is a boolean return value telling you whether it was
63    successful or not. If it wasn't a zero value is assigned with the help of zeroise<T>().
64*/
65
66#ifndef _MultiType_H__
67#define _MultiType_H__
68
69#include "UtilPrereqs.h"
70
71#include <boost/static_assert.hpp>
72
73#include "Math.h"
74
75/**
76    @brief Enum of all possible types of a MultiType.
77*/
78enum MT_Type
79{
80    MT_null,
81    MT_char,
82    MT_uchar,
83    MT_short,
84    MT_ushort,
85    MT_int,
86    MT_uint,
87    MT_long,
88    MT_ulong,
89    MT_longlong,
90    MT_ulonglong,
91    MT_float,
92    MT_double,
93    MT_longdouble,
94    MT_bool,
95    MT_void,
96    MT_string,
97    MT_vector2,
98    MT_vector3,
99    MT_vector4,
100    MT_colourvalue,
101    MT_quaternion,
102    MT_radian,
103    MT_degree
104};
105
106/**
107    @brief The MultiType can hold a value of many possible types and convert them to other types.
108
109    The following types are supported by the MultiType:
110     - all primitves
111     - all pointers
112     - string
113     - Vector2, Vector3, Vector4
114     - Quaternion
115     - ColourValue
116     - Radian, Degree
117
118    The internal type of a MultiType is determined by the first assigned value, but can be
119    changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned
120    the normal way (operator=, setValue(value)), the value gets converted to the current internal
121    type of the MultiType.
122*/
123class _UtilExport MultiType
124{
125    _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
126    template <typename T> friend struct MT_Value;
127
128    /**
129        @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType.
130        This class is only used within the MultiType.
131    */
132    struct _UtilExport MT_ValueBase
133    {
134        MT_ValueBase(MT_Type type) : type_(type), bHasDefaultValue_(false) {}
135        virtual ~MT_ValueBase() {}
136
137        virtual MT_ValueBase* clone() const = 0;
138
139        virtual void reset() = 0;
140        virtual bool assimilate(const MultiType& other) = 0;
141
142        /** @brief Returns the type of the current value. */
143        const MT_Type& getType() const { return this->type_; }
144
145        /** @brief Checks whether the value is a default one. */
146        bool hasDefaultValue()   const { return this->bHasDefaultValue_; }
147
148        virtual bool setValue(const char& value)                 = 0;
149        virtual bool setValue(const unsigned char& value)        = 0;
150        virtual bool setValue(const short& value)                = 0;
151        virtual bool setValue(const unsigned short& value)       = 0;
152        virtual bool setValue(const int& value)                  = 0;
153        virtual bool setValue(const unsigned int& value)         = 0;
154        virtual bool setValue(const long& value)                 = 0;
155        virtual bool setValue(const unsigned long& value)        = 0;
156        virtual bool setValue(const long long& value)            = 0;
157        virtual bool setValue(const unsigned long long& value)   = 0;
158        virtual bool setValue(const float& value)                = 0;
159        virtual bool setValue(const double& value)               = 0;
160        virtual bool setValue(const long double& value)          = 0;
161        virtual bool setValue(const bool& value)                 = 0;
162        virtual bool setValue(      void* const& value)          = 0;
163        virtual bool setValue(const std::string& value)          = 0;
164        virtual bool setValue(const orxonox::Vector2& value)     = 0;
165        virtual bool setValue(const orxonox::Vector3& value)     = 0;
166        virtual bool setValue(const orxonox::Vector4& value)     = 0;
167        virtual bool setValue(const orxonox::ColourValue& value) = 0;
168        virtual bool setValue(const orxonox::Quaternion& value)  = 0;
169        virtual bool setValue(const orxonox::Radian& value)      = 0;
170        virtual bool setValue(const orxonox::Degree& value)      = 0;
171
172        virtual bool getValue(char*                 value) const = 0;
173        virtual bool getValue(unsigned char*        value) const = 0;
174        virtual bool getValue(short*                value) const = 0;
175        virtual bool getValue(unsigned short*       value) const = 0;
176        virtual bool getValue(int*                  value) const = 0;
177        virtual bool getValue(unsigned int*         value) const = 0;
178        virtual bool getValue(long*                 value) const = 0;
179        virtual bool getValue(unsigned long*        value) const = 0;
180        virtual bool getValue(long long*            value) const = 0;
181        virtual bool getValue(unsigned long long*   value) const = 0;
182        virtual bool getValue(float*                value) const = 0;
183        virtual bool getValue(double*               value) const = 0;
184        virtual bool getValue(long double*          value) const = 0;
185        virtual bool getValue(bool*                 value) const = 0;
186        virtual bool getValue(void**                value) const = 0;
187        virtual bool getValue(std::string*          value) const = 0;
188        virtual bool getValue(orxonox::Vector2*     value) const = 0;
189        virtual bool getValue(orxonox::Vector3*     value) const = 0;
190        virtual bool getValue(orxonox::Vector4*     value) const = 0;
191        virtual bool getValue(orxonox::ColourValue* value) const = 0;
192        virtual bool getValue(orxonox::Quaternion*  value) const = 0;
193        virtual bool getValue(orxonox::Radian*      value) const = 0;
194        virtual bool getValue(orxonox::Degree*      value) const = 0;
195
196        virtual operator char()                 const = 0;
197        virtual operator unsigned char()        const = 0;
198        virtual operator short()                const = 0;
199        virtual operator unsigned short()       const = 0;
200        virtual operator int()                  const = 0;
201        virtual operator unsigned int()         const = 0;
202        virtual operator long()                 const = 0;
203        virtual operator unsigned long()        const = 0;
204        virtual operator long long()            const = 0;
205        virtual operator unsigned long long()   const = 0;
206        virtual operator float()                const = 0;
207        virtual operator double()               const = 0;
208        virtual operator long double()          const = 0;
209        virtual operator bool()                 const = 0;
210        virtual operator void*()                const = 0;
211        virtual operator std::string()          const = 0;
212        virtual operator orxonox::Vector2()     const = 0;
213        virtual operator orxonox::Vector3()     const = 0;
214        virtual operator orxonox::Vector4()     const = 0;
215        virtual operator orxonox::ColourValue() const = 0;
216        virtual operator orxonox::Quaternion()  const = 0;
217        virtual operator orxonox::Radian()      const = 0;
218        virtual operator orxonox::Degree()      const = 0;
219
220        virtual void toString(std::ostream& outstream) const = 0;
221
222        MT_Type type_;          //!< The type of the current value
223        bool bHasDefaultValue_; //!< True if the last conversion wasn't successful
224    };
225
226    public:
227        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. */
228        inline MultiType(const char& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
229        inline MultiType(const unsigned char& value)        : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
230        inline MultiType(const short& value)                : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
231        inline MultiType(const unsigned short& value)       : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
232        inline MultiType(const int& value)                  : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
233        inline MultiType(const unsigned int& value)         : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
234        inline MultiType(const long& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
235        inline MultiType(const unsigned long& value)        : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
236        inline MultiType(const long long& value)            : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
237        inline MultiType(const unsigned long long& value)   : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
238        inline MultiType(const float& value)                : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
239        inline MultiType(const double& value)               : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
240        inline MultiType(const long double& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
241        inline MultiType(const bool& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
242        inline MultiType(      void* const& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
243        inline MultiType(const std::string& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
244        inline MultiType(const orxonox::Vector2& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
245        inline MultiType(const orxonox::Vector3& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
246        inline MultiType(const orxonox::Vector4& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
247        inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
248        inline MultiType(const orxonox::Quaternion& value)  : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
249        inline MultiType(const orxonox::Radian& value)      : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
250        inline MultiType(const orxonox::Degree& value)      : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
251        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. */
252        inline MultiType(const MultiType& other)            : value_(0) { this->setValue(other); }              /** @brief Copyconstructor: Assigns value and type of the other MultiType. */
253        inline MultiType(MT_Type type)                      : value_(0) { this->setType(type); }                /** @brief Constructor: Sets the type, the next assignment will determine the value. */
254
255        /** @brief Destructor: Deletes the MT_Value. */
256        inline ~MultiType() { if (this->value_) { delete this->value_; } }
257
258        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. */
259        template <typename V> inline const MultiType& operator=(V* value)               { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */
260        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. */
261        inline                       const MultiType& operator=(MT_Type type)           { this->setType(type);   return (*this); } /** @brief Resets the value and changes the type. */
262
263        inline bool                                   setValue(const char& value);
264        inline bool                                   setValue(const unsigned char& value);
265        inline bool                                   setValue(const short& value);
266        inline bool                                   setValue(const unsigned short& value);
267        inline bool                                   setValue(const int& value);
268        inline bool                                   setValue(const unsigned int& value);
269        inline bool                                   setValue(const long& value);
270        inline bool                                   setValue(const unsigned long& value);
271        inline bool                                   setValue(const long long& value);
272        inline bool                                   setValue(const unsigned long long& value);
273        inline bool                                   setValue(const float& value);
274        inline bool                                   setValue(const double& value);
275        inline bool                                   setValue(const long double& value);
276        inline bool                                   setValue(const bool& value);
277        inline bool                                   setValue(      void* const& value);
278        inline bool                                   setValue(const std::string& value);
279        inline bool                                   setValue(const orxonox::Vector2& value);
280        inline bool                                   setValue(const orxonox::Vector3& value);
281        inline bool                                   setValue(const orxonox::Vector4& value);
282        inline bool                                   setValue(const orxonox::ColourValue& value);
283        inline bool                                   setValue(const orxonox::Quaternion& value);
284        inline bool                                   setValue(const orxonox::Radian& value);
285        inline bool                                   setValue(const orxonox::Degree& value);
286        inline bool                                   setValue(const char* value);
287        /** @brief Assigns a pointer. */
288        template <typename V> inline bool             setValue(V* value)               { if (this->value_) { return this->value_->setValue((void*)value); } else { return this->assignValue((void*)value); } }
289        /** @brief Assigns the value of the other MultiType and converts it to the current type. */
290        bool                                          setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } }
291        /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */
292        template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); }
293
294
295        /** @brief Copies the other MultiType by assigning value and type. */
296        inline void                       copy(const MultiType& other)    { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; }
297
298        template <typename T> inline bool convert()                       { return this->setValue<T>((T)(*this));  } /** @brief Converts the current value to type T. */
299        inline bool                       convert(const MultiType& other) { return this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */
300        bool                              convert(MT_Type type);
301
302        /** @brief Current content gets deleted. New type is MT_null */
303        inline void                       reset()                         { if (this->value_) this->value_->reset(); }
304
305        template <typename T> inline void setType()                       { this->assignValue(T());                            } /** @brief Resets the value and changes the internal type to T. */
306        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. */
307        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. */
308
309        /** @brief Returns the current type. */
310        inline MT_Type                    getType()                 const { return (this->value_) ? this->value_->type_ : MT_null; }
311        /** @brief Returns true if the current type equals the given type. */
312        inline bool                       isType(MT_Type type)      const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_null); }
313        /** @brief Returns true if the current type is T. */
314        template <typename T> inline bool isType()                  const { return false; } // Only works for specialized values - see below
315        std::string                       getTypename()             const;
316
317        /** @brief Checks whether the value is a default one. */
318        bool                              hasDefaultValue()         const { return this->value_->hasDefaultValue(); }
319
320        operator char()                  const;
321        operator unsigned char()         const;
322        operator short()                 const;
323        operator unsigned short()        const;
324        operator int()                   const;
325        operator unsigned int()          const;
326        operator long()                  const;
327        operator unsigned long()         const;
328        operator long long()             const;
329        operator unsigned long long()    const;
330        operator float()                 const;
331        operator double()                const;
332        operator long double()           const;
333        operator bool()                  const;
334        operator void*()                 const;
335        operator std::string()           const;
336        operator orxonox::Vector2()      const;
337        operator orxonox::Vector3()      const;
338        operator orxonox::Vector4()      const;
339        operator orxonox::ColourValue()  const;
340        operator orxonox::Quaternion()   const;
341        operator orxonox::Radian()       const;
342        operator orxonox::Degree()       const;
343        /** @brief Returns the current value, converted to a T* pointer. */
344        template <class T> operator T*() const { return ((T*)this->operator void*()); }
345
346        inline bool getValue(char*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
347        inline bool getValue(unsigned char*        value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
348        inline bool getValue(short*                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
349        inline bool getValue(unsigned short*       value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
350        inline bool getValue(int*                  value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
351        inline bool getValue(unsigned int*         value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
352        inline bool getValue(long*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
353        inline bool getValue(unsigned long*        value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
354        inline bool getValue(long long*            value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
355        inline bool getValue(unsigned long long*   value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
356        inline bool getValue(float*                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
357        inline bool getValue(double*               value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
358        inline bool getValue(long double*          value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
359        inline bool getValue(bool*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
360        inline bool getValue(void**                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
361        inline bool getValue(std::string*          value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
362        inline bool getValue(orxonox::Vector2*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
363        inline bool getValue(orxonox::Vector3*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
364        inline bool getValue(orxonox::Vector4*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
365        inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
366        inline bool getValue(orxonox::Quaternion*  value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
367        inline bool getValue(orxonox::Radian*      value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
368        inline bool getValue(orxonox::Degree*      value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
369
370        inline char                     getChar()             const { return this->operator char();                 } /** @brief Returns the current value, converted to the requested type. */
371        inline unsigned char            getUnsignedChar()     const { return this->operator unsigned char();        } /** @brief Returns the current value, converted to the requested type. */
372        inline short                    getShort()            const { return this->operator short();                } /** @brief Returns the current value, converted to the requested type. */
373        inline unsigned short           getUnsignedShort()    const { return this->operator unsigned short();       } /** @brief Returns the current value, converted to the requested type. */
374        inline int                      getInt()              const { return this->operator int();                  } /** @brief Returns the current value, converted to the requested type. */
375        inline unsigned int             getUnsignedInt()      const { return this->operator unsigned int();         } /** @brief Returns the current value, converted to the requested type. */
376        inline long                     getLong()             const { return this->operator long();                 } /** @brief Returns the current value, converted to the requested type. */
377        inline unsigned long            getUnsignedLong()     const { return this->operator unsigned long();        } /** @brief Returns the current value, converted to the requested type. */
378        inline long long                getLongLong()         const { return this->operator long long();            } /** @brief Returns the current value, converted to the requested type. */
379        inline unsigned long long       getUnsignedLongLong() const { return this->operator unsigned long long();   } /** @brief Returns the current value, converted to the requested type. */
380        inline float                    getFloat()            const { return this->operator float();                } /** @brief Returns the current value, converted to the requested type. */
381        inline double                   getDouble()           const { return this->operator double();               } /** @brief Returns the current value, converted to the requested type. */
382        inline long double              getLongDouble()       const { return this->operator long double();          } /** @brief Returns the current value, converted to the requested type. */
383        inline bool                     getBool()             const { return this->operator bool();                 } /** @brief Returns the current value, converted to the requested type. */
384        inline void*                    getVoid()             const { return this->operator void*();                } /** @brief Returns the current value, converted to the requested type. */
385        inline std::string              getString()           const { return this->operator std::string();          } /** @brief Returns the current value, converted to the requested type. */
386        inline orxonox::Vector2         getVector2()          const { return this->operator orxonox::Vector2();     } /** @brief Returns the current value, converted to the requested type. */
387        inline orxonox::Vector3         getVector3()          const { return this->operator orxonox::Vector3();     } /** @brief Returns the current value, converted to the requested type. */
388        inline orxonox::Vector4         getVector4()          const { return this->operator orxonox::Vector4();     } /** @brief Returns the current value, converted to the requested type. */
389        inline orxonox::ColourValue     getColourValue()      const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */
390        inline orxonox::Quaternion      getQuaternion()       const { return this->operator orxonox::Quaternion();  } /** @brief Returns the current value, converted to the requested type. */
391        inline orxonox::Radian          getRadian()           const { return this->operator orxonox::Radian();      } /** @brief Returns the current value, converted to the requested type. */
392        inline orxonox::Degree          getDegree()           const { return this->operator orxonox::Degree();      } /** @brief Returns the current value, converted to the requested type. */
393        template <typename T> inline T* getPointer()          const { return ((T*)this->getVoid());                 } /** @brief Returns the current value, converted to a T* pointer. */
394
395    private:
396        inline bool assignValue(const char& value)                 { if (this->value_ && this->value_->type_ == MT_char)        { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value);                 return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
397        inline bool assignValue(const unsigned char& value)        { if (this->value_ && this->value_->type_ == MT_uchar)       { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value);        return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
398        inline bool assignValue(const short& value)                { if (this->value_ && this->value_->type_ == MT_short)       { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value);                return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
399        inline bool assignValue(const unsigned short& value)       { if (this->value_ && this->value_->type_ == MT_ushort)      { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value);       return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
400        inline bool assignValue(const int& value)                  { if (this->value_ && this->value_->type_ == MT_int)         { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value);                  return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
401        inline bool assignValue(const unsigned int& value)         { if (this->value_ && this->value_->type_ == MT_uint)        { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value);         return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
402        inline bool assignValue(const long& value)                 { if (this->value_ && this->value_->type_ == MT_long)        { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value);                 return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
403        inline bool assignValue(const unsigned long& value)        { if (this->value_ && this->value_->type_ == MT_ulong)       { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value);        return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
404        inline bool assignValue(const long long& value)            { if (this->value_ && this->value_->type_ == MT_longlong)    { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value);            return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
405        inline bool assignValue(const unsigned long long& value)   { if (this->value_ && this->value_->type_ == MT_ulonglong)   { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value);   return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
406        inline bool assignValue(const float& value)                { if (this->value_ && this->value_->type_ == MT_float)       { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value);                return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
407        inline bool assignValue(const double& value)               { if (this->value_ && this->value_->type_ == MT_double)      { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value);               return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
408        inline bool assignValue(const long double& value)          { if (this->value_ && this->value_->type_ == MT_longdouble)  { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value);          return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
409        inline bool assignValue(const bool& value)                 { if (this->value_ && this->value_->type_ == MT_bool)        { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value);                 return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
410        inline bool assignValue(      void* const& value)          { if (this->value_ && this->value_->type_ == MT_void)        { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value);                return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
411        inline bool assignValue(const std::string& value)          { if (this->value_ && this->value_->type_ == MT_string)      { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value);          return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
412        inline bool assignValue(const orxonox::Vector2& value)     { if (this->value_ && this->value_->type_ == MT_vector2)     { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value);     return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
413        inline bool assignValue(const orxonox::Vector3& value)     { if (this->value_ && this->value_->type_ == MT_vector3)     { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value);     return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
414        inline bool assignValue(const orxonox::Vector4& value)     { if (this->value_ && this->value_->type_ == MT_vector4)     { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value);     return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
415        inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_colourvalue) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
416        inline bool assignValue(const orxonox::Quaternion& value)  { if (this->value_ && this->value_->type_ == MT_quaternion)  { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value);  return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
417        inline bool assignValue(const orxonox::Radian& value)      { if (this->value_ && this->value_->type_ == MT_radian)      { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value);      return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
418        inline bool assignValue(const orxonox::Degree& value)      { if (this->value_ && this->value_->type_ == MT_degree)      { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value);      return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
419
420        /** @brief Changes the value container. */
421        template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); }
422        /** @brief Creates a new value container (works only with specialized types). */
423        template <typename T>        void createNewValueContainer(const T& value) { BOOST_STATIC_ASSERT(sizeof(T) == 0); return false; }
424
425        MT_ValueBase* value_; //!< A pointer to the value container
426};
427
428/** @brief Puts the MultiType on a stream by using the native << operator of the current type. */
429_UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; }
430
431template <> 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. */
432template <> 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. */
433template <> 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. */
434template <> 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. */
435template <> 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. */
436template <> 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. */
437template <> 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. */
438template <> 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. */
439template <> 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. */
440template <> 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. */
441template <> 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. */
442template <> 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. */
443template <> 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. */
444template <> 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. */
445template <> 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. */
446template <> 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. */
447template <> 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. */
448template <> 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. */
449template <> 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. */
450template <> 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. */
451template <> 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. */
452template <> 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. */
453template <> 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. */
454
455// Specialization to avoid ambiguities with the conversion operator
456template <> inline bool MultiType::convert<std::string>()          { return this->setValue<std::string>         (this->operator std::string());          } /** @brief Converts the current value to the given type. */
457template <> inline bool MultiType::convert<orxonox::Vector2>()     { return this->setValue<orxonox::Vector2>    (this->operator orxonox::Vector2());     } /** @brief Converts the current value to the given type. */
458template <> inline bool MultiType::convert<orxonox::Vector3>()     { return this->setValue<orxonox::Vector3>    (this->operator orxonox::Vector3());     } /** @brief Converts the current value to the given type. */
459template <> inline bool MultiType::convert<orxonox::Vector4>()     { return this->setValue<orxonox::Vector4>    (this->operator orxonox::Vector4());     } /** @brief Converts the current value to the given type. */
460template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */
461template <> inline bool MultiType::convert<orxonox::Quaternion>()  { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion());  } /** @brief Converts the current value to the given type. */
462template <> inline bool MultiType::convert<orxonox::Radian>()      { return this->setValue<orxonox::Radian>     (this->operator orxonox::Radian());      } /** @brief Converts the current value to the given type. */
463template <> inline bool MultiType::convert<orxonox::Degree>()      { return this->setValue<orxonox::Degree>     (this->operator orxonox::Degree());      } /** @brief Converts the current value to the given type. */
464
465// Specialization to avoid ambiguities with the conversion operator
466template <> inline bool MultiType::convert<const std::string&>()          { return this->convert<std::string>();          } /** @brief Converts the current value to the given type. */
467template <> inline bool MultiType::convert<const orxonox::Vector2&>()     { return this->convert<orxonox::Vector2>();     } /** @brief Converts the current value to the given type. */
468template <> inline bool MultiType::convert<const orxonox::Vector3&>()     { return this->convert<orxonox::Vector3>();     } /** @brief Converts the current value to the given type. */
469template <> inline bool MultiType::convert<const orxonox::Vector4&>()     { return this->convert<orxonox::Vector4>();     } /** @brief Converts the current value to the given type. */
470template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */
471template <> inline bool MultiType::convert<const orxonox::Quaternion&>()  { return this->convert<orxonox::Quaternion>();  } /** @brief Converts the current value to the given type. */
472template <> inline bool MultiType::convert<const orxonox::Radian&>()      { return this->convert<orxonox::Radian>();      } /** @brief Converts the current value to the given type. */
473template <> inline bool MultiType::convert<const orxonox::Degree&>()      { return this->convert<orxonox::Degree>();      } /** @brief Converts the current value to the given type. */
474
475template <> void MultiType::createNewValueContainer(const char& value);
476template <> void MultiType::createNewValueContainer(const unsigned char& value);
477template <> void MultiType::createNewValueContainer(const short& value);
478template <> void MultiType::createNewValueContainer(const unsigned short& value);
479template <> void MultiType::createNewValueContainer(const int& value);
480template <> void MultiType::createNewValueContainer(const unsigned int& value);
481template <> void MultiType::createNewValueContainer(const long& value);
482template <> void MultiType::createNewValueContainer(const unsigned long& value);
483template <> void MultiType::createNewValueContainer(const long long& value);
484template <> void MultiType::createNewValueContainer(const unsigned long long& value);
485template <> void MultiType::createNewValueContainer(const float& value);
486template <> void MultiType::createNewValueContainer(const double& value);
487template <> void MultiType::createNewValueContainer(const bool& value);
488template <> void MultiType::createNewValueContainer(const long double& value);
489template <> void MultiType::createNewValueContainer(      void* const& value);
490template <> void MultiType::createNewValueContainer(const std::string& value);
491template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value);
492template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value);
493template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value);
494template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value);
495template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value);
496template <> void MultiType::createNewValueContainer(const orxonox::Radian& value);
497template <> void MultiType::createNewValueContainer(const orxonox::Degree& value);
498
499inline bool MultiType::setValue(const char& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
500inline bool MultiType::setValue(const unsigned char& value)         { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
501inline bool MultiType::setValue(const short& value)                 { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
502inline bool MultiType::setValue(const unsigned short& value)        { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
503inline bool MultiType::setValue(const int& value)                   { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
504inline bool MultiType::setValue(const unsigned int& value)          { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
505inline bool MultiType::setValue(const long& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
506inline bool MultiType::setValue(const unsigned long& value)         { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
507inline bool MultiType::setValue(const long long& value)             { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
508inline bool MultiType::setValue(const unsigned long long& value)    { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
509inline bool MultiType::setValue(const float& value)                 { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
510inline bool MultiType::setValue(const double& value)                { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
511inline bool MultiType::setValue(const long double& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
512inline bool MultiType::setValue(const bool& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
513inline bool MultiType::setValue(      void* const& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
514inline bool MultiType::setValue(const std::string& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
515inline bool MultiType::setValue(const orxonox::Vector2& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
516inline bool MultiType::setValue(const orxonox::Vector3& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
517inline bool MultiType::setValue(const orxonox::Vector4& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
518inline bool MultiType::setValue(const orxonox::ColourValue& value)  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
519inline bool MultiType::setValue(const orxonox::Quaternion& value)   { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
520inline bool MultiType::setValue(const orxonox::Radian& value)       { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
521inline bool MultiType::setValue(const orxonox::Degree& value)       { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
522
523inline bool MultiType::setValue(const char* value)                  { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } }  /** @brief Assigns the given value and converts it to the current type. */
524
525#endif /* _MultiType_H__ */
Note: See TracBrowser for help on using the repository browser.