Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3264 was 3241, checked in by rgrieder, 15 years ago

You shouln't feed GCC too much non standard compliant code ;)

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