Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3028 was 2662, checked in by rgrieder, 16 years ago

Merged presentation branch back to trunk.

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