Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/forks/sandbox_light/src/libraries/util/MultiType.h @ 7908

Last change on this file since 7908 was 7908, checked in by rgrieder, 13 years ago

Stripped down trunk to form a new light sandbox.

  • Property svn:eol-style set to native
File size: 58.6 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    @defgroup MultiType MultiType
31    @ingroup Util
32*/
33
34/**
35    @file
36    @ingroup MultiType
37    @brief Declaration of the MultiType and some helper constructs.
38
39    @anchor MultiTypeExamples
40
41    The MultiType can hold a value of one of the following types:
42     - all primitives (int, float, bool, etc.)
43     - all pointers (void* and T*)
44     - std::string
45     - Vector2, Vector3, Vector4
46     - Quaternion
47     - ColourValue
48     - Radian, Degree
49
50    The MultiType has an internal "type" determined by the first assigned value, using one of these ways:
51     - @ref orxonox::MultiType::MultiType "The constructor"
52     - The assignment operator= (orxonox::MultiType::operator=())
53     - @ref orxonox::MultiType::setValue() "setValue(value)"
54
55    If you assign another value of another type, the MultiType keeps "its" type and
56    converts the new value to the old type.
57
58    If you want to change the type, there are three possibilities:
59     - @ref orxonox::MultiType::convert "convert<T>()" sets the type to T and converts the currently assigned value
60     - @ref orxonox::MultiType::setType "setType<T>()" sets the type to T and resets the value to zero using zeroise<T>()
61     - setValue<T>(value) assigns a new value and changes the type to T.
62
63    Examples:
64    @code
65    MultiType a = 10;          // a has now the type int and the value 10
66    a.setValue("3.14");        // a has still the type int and "3.14" gets converted, therefore the value is now 3
67    a.setValue<float>("3.14"); // a has now the type float and "3.14" gets converted to 3.14f
68    a.convert<bool>();         // converts 3.14f to bool, which is true
69    a = false;                 // assigns false, this is equivalent to a.setValue(false)
70    @endcode
71
72    You can pass a MultiType to a function as an argument, even if the argument is
73    not of type MultiType. This works, because the MultiType is automatically converted
74    to the right type.
75
76    Example:
77    @code
78    void myfunction(int value)
79    {
80        COUT(0) << "doubled value is " << (2 * value) << std::endl;
81    }
82
83    MultiType a = "50";        // Note: We assigned a string
84    myfunction(a);             // a is converted to int and passed to the function, which prints "value is 100"
85    @endcode
86
87    Note however that it is of course quite expensive to convert values, especially std::string <-> value.
88    So if you can, always assign a value with the right type to avoid conversion.
89
90    @note
91    Whenever a value gets converted, there is a boolean return value telling you whether it was
92    successful or not. If it wasn't a zero value is assigned with the help of zeroise<T>().
93*/
94
95#ifndef _MultiType_H__
96#define _MultiType_H__
97
98#include "UtilPrereqs.h"
99
100#include <cassert>
101#include <string>
102#include <ogremath/OgreVector2.h>
103#include <ogremath/OgreVector3.h>
104#include <ogremath/OgreVector4.h>
105#include <ogremath/OgreQuaternion.h>
106#include <ogremath/OgreColourValue.h>
107#include <loki/TypeTraits.h>
108#include "mbool.h"
109
110namespace orxonox
111{
112    /**
113        @brief Enum of all possible types of a MultiType.
114    */
115    namespace MT_Type
116    {
117        enum Value
118        {
119            Null,
120            Char,
121            UnsignedChar,
122            Short,
123            UnsignedShort,
124            Int,
125            UnsignedInt,
126            Long,
127            UnsignedLong,
128            LongLong,
129            UnsignedLongLong,
130            Float,
131            Double,
132            LongDouble,
133            Bool,
134            VoidPointer,
135            String,
136            Vector2,
137            Vector3,
138            Vector4,
139            ColourValue,
140            Quaternion,
141            Radian,
142            Degree
143        };
144    }
145
146    /**
147        @brief The MultiType can hold a value of many possible types and convert them to other types.
148
149        The following types are supported by the MultiType:
150         - all primitves
151         - all pointers
152         - string
153         - Vector2, Vector3, Vector4
154         - Quaternion
155         - ColourValue
156         - Radian, Degree
157
158        For more information and some examples see the description @ref MultiTypeExamples "here".
159
160        @see MultiType.h
161    */
162    class _UtilExport MultiType
163    {
164        _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
165        template <typename T> friend class MT_Value;
166
167    public:
168        /**
169            @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType.
170            This class is only used within the MultiType.
171        */
172        class _UtilExport MT_ValueBase
173        {
174        public:
175            MT_ValueBase(MT_Type::Value type) : type_(type), bHasDefaultValue_(false) {}
176            virtual ~MT_ValueBase() {}
177
178            virtual MT_ValueBase* clone() const = 0;
179
180            virtual void reset() = 0;
181            virtual bool assimilate(const MultiType& other) = 0;
182
183            /// Returns the type of the current value.
184            const MT_Type::Value& getType() const { return this->type_; }
185
186            /// Checks whether the value is a default one.
187            bool hasDefaultValue()   const { return this->bHasDefaultValue_; }
188
189            virtual bool setValue(const char& value)                 = 0;
190            virtual bool setValue(const unsigned char& value)        = 0;
191            virtual bool setValue(const short& value)                = 0;
192            virtual bool setValue(const unsigned short& value)       = 0;
193            virtual bool setValue(const int& value)                  = 0;
194            virtual bool setValue(const unsigned int& value)         = 0;
195            virtual bool setValue(const long& value)                 = 0;
196            virtual bool setValue(const unsigned long& value)        = 0;
197            virtual bool setValue(const long long& value)            = 0;
198            virtual bool setValue(const unsigned long long& value)   = 0;
199            virtual bool setValue(const float& value)                = 0;
200            virtual bool setValue(const double& value)               = 0;
201            virtual bool setValue(const long double& value)          = 0;
202            virtual bool setValue(const bool& value)                 = 0;
203            virtual bool setValue(      void* const& value)          = 0;
204            virtual bool setValue(const std::string& value)          = 0;
205            virtual bool setValue(const orxonox::Vector2& value)     = 0;
206            virtual bool setValue(const orxonox::Vector3& value)     = 0;
207            virtual bool setValue(const orxonox::Vector4& value)     = 0;
208            virtual bool setValue(const orxonox::ColourValue& value) = 0;
209            virtual bool setValue(const orxonox::Quaternion& value)  = 0;
210            virtual bool setValue(const orxonox::Radian& value)      = 0;
211            virtual bool setValue(const orxonox::Degree& value)      = 0;
212
213            virtual bool getValue(char*                 value) const = 0;
214            virtual bool getValue(unsigned char*        value) const = 0;
215            virtual bool getValue(short*                value) const = 0;
216            virtual bool getValue(unsigned short*       value) const = 0;
217            virtual bool getValue(int*                  value) const = 0;
218            virtual bool getValue(unsigned int*         value) const = 0;
219            virtual bool getValue(long*                 value) const = 0;
220            virtual bool getValue(unsigned long*        value) const = 0;
221            virtual bool getValue(long long*            value) const = 0;
222            virtual bool getValue(unsigned long long*   value) const = 0;
223            virtual bool getValue(float*                value) const = 0;
224            virtual bool getValue(double*               value) const = 0;
225            virtual bool getValue(long double*          value) const = 0;
226            virtual bool getValue(bool*                 value) const = 0;
227            virtual bool getValue(void**                value) const = 0;
228            virtual bool getValue(std::string*          value) const = 0;
229            virtual bool getValue(orxonox::Vector2*     value) const = 0;
230            virtual bool getValue(orxonox::Vector3*     value) const = 0;
231            virtual bool getValue(orxonox::Vector4*     value) const = 0;
232            virtual bool getValue(orxonox::ColourValue* value) const = 0;
233            virtual bool getValue(orxonox::Quaternion*  value) const = 0;
234            virtual bool getValue(orxonox::Radian*      value) const = 0;
235            virtual bool getValue(orxonox::Degree*      value) const = 0;
236
237            virtual operator char()                 const = 0;
238            virtual operator unsigned char()        const = 0;
239            virtual operator short()                const = 0;
240            virtual operator unsigned short()       const = 0;
241            virtual operator int()                  const = 0;
242            virtual operator unsigned int()         const = 0;
243            virtual operator long()                 const = 0;
244            virtual operator unsigned long()        const = 0;
245            virtual operator long long()            const = 0;
246            virtual operator unsigned long long()   const = 0;
247            virtual operator float()                const = 0;
248            virtual operator double()               const = 0;
249            virtual operator long double()          const = 0;
250            virtual operator bool()                 const = 0;
251            virtual operator void*()                const = 0;
252            virtual operator std::string()          const = 0;
253            virtual operator orxonox::Vector2()     const = 0;
254            virtual operator orxonox::Vector3()     const = 0;
255            virtual operator orxonox::Vector4()     const = 0;
256            virtual operator orxonox::ColourValue() const = 0;
257            virtual operator orxonox::Quaternion()  const = 0;
258            virtual operator orxonox::Radian()      const = 0;
259            virtual operator orxonox::Degree()      const = 0;
260
261            virtual void toString(std::ostream& outstream) const = 0;
262
263            MT_Type::Value type_;   ///< The type of the current value
264            bool bHasDefaultValue_; ///< True if the last conversion wasn't successful
265        };
266
267        public:
268            inline MultiType()                                  : value_(0) {}                                      ///< Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value.
269            inline MultiType(const char& value)                 : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
270            inline MultiType(const unsigned char& value)        : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
271            inline MultiType(const short& value)                : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
272            inline MultiType(const unsigned short& value)       : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
273            inline MultiType(const int& value)                  : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
274            inline MultiType(const unsigned int& value)         : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
275            inline MultiType(const long& value)                 : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
276            inline MultiType(const unsigned long& value)        : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
277            inline MultiType(const long long& value)            : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
278            inline MultiType(const unsigned long long& value)   : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
279            inline MultiType(const float& value)                : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
280            inline MultiType(const double& value)               : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
281            inline MultiType(const long double& value)          : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
282            inline MultiType(const bool& value)                 : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
283            inline MultiType(      void* const& value)          : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
284            inline MultiType(const std::string& value)          : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
285            inline MultiType(const orxonox::Vector2& value)     : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
286            inline MultiType(const orxonox::Vector3& value)     : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
287            inline MultiType(const orxonox::Vector4& value)     : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
288            inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
289            inline MultiType(const orxonox::Quaternion& value)  : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
290            inline MultiType(const orxonox::Radian& value)      : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
291            inline MultiType(const orxonox::Degree& value)      : value_(0) { this->assignValue(value); }           ///< Constructor: Assigns the given value and sets the type.
292            inline MultiType(const orxonox::mbool& value)       : value_(0) { this->assignValue((bool)value); }     ///< Constructor: Assigns the given mbool and converts it to bool.
293            inline MultiType(const char* value)                 : value_(0) { this->setValue(std::string(value)); } ///< Constructor: Converts the char array to a std::string, assigns the value and sets the type.
294            inline MultiType(const MultiType& other)            : value_(0) { this->setValue(other); }              ///< Copyconstructor: Assigns value and type of the other MultiType.
295            inline MultiType(MT_Type::Value type)               : value_(0) { this->setType(type); }                ///< Constructor: Sets the type, the next assignment will determine the value.
296
297            /// Destructor: Deletes the MT_Value.
298            inline ~MultiType() { if (this->value_) { delete this->value_; } }
299
300            template <typename V> inline MultiType& operator=(const V& value)         { this->setValue(value); return (*this); } ///< Assigns a new value. The value will be converted to the current type of the MultiType.
301            template <typename V> inline MultiType& operator=(V* value)               { this->setValue(value); return (*this); } ///< Assigns a pointer.
302            inline                       MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } ///< Assigns the value of the other MultiType and converts it to the current type of the MultiType.
303            inline                       MultiType& operator=(MT_Type::Value type)    { this->setType(type);   return (*this); } ///< Resets the value and changes the type.
304
305            inline bool                                   setValue(const char& value);
306            inline bool                                   setValue(const unsigned char& value);
307            inline bool                                   setValue(const short& value);
308            inline bool                                   setValue(const unsigned short& value);
309            inline bool                                   setValue(const int& value);
310            inline bool                                   setValue(const unsigned int& value);
311            inline bool                                   setValue(const long& value);
312            inline bool                                   setValue(const unsigned long& value);
313            inline bool                                   setValue(const long long& value);
314            inline bool                                   setValue(const unsigned long long& value);
315            inline bool                                   setValue(const float& value);
316            inline bool                                   setValue(const double& value);
317            inline bool                                   setValue(const long double& value);
318            inline bool                                   setValue(const bool& value);
319            inline bool                                   setValue(      void* const& value);
320            inline bool                                   setValue(const std::string& value);
321            inline bool                                   setValue(const orxonox::Vector2& value);
322            inline bool                                   setValue(const orxonox::Vector3& value);
323            inline bool                                   setValue(const orxonox::Vector4& value);
324            inline bool                                   setValue(const orxonox::ColourValue& value);
325            inline bool                                   setValue(const orxonox::Quaternion& value);
326            inline bool                                   setValue(const orxonox::Radian& value);
327            inline bool                                   setValue(const orxonox::Degree& value);
328            inline bool                                   setValue(const char* value);
329            /// Assigns a pointer.
330            template <typename V> inline bool setValue(V* value)
331            {
332                if (this->value_)
333                    return this->value_->setValue(static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
334                else
335                    return this->assignValue     (static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
336            }
337            /// Assigns the value of the other MultiType and converts it to the current type.
338            bool                                          setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } }
339            /// Changes the type to T and assigns the new value (which might be of another type than T - it gets converted).
340            template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); }
341
342
343            /// Copies the other MultiType by assigning value and type.
344            inline void                       copy(const MultiType& other)    { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; }
345
346            /// Converts the current value to type T.
347            template <typename T> inline bool convert()                       { return this->setValue<T>((typename Loki::TypeTraits<T>::UnqualifiedReferredType)(*this));  }
348            /// Converts the current value to the type of the other MultiType.
349            inline bool                       convert(const MultiType& other) { return this->convert(other.getType()); }
350            bool                              convert(MT_Type::Value type);
351
352            /// Current content gets deleted. New type is MT_Type::Null
353            inline void                       reset()                         { if (this->value_) delete this->value_; this->value_ = 0; }
354            /// Current content gets overridden with default zero value
355            inline void                       resetValue()                    { if (this->value_) this->value_->reset(); }
356
357            /// Resets the value and changes the internal type to T.
358            template <typename T> inline void setType()                       { this->assignValue(typename Loki::TypeTraits<T>::UnqualifiedReferredType()); }
359            /// Resets the value and changes the internal type to the type of the other MultiType.
360            inline void                       setType(const MultiType& other) { this->setType(other.getType());                                             }
361            /// Resets the value and changes the internal type to the given type.
362            inline void                       setType(MT_Type::Value type)    { this->reset(); this->convert(type); this->resetValue();                     }
363
364            /// Returns the current type.
365            inline MT_Type::Value             getType()                   const { return (this->value_) ? this->value_->type_ : MT_Type::Null; }
366            /// Returns true if the current type equals the given type.
367            inline bool                       isType(MT_Type::Value type) const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_Type::Null); }
368            /// Returns true if the current type is T.
369            template <typename T> inline bool isType()                    const { return false; } // Only works for specialized values - see below
370            std::string                       getTypename()               const;
371
372            /// Checks whether the value is a default one (assigned after a failed conversion)
373            bool                              hasDefaultValue() const { return this->value_->hasDefaultValue(); }
374
375            /// Checks if the MT contains no value.
376            bool                              null() const { return (!this->value_); }
377
378            operator char()                  const;
379            operator unsigned char()         const;
380            operator short()                 const;
381            operator unsigned short()        const;
382            operator int()                   const;
383            operator unsigned int()          const;
384            operator long()                  const;
385            operator unsigned long()         const;
386            operator long long()             const;
387            operator unsigned long long()    const;
388            operator float()                 const;
389            operator double()                const;
390            operator long double()           const;
391            operator bool()                  const;
392            operator void*()                 const;
393            operator std::string()           const;
394            operator orxonox::Vector2()      const;
395            operator orxonox::Vector3()      const;
396            operator orxonox::Vector4()      const;
397            operator orxonox::ColourValue()  const;
398            operator orxonox::Quaternion()   const;
399            operator orxonox::Radian()       const;
400            operator orxonox::Degree()       const;
401            /// Returns the current value, converted to a T* pointer.
402            template <class T> operator T*() const { return (static_cast<T*>(this->operator void*())); }
403
404            inline bool getValue(char*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
405            inline bool getValue(unsigned char*        value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
406            inline bool getValue(short*                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
407            inline bool getValue(unsigned short*       value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
408            inline bool getValue(int*                  value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
409            inline bool getValue(unsigned int*         value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
410            inline bool getValue(long*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
411            inline bool getValue(unsigned long*        value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
412            inline bool getValue(long long*            value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
413            inline bool getValue(unsigned long long*   value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
414            inline bool getValue(float*                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
415            inline bool getValue(double*               value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
416            inline bool getValue(long double*          value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
417            inline bool getValue(bool*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
418            inline bool getValue(void**                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
419            inline bool getValue(std::string*          value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
420            inline bool getValue(orxonox::Vector2*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
421            inline bool getValue(orxonox::Vector3*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
422            inline bool getValue(orxonox::Vector4*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
423            inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
424            inline bool getValue(orxonox::Quaternion*  value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
425            inline bool getValue(orxonox::Radian*      value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
426            inline bool getValue(orxonox::Degree*      value) const { if (this->value_) { return this->value_->getValue(value); } return false; } ///< Assigns the value to the given pointer. The value gets converted if the types don't match.
427
428            inline char                     getChar()             const { return this->operator char();                 } ///< Returns the current value, converted to the requested type.
429            inline unsigned char            getUnsignedChar()     const { return this->operator unsigned char();        } ///< Returns the current value, converted to the requested type.
430            inline short                    getShort()            const { return this->operator short();                } ///< Returns the current value, converted to the requested type.
431            inline unsigned short           getUnsignedShort()    const { return this->operator unsigned short();       } ///< Returns the current value, converted to the requested type.
432            inline int                      getInt()              const { return this->operator int();                  } ///< Returns the current value, converted to the requested type.
433            inline unsigned int             getUnsignedInt()      const { return this->operator unsigned int();         } ///< Returns the current value, converted to the requested type.
434            inline long                     getLong()             const { return this->operator long();                 } ///< Returns the current value, converted to the requested type.
435            inline unsigned long            getUnsignedLong()     const { return this->operator unsigned long();        } ///< Returns the current value, converted to the requested type.
436            inline long long                getLongLong()         const { return this->operator long long();            } ///< Returns the current value, converted to the requested type.
437            inline unsigned long long       getUnsignedLongLong() const { return this->operator unsigned long long();   } ///< Returns the current value, converted to the requested type.
438            inline float                    getFloat()            const { return this->operator float();                } ///< Returns the current value, converted to the requested type.
439            inline double                   getDouble()           const { return this->operator double();               } ///< Returns the current value, converted to the requested type.
440            inline long double              getLongDouble()       const { return this->operator long double();          } ///< Returns the current value, converted to the requested type.
441            inline bool                     getBool()             const { return this->operator bool();                 } ///< Returns the current value, converted to the requested type.
442            inline void*                    getVoid()             const { return this->operator void*();                } ///< Returns the current value, converted to the requested type.
443            inline std::string              getString()           const { return this->operator std::string();          } ///< Returns the current value, converted to the requested type.
444            inline orxonox::Vector2         getVector2()          const { return this->operator orxonox::Vector2();     } ///< Returns the current value, converted to the requested type.
445            inline orxonox::Vector3         getVector3()          const { return this->operator orxonox::Vector3();     } ///< Returns the current value, converted to the requested type.
446            inline orxonox::Vector4         getVector4()          const { return this->operator orxonox::Vector4();     } ///< Returns the current value, converted to the requested type.
447            inline orxonox::ColourValue     getColourValue()      const { return this->operator orxonox::ColourValue(); } ///< Returns the current value, converted to the requested type.
448            inline orxonox::Quaternion      getQuaternion()       const { return this->operator orxonox::Quaternion();  } ///< Returns the current value, converted to the requested type.
449            inline orxonox::Radian          getRadian()           const { return this->operator orxonox::Radian();      } ///< Returns the current value, converted to the requested type.
450            inline orxonox::Degree          getDegree()           const { return this->operator orxonox::Degree();      } ///< Returns the current value, converted to the requested type.
451            template <typename T> inline T* getPointer()          const { return static_cast<T*>(this->getVoid());      } ///< Returns the current value, converted to a T* pointer.
452
453        private:
454            inline bool assignValue(const char& value)                 { if (this->value_ && this->value_->type_ == MT_Type::Char)             { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value);                 return true; } } ///< Assigns a new value by changing type and creating a new container.
455            inline bool assignValue(const unsigned char& value)        { if (this->value_ && this->value_->type_ == MT_Type::UnsignedChar)     { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value);        return true; } } ///< Assigns a new value by changing type and creating a new container.
456            inline bool assignValue(const short& value)                { if (this->value_ && this->value_->type_ == MT_Type::Short)            { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value);                return true; } } ///< Assigns a new value by changing type and creating a new container.
457            inline bool assignValue(const unsigned short& value)       { if (this->value_ && this->value_->type_ == MT_Type::UnsignedShort)    { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value);       return true; } } ///< Assigns a new value by changing type and creating a new container.
458            inline bool assignValue(const int& value)                  { if (this->value_ && this->value_->type_ == MT_Type::Int)              { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value);                  return true; } } ///< Assigns a new value by changing type and creating a new container.
459            inline bool assignValue(const unsigned int& value)         { if (this->value_ && this->value_->type_ == MT_Type::UnsignedInt)      { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value);         return true; } } ///< Assigns a new value by changing type and creating a new container.
460            inline bool assignValue(const long& value)                 { if (this->value_ && this->value_->type_ == MT_Type::Long)             { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value);                 return true; } } ///< Assigns a new value by changing type and creating a new container.
461            inline bool assignValue(const unsigned long& value)        { if (this->value_ && this->value_->type_ == MT_Type::UnsignedLong)     { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value);        return true; } } ///< Assigns a new value by changing type and creating a new container.
462            inline bool assignValue(const long long& value)            { if (this->value_ && this->value_->type_ == MT_Type::LongLong)         { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value);            return true; } } ///< Assigns a new value by changing type and creating a new container.
463            inline bool assignValue(const unsigned long long& value)   { if (this->value_ && this->value_->type_ == MT_Type::UnsignedLongLong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value);   return true; } } ///< Assigns a new value by changing type and creating a new container.
464            inline bool assignValue(const float& value)                { if (this->value_ && this->value_->type_ == MT_Type::Float)            { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value);                return true; } } ///< Assigns a new value by changing type and creating a new container.
465            inline bool assignValue(const double& value)               { if (this->value_ && this->value_->type_ == MT_Type::Double)           { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value);               return true; } } ///< Assigns a new value by changing type and creating a new container.
466            inline bool assignValue(const long double& value)          { if (this->value_ && this->value_->type_ == MT_Type::LongDouble)       { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value);          return true; } } ///< Assigns a new value by changing type and creating a new container.
467            inline bool assignValue(const bool& value)                 { if (this->value_ && this->value_->type_ == MT_Type::Bool)             { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value);                 return true; } } ///< Assigns a new value by changing type and creating a new container.
468            inline bool assignValue(      void* const& value)          { if (this->value_ && this->value_->type_ == MT_Type::VoidPointer)      { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value);                return true; } } ///< Assigns a new value by changing type and creating a new container.
469            inline bool assignValue(const std::string& value)          { if (this->value_ && this->value_->type_ == MT_Type::String)           { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value);          return true; } } ///< Assigns a new value by changing type and creating a new container.
470            inline bool assignValue(const orxonox::Vector2& value)     { if (this->value_ && this->value_->type_ == MT_Type::Vector2)          { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value);     return true; } } ///< Assigns a new value by changing type and creating a new container.
471            inline bool assignValue(const orxonox::Vector3& value)     { if (this->value_ && this->value_->type_ == MT_Type::Vector3)          { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value);     return true; } } ///< Assigns a new value by changing type and creating a new container.
472            inline bool assignValue(const orxonox::Vector4& value)     { if (this->value_ && this->value_->type_ == MT_Type::Vector4)          { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value);     return true; } } ///< Assigns a new value by changing type and creating a new container.
473            inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_Type::ColourValue)      { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } ///< Assigns a new value by changing type and creating a new container.
474            inline bool assignValue(const orxonox::Quaternion& value)  { if (this->value_ && this->value_->type_ == MT_Type::Quaternion)       { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value);  return true; } } ///< Assigns a new value by changing type and creating a new container.
475            inline bool assignValue(const orxonox::Radian& value)      { if (this->value_ && this->value_->type_ == MT_Type::Radian)           { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value);      return true; } } ///< Assigns a new value by changing type and creating a new container.
476            inline bool assignValue(const orxonox::Degree& value)      { if (this->value_ && this->value_->type_ == MT_Type::Degree)           { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value);      return true; } } ///< Assigns a new value by changing type and creating a new container.
477
478            /// Changes the value container.
479            template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); }
480            /// Creates a new value container (works only with specialized types).
481            template <typename T>        void createNewValueContainer(const T& value) { /* STATIC ASSERT */ *****value; return false; }
482
483            MT_ValueBase* value_; //!< A pointer to the value container
484    };
485
486    /// Puts the MultiType on a stream by using the native << operator of the current type.
487    _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; }
488
489    template <> inline bool MultiType::isType<char>()                 const { return (this->value_ && this->value_->type_ == MT_Type::Char);             } ///< Returns true if the current type equals the given type.
490    template <> inline bool MultiType::isType<unsigned char>()        const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedChar);     } ///< Returns true if the current type equals the given type.
491    template <> inline bool MultiType::isType<short>()                const { return (this->value_ && this->value_->type_ == MT_Type::Short);            } ///< Returns true if the current type equals the given type.
492    template <> inline bool MultiType::isType<unsigned short>()       const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedShort);    } ///< Returns true if the current type equals the given type.
493    template <> inline bool MultiType::isType<int>()                  const { return (this->value_ && this->value_->type_ == MT_Type::Int);              } ///< Returns true if the current type equals the given type.
494    template <> inline bool MultiType::isType<unsigned int>()         const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedInt);      } ///< Returns true if the current type equals the given type.
495    template <> inline bool MultiType::isType<long>()                 const { return (this->value_ && this->value_->type_ == MT_Type::Long);             } ///< Returns true if the current type equals the given type.
496    template <> inline bool MultiType::isType<unsigned long>()        const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedLong);     } ///< Returns true if the current type equals the given type.
497    template <> inline bool MultiType::isType<long long>()            const { return (this->value_ && this->value_->type_ == MT_Type::LongLong);         } ///< Returns true if the current type equals the given type.
498    template <> inline bool MultiType::isType<unsigned long long>()   const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedLongLong); } ///< Returns true if the current type equals the given type.
499    template <> inline bool MultiType::isType<float>()                const { return (this->value_ && this->value_->type_ == MT_Type::Float);            } ///< Returns true if the current type equals the given type.
500    template <> inline bool MultiType::isType<double>()               const { return (this->value_ && this->value_->type_ == MT_Type::Double);           } ///< Returns true if the current type equals the given type.
501    template <> inline bool MultiType::isType<long double>()          const { return (this->value_ && this->value_->type_ == MT_Type::LongDouble);       } ///< Returns true if the current type equals the given type.
502    template <> inline bool MultiType::isType<bool>()                 const { return (this->value_ && this->value_->type_ == MT_Type::Bool);             } ///< Returns true if the current type equals the given type.
503    template <> inline bool MultiType::isType<void*>()                const { return (this->value_ && this->value_->type_ == MT_Type::VoidPointer);      } ///< Returns true if the current type equals the given type.
504    template <> inline bool MultiType::isType<std::string>()          const { return (this->value_ && this->value_->type_ == MT_Type::String);           } ///< Returns true if the current type equals the given type.
505    template <> inline bool MultiType::isType<orxonox::Vector2>()     const { return (this->value_ && this->value_->type_ == MT_Type::Vector2);          } ///< Returns true if the current type equals the given type.
506    template <> inline bool MultiType::isType<orxonox::Vector3>()     const { return (this->value_ && this->value_->type_ == MT_Type::Vector3);          } ///< Returns true if the current type equals the given type.
507    template <> inline bool MultiType::isType<orxonox::Vector4>()     const { return (this->value_ && this->value_->type_ == MT_Type::Vector4);          } ///< Returns true if the current type equals the given type.
508    template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_Type::ColourValue);      } ///< Returns true if the current type equals the given type.
509    template <> inline bool MultiType::isType<orxonox::Quaternion>()  const { return (this->value_ && this->value_->type_ == MT_Type::Quaternion);       } ///< Returns true if the current type equals the given type.
510    template <> inline bool MultiType::isType<orxonox::Radian>()      const { return (this->value_ && this->value_->type_ == MT_Type::Radian);           } ///< Returns true if the current type equals the given type.
511    template <> inline bool MultiType::isType<orxonox::Degree>()      const { return (this->value_ && this->value_->type_ == MT_Type::Degree);           } ///< Returns true if the current type equals the given type.
512
513    /// Deletes the content, type becomes MT_Type::Null.
514    template <> inline bool MultiType::convert<void>()                 { this->reset(); return true; }
515
516    // Specialization to avoid ambiguities with the conversion operator
517    template <> inline bool MultiType::convert<std::string>()          { return this->setValue<std::string>         (this->operator std::string());          } ///< Converts the current value to the given type.
518    template <> inline bool MultiType::convert<orxonox::Vector2>()     { return this->setValue<orxonox::Vector2>    (this->operator orxonox::Vector2());     } ///< Converts the current value to the given type.
519    template <> inline bool MultiType::convert<orxonox::Vector3>()     { return this->setValue<orxonox::Vector3>    (this->operator orxonox::Vector3());     } ///< Converts the current value to the given type.
520    template <> inline bool MultiType::convert<orxonox::Vector4>()     { return this->setValue<orxonox::Vector4>    (this->operator orxonox::Vector4());     } ///< Converts the current value to the given type.
521    template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } ///< Converts the current value to the given type.
522    template <> inline bool MultiType::convert<orxonox::Quaternion>()  { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion());  } ///< Converts the current value to the given type.
523    template <> inline bool MultiType::convert<orxonox::Radian>()      { return this->setValue<orxonox::Radian>     (this->operator orxonox::Radian());      } ///< Converts the current value to the given type.
524    template <> inline bool MultiType::convert<orxonox::Degree>()      { return this->setValue<orxonox::Degree>     (this->operator orxonox::Degree());      } ///< Converts the current value to the given type.
525
526    // Specialization to avoid ambiguities with the conversion operator
527    template <> inline bool MultiType::convert<const std::string&>()          { return this->convert<std::string>();          } ///< Converts the current value to the given type.
528    template <> inline bool MultiType::convert<const orxonox::Vector2&>()     { return this->convert<orxonox::Vector2>();     } ///< Converts the current value to the given type.
529    template <> inline bool MultiType::convert<const orxonox::Vector3&>()     { return this->convert<orxonox::Vector3>();     } ///< Converts the current value to the given type.
530    template <> inline bool MultiType::convert<const orxonox::Vector4&>()     { return this->convert<orxonox::Vector4>();     } ///< Converts the current value to the given type.
531    template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } ///< Converts the current value to the given type.
532    template <> inline bool MultiType::convert<const orxonox::Quaternion&>()  { return this->convert<orxonox::Quaternion>();  } ///< Converts the current value to the given type.
533    template <> inline bool MultiType::convert<const orxonox::Radian&>()      { return this->convert<orxonox::Radian>();      } ///< Converts the current value to the given type.
534    template <> inline bool MultiType::convert<const orxonox::Degree&>()      { return this->convert<orxonox::Degree>();      } ///< Converts the current value to the given type.
535
536    template <> _UtilExport void MultiType::createNewValueContainer(const char& value);
537    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned char& value);
538    template <> _UtilExport void MultiType::createNewValueContainer(const short& value);
539    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned short& value);
540    template <> _UtilExport void MultiType::createNewValueContainer(const int& value);
541    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned int& value);
542    template <> _UtilExport void MultiType::createNewValueContainer(const long& value);
543    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned long& value);
544    template <> _UtilExport void MultiType::createNewValueContainer(const long long& value);
545    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned long long& value);
546    template <> _UtilExport void MultiType::createNewValueContainer(const float& value);
547    template <> _UtilExport void MultiType::createNewValueContainer(const double& value);
548    template <> _UtilExport void MultiType::createNewValueContainer(const bool& value);
549    template <> _UtilExport void MultiType::createNewValueContainer(const long double& value);
550    template <> _UtilExport void MultiType::createNewValueContainer(      void* const& value);
551    template <> _UtilExport void MultiType::createNewValueContainer(const std::string& value);
552    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Vector2& value);
553    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Vector3& value);
554    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Vector4& value);
555    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::ColourValue& value);
556    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Quaternion& value);
557    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Radian& value);
558    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Degree& value);
559
560    inline bool MultiType::setValue(const char& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
561    inline bool MultiType::setValue(const unsigned char& value)         { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
562    inline bool MultiType::setValue(const short& value)                 { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
563    inline bool MultiType::setValue(const unsigned short& value)        { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
564    inline bool MultiType::setValue(const int& value)                   { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
565    inline bool MultiType::setValue(const unsigned int& value)          { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
566    inline bool MultiType::setValue(const long& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
567    inline bool MultiType::setValue(const unsigned long& value)         { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
568    inline bool MultiType::setValue(const long long& value)             { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
569    inline bool MultiType::setValue(const unsigned long long& value)    { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
570    inline bool MultiType::setValue(const float& value)                 { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
571    inline bool MultiType::setValue(const double& value)                { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
572    inline bool MultiType::setValue(const long double& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
573    inline bool MultiType::setValue(const bool& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
574    inline bool MultiType::setValue(      void* const& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
575    inline bool MultiType::setValue(const std::string& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
576    inline bool MultiType::setValue(const orxonox::Vector2& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
577    inline bool MultiType::setValue(const orxonox::Vector3& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
578    inline bool MultiType::setValue(const orxonox::Vector4& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
579    inline bool MultiType::setValue(const orxonox::ColourValue& value)  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
580    inline bool MultiType::setValue(const orxonox::Quaternion& value)   { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
581    inline bool MultiType::setValue(const orxonox::Radian& value)       { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
582    inline bool MultiType::setValue(const orxonox::Degree& value)       { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } ///< Assigns the given value and converts it to the current type.
583
584    /// Assigns the given value and converts it to the current type.
585    inline bool MultiType::setValue(const char* value)                  { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } }
586}
587
588#endif /* _MultiType_H__ */
Note: See TracBrowser for help on using the repository browser.