Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/util/MultiType.h

Last change on this file was 11098, checked in by muemart, 8 years ago

Minor C++11 improvements:

  • Drop ImplicitConversion.h in favor of std::is_convertible.
  • Move constructor & assignment for MultiType and SubString. I'm not sure if the MultiType should convert types when moving. Currently it doesn't, because otherwise it would have no benefit over copying.
  • Use standard library functions for sleeping.
  • Property svn:eol-style set to native
File size: 28.5 KB
RevLine 
[1505]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
[1791]29/**
[7401]30    @defgroup MultiType MultiType
31    @ingroup Util
32*/
33
34/**
[2171]35    @file
[7401]36    @ingroup MultiType
[1791]37    @brief Declaration of the MultiType and some helper constructs.
38
[7401]39    @anchor MultiTypeExamples
40
[1791]41    The MultiType can hold a value of one of the following types:
[7401]42     - all primitives (int, float, bool, etc.)
43     - all pointers (void* and T*)
44     - std::string
[1791]45     - Vector2, Vector3, Vector4
46     - Quaternion
47     - ColourValue
48     - Radian, Degree
49
[7401]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=())
[9550]53     - @ref orxonox::MultiType::set() "set(value)"
[1791]54
[7401]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
[1791]58    If you want to change the type, there are three possibilities:
[7401]59     - @ref orxonox::MultiType::convert "convert<T>()" sets the type to T and converts the currently assigned value
[9550]60     - @ref orxonox::MultiType::reset "reset<T>()" sets the type to T and resets the value to zero using zeroise<T>()
61     - force<T>(value) assigns a new value and changes the type to T.
[1791]62
[7401]63    Examples:
64    @code
[9550]65    MultiType a = 10;       // a has now the type int and the value 10
66    a.set("3.14");          // a has still the type int and "3.14" gets converted, therefore the value is now 3
67    a.force<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)
[7401]70    @endcode
[2087]71
[7401]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    {
[8858]80        orxout() << "doubled value is " << (2 * value) << endl;
[7401]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
[2087]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>().
[1791]93*/
94
[1505]95#ifndef _MultiType_H__
96#define _MultiType_H__
97
98#include "UtilPrereqs.h"
99
[3196]100#include <cassert>
101#include <string>
[11098]102#include <utility>
[3196]103#include <OgreVector2.h>
104#include <OgreVector3.h>
105#include <OgreVector4.h>
106#include <OgreQuaternion.h>
107#include <OgreColourValue.h>
[7266]108#include <loki/TypeTraits.h>
[9550]109#include "Math.h"
[7284]110#include "mbool.h"
[1747]111
[2171]112namespace orxonox
[1505]113{
[2171]114    /**
115        @brief The MultiType can hold a value of many possible types and convert them to other types.
[1791]116
[2171]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
[1791]125
[7401]126        For more information and some examples see the description @ref MultiTypeExamples "here".
127
128        @see MultiType.h
[1791]129    */
[2171]130    class _UtilExport MultiType
[1747]131    {
[2171]132        _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
133        template <typename T> friend class MT_Value;
[1747]134
[11071]135        /**
136            @brief Enum of all possible types of a MultiType.
137        */
138        enum class Type : uint8_t
[9550]139        {
[11071]140            Null,
141            Char,
142            UnsignedChar,
143            Short,
144            UnsignedShort,
145            Int,
146            UnsignedInt,
147            Long,
148            UnsignedLong,
149            LongLong,
150            UnsignedLongLong,
151            Float,
152            Double,
153            LongDouble,
154            Bool,
155            VoidPointer,
156            String,
157            Vector2,
158            Vector3,
159            Vector4,
160            ColourValue,
161            Quaternion,
162            Radian,
163            Degree
[9550]164        };
165
[2171]166    public:
167        /**
168            @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType.
169            This class is only used within the MultiType.
170        */
171        class _UtilExport MT_ValueBase
172        {
173        public:
[11071]174            inline MT_ValueBase(void* data, Type type) : type_(type), bLastConversionSuccessful(true), data_(data) {}
175            virtual inline ~MT_ValueBase() {}
[1747]176
[2171]177            virtual MT_ValueBase* clone() const = 0;
[1791]178
[2171]179            virtual void reset() = 0;
[1747]180
[7401]181            /// Returns the type of the current value.
[11071]182            inline const Type& getType() const { return this->type_; }
[1747]183
[11071]184            /// Returns true if the type of the stored value is T. Note: the actual implementations for all supported types are defined outside of the class.
185            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
186            inline /*bool*/ isType() const
187            {
188                // If you reach this code, you used MultiType with an unsupported type T
189                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
190                return false;
191            }
192            /// Implementation for enum classes: Returns true if the type of the stored value is the underlying type of T.
193            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
194            inline /*bool*/ isType() const
195            {
196                return this->isType<typename std::underlying_type<T>::type>();
197            }
198
[7401]199            /// Checks whether the value is a default one.
[9550]200            inline bool lastConversionSuccessful()   const { return this->bLastConversionSuccessful; }
[2087]201
[2171]202            virtual bool setValue(const char& value)                 = 0;
203            virtual bool setValue(const unsigned char& value)        = 0;
204            virtual bool setValue(const short& value)                = 0;
205            virtual bool setValue(const unsigned short& value)       = 0;
206            virtual bool setValue(const int& value)                  = 0;
207            virtual bool setValue(const unsigned int& value)         = 0;
208            virtual bool setValue(const long& value)                 = 0;
209            virtual bool setValue(const unsigned long& value)        = 0;
210            virtual bool setValue(const long long& value)            = 0;
211            virtual bool setValue(const unsigned long long& value)   = 0;
212            virtual bool setValue(const float& value)                = 0;
213            virtual bool setValue(const double& value)               = 0;
214            virtual bool setValue(const long double& value)          = 0;
215            virtual bool setValue(const bool& value)                 = 0;
216            virtual bool setValue(      void* const& value)          = 0;
217            virtual bool setValue(const std::string& value)          = 0;
218            virtual bool setValue(const orxonox::Vector2& value)     = 0;
219            virtual bool setValue(const orxonox::Vector3& value)     = 0;
220            virtual bool setValue(const orxonox::Vector4& value)     = 0;
221            virtual bool setValue(const orxonox::ColourValue& value) = 0;
222            virtual bool setValue(const orxonox::Quaternion& value)  = 0;
223            virtual bool setValue(const orxonox::Radian& value)      = 0;
224            virtual bool setValue(const orxonox::Degree& value)      = 0;
[2087]225
[9550]226            virtual bool setValue(const MultiType& other)            = 0;
227
[11071]228            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
229            inline /*bool*/ setValue(const T& value)
230            {
231                // If you reach this code, you used MultiType with an unsupported type T
232                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
233                return false;
234            }
235            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
236            inline /*bool*/ setValue(const T& value)
237            {
238                typedef typename std::underlying_type<T>::type UnderlyingType;
239                return this->setValue(reinterpret_cast<const UnderlyingType&>(value));
240            }
241
[2171]242            virtual bool getValue(char*                 value) const = 0;
243            virtual bool getValue(unsigned char*        value) const = 0;
244            virtual bool getValue(short*                value) const = 0;
245            virtual bool getValue(unsigned short*       value) const = 0;
246            virtual bool getValue(int*                  value) const = 0;
247            virtual bool getValue(unsigned int*         value) const = 0;
248            virtual bool getValue(long*                 value) const = 0;
249            virtual bool getValue(unsigned long*        value) const = 0;
250            virtual bool getValue(long long*            value) const = 0;
251            virtual bool getValue(unsigned long long*   value) const = 0;
252            virtual bool getValue(float*                value) const = 0;
253            virtual bool getValue(double*               value) const = 0;
254            virtual bool getValue(long double*          value) const = 0;
255            virtual bool getValue(bool*                 value) const = 0;
256            virtual bool getValue(void**                value) const = 0;
257            virtual bool getValue(std::string*          value) const = 0;
258            virtual bool getValue(orxonox::Vector2*     value) const = 0;
259            virtual bool getValue(orxonox::Vector3*     value) const = 0;
260            virtual bool getValue(orxonox::Vector4*     value) const = 0;
261            virtual bool getValue(orxonox::ColourValue* value) const = 0;
262            virtual bool getValue(orxonox::Quaternion*  value) const = 0;
263            virtual bool getValue(orxonox::Radian*      value) const = 0;
264            virtual bool getValue(orxonox::Degree*      value) const = 0;
[1747]265
[11071]266            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
267            inline /*bool*/ getValue(T* value) const
268            {
269                // If you reach this code, you used MultiType with an unsupported type T
270                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
271                return false;
272            }
273            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
274            inline /*bool*/ getValue(T* value) const
275            {
276                typedef typename std::underlying_type<T>::type UnderlyingType;
277                return this->getValue(reinterpret_cast<UnderlyingType*>(value));
278            }
279
[9550]280            template <typename T> T get() const
281            {
282                if (this->isType<T>())
283                    return *reinterpret_cast<const T*>(this->data_);
284                else
285                {
286                    T value;
287                    this->getValue(&value);
288                    return value;
289                }
290            }
[1747]291
[2171]292            virtual void toString(std::ostream& outstream) const = 0;
[6417]293
[9550]294            virtual void importData(uint8_t*& mem) = 0;
295            virtual void exportData(uint8_t*& mem) const = 0;
296            virtual uint8_t getSize() const = 0;
[1747]297
[11071]298            Type type_;                     ///< The type of the current value
[9550]299            bool bLastConversionSuccessful; ///< True if the last conversion was successful
300            void* data_;                    ///< For direct access to the value if the type is known
[2171]301        };
[1747]302
[2171]303        public:
[9550]304            static const MultiType Null;
[1747]305
[9550]306            /// Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value.
[11071]307            inline MultiType()                       : value_(nullptr) { }
[9550]308            /// Constructor: Assigns the given value and sets the type.
309            template <typename V>
[11071]310            inline MultiType(const V& value)         : value_(nullptr) { this->set(value); }
[9550]311            /// Copyconstructor: Assigns value and type of the other MultiType.
[11071]312            inline MultiType(const MultiType& other) : value_(nullptr) { this->set(other); }
[11098]313            /// Moveconstructor: Moves the value and its type from the other MultiType
314            inline MultiType(MultiType&& other)      : value_(nullptr) { std::swap(this->value_, other.value_); };
[9550]315
[7401]316            /// Destructor: Deletes the MT_Value.
[2171]317            inline ~MultiType() { if (this->value_) { delete this->value_; } }
[1747]318
[9550]319            /// Assigns a new value. The value will be converted to the current type of the MultiType.
320            template <typename V> inline MultiType& operator=(const V& value)         { this->set(value); return (*this); }
321            /// Assigns a pointer.
322            template <typename V> inline MultiType& operator=(V* value)               { this->set(value); return (*this); }
323            /// Assigns the value of the other MultiType and converts it to the current type of the MultiType.
324            inline                       MultiType& operator=(const MultiType& other) { this->set(other); return (*this); }
[11098]325            /// Moves the value and the type of the other MultiType to this one.
326            inline                       MultiType& operator=(MultiType&& other)      { std::swap(this->value_, other.value_); return (*this); }
[1747]327
[9550]328            /// Assigns the given value and converts it to the current type.
329            template <typename V> inline bool set(const V& value)
330            {
331                if (this->value_)
332                    return this->value_->setValue(value);
333
334                this->assignValue(value);
335                return true;
336            }
[7401]337            /// Assigns a pointer.
[9550]338            template <typename V> inline bool set(V* value)
[3332]339            {
340                if (this->value_)
341                    return this->value_->setValue(static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
[9550]342
343                this->assignValue(static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
344                return true;
[3332]345            }
[7401]346            /// Assigns the value of the other MultiType and converts it to the current type.
[9550]347            inline bool set(const MultiType& other)
348            {
349                if (this->value_)
350                    return this->value_->setValue(other);
351                else if (other.value_)
352                    this->value_ = other.value_->clone();
353                return true;
354            }
355
[7401]356            /// Changes the type to T and assigns the new value (which might be of another type than T - it gets converted).
[9550]357            template <typename T, typename V> inline bool force(const V& value)
358            {
359                this->reset<T>();
360                return this->set(value);
361            }
[1791]362
[7401]363            /// Copies the other MultiType by assigning value and type.
[9550]364            inline void copy(const MultiType& other)
365            {
366                if (this == &other)
367                    return;
368                if (this->value_)
369                    delete this->value_;
[11071]370                this->value_ = (other.value_) ? other.value_->clone() : nullptr;
[9550]371            }
[1747]372
[7401]373            /// Converts the current value to type T.
[9550]374            template <typename T> inline bool convert() { return this->force<T>(MultiType(*this)); }
[1747]375
[9550]376            /// Resets value and type. Type will be void afterwards and null() returns true.
[11071]377            inline void reset() { if (this->value_) delete this->value_; this->value_ = nullptr; }
[7401]378            /// Resets the value and changes the internal type to T.
[9550]379            template <typename T> inline void reset() { this->assignValue(typename Loki::TypeTraits<T>::UnqualifiedReferredType()); }
380            /// Current value gets overridden with default zero value
381            inline void resetValue() { if (this->value_) this->value_->reset(); }
[1747]382
[9550]383            /// Returns true if the type of the current value is T.
384            template <typename T> inline bool isType() const { return (this->value_ ? this->value_->isType<T>() : false); }
385            std::string getTypename() const;
[6417]386
[9550]387            /// Checks whether the last conversion was successful
388            inline bool lastConversionSuccessful() const { return !this->value_ || this->value_->lastConversionSuccessful(); }
[2087]389
[7401]390            /// Checks if the MT contains no value.
[9550]391            inline bool null() const { return !this->value_; }
[7284]392
[10197]393            /// Conversion operator for all types
394            template <class T> operator T()  const { return this->get<T>(); }
[1747]395
[9550]396            /// Assigns the value to the given pointer. The value gets converted if the types don't match.
397            template <typename T> inline bool getValue(T* value) const { if (this->value_) { return this->value_->getValue(value); } return false; }
[1747]398
[11071]399            /// Returns the current value, converted to the requested type.
400            template <typename T> /* for normal types */ typename std::enable_if<!std::is_pointer<T>::value, T>::type
401            inline /*T*/ get() const { return (this->value_ ? this->value_->get<T>() : NilValue<T>()); }
402            /// Returns the current value, converted to a pointer of the requested type.
403            template <typename T> /* for pointers */ typename std::enable_if<std::is_pointer<T>::value, T>::type
404            inline /*T*/ get() const { return this->value_ ? static_cast<T>(this->value_->get<void*>()) : nullptr; }
[1747]405
[9550]406
407            ///////////////////////////////
408            // network-related functions //
409            ///////////////////////////////
410            /// Saves the value of the MT to a bytestream (pointed at by mem) and increases mem pointer by size of MT
411            inline void exportData(uint8_t*& mem) const
412            {
[11071]413                assert(sizeof(Type) <= 8);
414                *static_cast<uint8_t*>(mem) = static_cast<uint8_t>(this->getType());
[9550]415                mem += sizeof(uint8_t);
416                this->value_->exportData(mem);
417            }
418            /// Loads the value of the MT from a bytestream (pointed at by mem) and increases mem pointer by size of MT
419            inline void importData(uint8_t*& mem)
420            {
[11071]421                assert(sizeof(Type) <= 8);
422                this->setType(static_cast<Type>(*static_cast<uint8_t*>(mem)));
[9550]423                mem += sizeof(uint8_t);
424                this->value_->importData(mem);
425            }
426            /// Saves the value of the MT to a bytestream and increases pointer to bytestream by size of MT
427            inline uint8_t*& operator<<(uint8_t*& mem)
428            {
429                importData(mem);
430                return mem;
431            }
432            /// Loads the value of the MT to a bytestream and increases pointer to bytestream by size of MT
433            inline void operator>>(uint8_t*& mem) const
434            {
435                exportData(mem);
436            }
437            inline uint32_t getNetworkSize() const
438            {
439                assert(this->value_);
440                return this->value_->getSize() + sizeof(uint8_t);
441            }
442
[2171]443        private:
[9550]444            /// Assigns a new value by changing type and creating a new container.
445            template <typename T> inline void assignValue(const T& value)
446            {
447                if (this->isType<T>())
448                    this->value_->setValue(value);
449                else
450                    this->changeValueContainer(value);
451            }
452            /// Assigns a new value by changing type and creating a new container (overload for pointers).
453            template <typename T> inline void assignValue(T* const& value)
454            {
455                if (this->isType<void*>())
456                    this->value_->setValue(static_cast<void*>(value));
457                else
458                    this->changeValueContainer<void*>(value);
459            }
[1747]460
[9550]461            /// Resets the value and changes the internal type to the given type.
[11071]462            inline void setType(Type type) { this->reset(); this->convert(type); this->resetValue(); }
[9550]463            /// Returns the current type.
[11071]464            inline Type getType() const { return (this->value_) ? this->value_->type_ : Type::Null; }
[9550]465            /// Converts the current value to the given type.
[11071]466            bool convert(Type type);
[9550]467
[7401]468            /// Changes the value container.
[9550]469            template <typename T> inline void changeValueContainer(const T& value)
470            {
471                if (this->value_)
472                    delete this->value_;
473                this->createNewValueContainer(value);
474            }
[7401]475            /// Creates a new value container (works only with specialized types).
[11071]476            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value>::type
477            inline /*void*/ createNewValueContainer(const T& value)
478            { 
479                // If you reach this code, you used MultiType with an unsupported type T
480                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
481            }
482            /// Creates a new value container (implementation for enum classes that must be cast to the underlying type).
483            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value>::type
484            inline /*void*/ createNewValueContainer(const T& value)
485            {
486                typedef typename std::underlying_type<T>::type UnderlyingType;
487                this->createNewValueContainer<UnderlyingType>(reinterpret_cast<const UnderlyingType&>(value));
488            }
[1505]489
[2171]490            MT_ValueBase* value_; //!< A pointer to the value container
491    };
[1747]492
[7401]493    /// Puts the MultiType on a stream by using the native << operator of the current type.
[9550]494    _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt)
495    {
496        if (mt.value_)
497            mt.value_->toString(outstream);
498        return outstream;
499    }
[1747]500
[9550]501    template <> inline bool MultiType::MT_ValueBase::isType<char>()                 const { return this->type_ == Type::Char;             }
502    template <> inline bool MultiType::MT_ValueBase::isType<unsigned char>()        const { return this->type_ == Type::UnsignedChar;     }
503    template <> inline bool MultiType::MT_ValueBase::isType<short>()                const { return this->type_ == Type::Short;            }
504    template <> inline bool MultiType::MT_ValueBase::isType<unsigned short>()       const { return this->type_ == Type::UnsignedShort;    }
505    template <> inline bool MultiType::MT_ValueBase::isType<int>()                  const { return this->type_ == Type::Int;              }
506    template <> inline bool MultiType::MT_ValueBase::isType<unsigned int>()         const { return this->type_ == Type::UnsignedInt;      }
507    template <> inline bool MultiType::MT_ValueBase::isType<long>()                 const { return this->type_ == Type::Long;             }
508    template <> inline bool MultiType::MT_ValueBase::isType<unsigned long>()        const { return this->type_ == Type::UnsignedLong;     }
509    template <> inline bool MultiType::MT_ValueBase::isType<long long>()            const { return this->type_ == Type::LongLong;         }
510    template <> inline bool MultiType::MT_ValueBase::isType<unsigned long long>()   const { return this->type_ == Type::UnsignedLongLong; }
511    template <> inline bool MultiType::MT_ValueBase::isType<float>()                const { return this->type_ == Type::Float;            }
512    template <> inline bool MultiType::MT_ValueBase::isType<double>()               const { return this->type_ == Type::Double;           }
513    template <> inline bool MultiType::MT_ValueBase::isType<long double>()          const { return this->type_ == Type::LongDouble;       }
514    template <> inline bool MultiType::MT_ValueBase::isType<bool>()                 const { return this->type_ == Type::Bool;             }
515    template <> inline bool MultiType::MT_ValueBase::isType<void*>()                const { return this->type_ == Type::VoidPointer;      }
516    template <> inline bool MultiType::MT_ValueBase::isType<std::string>()          const { return this->type_ == Type::String;           }
517    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::Vector2>()     const { return this->type_ == Type::Vector2;          }
518    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::Vector3>()     const { return this->type_ == Type::Vector3;          }
519    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::Vector4>()     const { return this->type_ == Type::Vector4;          }
520    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::ColourValue>() const { return this->type_ == Type::ColourValue;      }
521    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::Quaternion>()  const { return this->type_ == Type::Quaternion;       }
522    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::Radian>()      const { return this->type_ == Type::Radian;           }
523    template <> inline bool MultiType::MT_ValueBase::isType<orxonox::Degree>()      const { return this->type_ == Type::Degree;           }
[1747]524
[9550]525    template <> inline bool MultiType::set(const char* value)  { return this->set(std::string(value)); }
526    template <> inline bool MultiType::set(const mbool& value) { return this->set((bool)value); }
[7284]527
[9550]528    // Spezializations for void
529    template <> inline bool MultiType::isType<void>() const { return this->null(); }
530    template <> inline bool MultiType::convert<void>() { this->reset(); return true; }
[1747]531
[7165]532    template <> _UtilExport void MultiType::createNewValueContainer(const char& value);
533    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned char& value);
534    template <> _UtilExport void MultiType::createNewValueContainer(const short& value);
535    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned short& value);
536    template <> _UtilExport void MultiType::createNewValueContainer(const int& value);
537    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned int& value);
538    template <> _UtilExport void MultiType::createNewValueContainer(const long& value);
539    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned long& value);
540    template <> _UtilExport void MultiType::createNewValueContainer(const long long& value);
541    template <> _UtilExport void MultiType::createNewValueContainer(const unsigned long long& value);
542    template <> _UtilExport void MultiType::createNewValueContainer(const float& value);
543    template <> _UtilExport void MultiType::createNewValueContainer(const double& value);
544    template <> _UtilExport void MultiType::createNewValueContainer(const bool& value);
545    template <> _UtilExport void MultiType::createNewValueContainer(const long double& value);
546    template <> _UtilExport void MultiType::createNewValueContainer(      void* const& value);
547    template <> _UtilExport void MultiType::createNewValueContainer(const std::string& value);
548    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Vector2& value);
549    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Vector3& value);
550    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Vector4& value);
551    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::ColourValue& value);
552    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Quaternion& value);
553    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Radian& value);
554    template <> _UtilExport void MultiType::createNewValueContainer(const orxonox::Degree& value);
[2171]555}
556
[1505]557#endif /* _MultiType_H__ */
Note: See TracBrowser for help on using the repository browser.