Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SuperOrxoBros_HS18/SuperOrxoBros_HS18/src/libraries/util/MultiType.h @ 12175

Last change on this file since 12175 was 12175, checked in by siramesh, 5 years ago

Super Orxo Bros (Sidharth Ramesh, Nisa Balta, Jeff Ren)

File size: 28.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @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::set() "set(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::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.
62
63    Examples:
64    @code
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)
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        orxout() << "doubled value is " << (2 * value) << 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 <utility>
103#include <OgreVector2.h>
104#include <OgreVector3.h>
105#include <OgreVector4.h>
106#include <OgreQuaternion.h>
107#include <OgreColourValue.h>
108#include <loki/TypeTraits.h>
109#include "Math.h"
110#include "mbool.h"
111
112namespace orxonox
113{
114    /**
115        @brief The MultiType can hold a value of many possible types and convert them to other types.
116
117        The following types are supported by the MultiType:
118         - all primitves
119         - all pointers
120         - string
121         - Vector2, Vector3, Vector4
122         - Quaternion
123         - ColourValue
124         - Radian, Degree
125
126        For more information and some examples see the description @ref MultiTypeExamples "here".
127
128        @see MultiType.h
129    */
130    class _UtilExport MultiType
131    {
132        _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
133        template <typename T> friend class MT_Value;
134
135        /**
136            @brief Enum of all possible types of a MultiType.
137        */
138        enum class Type : uint8_t
139        {
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
164        };
165
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:
174            inline MT_ValueBase(void* data, Type type) : type_(type), bLastConversionSuccessful(true), data_(data) {}
175            virtual inline ~MT_ValueBase() {}
176
177            virtual MT_ValueBase* clone() const = 0;
178
179            virtual void reset() = 0;
180
181            /// Returns the type of the current value.
182            inline const Type& getType() const { return this->type_; }
183
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
199            /// Checks whether the value is a default one.
200            inline bool lastConversionSuccessful()   const { return this->bLastConversionSuccessful; }
201
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;
225
226            virtual bool setValue(const MultiType& other)            = 0;
227
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
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;
265
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
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            }
291
292            virtual void toString(std::ostream& outstream) const = 0;
293
294            virtual void importData(uint8_t*& mem) = 0;
295            virtual void exportData(uint8_t*& mem) const = 0;
296            virtual uint8_t getSize() const = 0;
297
298            Type type_;                     ///< The type of the current value
299            bool bLastConversionSuccessful; ///< True if the last conversion was successful
300            void* data_;                    ///< For direct access to the value if the type is known
301        };
302
303        public:
304            static const MultiType Null;
305
306            /// Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value.
307            inline MultiType()                       : value_(nullptr) { }
308            /// Constructor: Assigns the given value and sets the type.
309            template <typename V>
310            inline MultiType(const V& value)         : value_(nullptr) { this->set(value); }
311            /// Copyconstructor: Assigns value and type of the other MultiType.
312            inline MultiType(const MultiType& other) : value_(nullptr) { this->set(other); }
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_); };
315
316            /// Destructor: Deletes the MT_Value.
317            inline ~MultiType() { if (this->value_) { delete this->value_; } }
318
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); }
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); }
327
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            }
337            /// Assigns a pointer.
338            template <typename V> inline bool set(V* value)
339            {
340                if (this->value_)
341                    return this->value_->setValue(static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
342
343                this->assignValue(static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
344                return true;
345            }
346            /// Assigns the value of the other MultiType and converts it to the current type.
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
356            /// Changes the type to T and assigns the new value (which might be of another type than T - it gets converted).
357            template <typename T, typename V> inline bool force(const V& value)
358            {
359                this->reset<T>();
360                return this->set(value);
361            }
362
363            /// Copies the other MultiType by assigning value and type.
364            inline void copy(const MultiType& other)
365            {
366                if (this == &other)
367                    return;
368                if (this->value_)
369                    delete this->value_;
370                this->value_ = (other.value_) ? other.value_->clone() : nullptr;
371            }
372
373            /// Converts the current value to type T.
374            template <typename T> inline bool convert() { return this->force<T>(MultiType(*this)); }
375
376            /// Resets value and type. Type will be void afterwards and null() returns true.
377            inline void reset() { if (this->value_) delete this->value_; this->value_ = nullptr; }
378            /// Resets the value and changes the internal type to T.
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(); }
382
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;
386
387            /// Checks whether the last conversion was successful
388            inline bool lastConversionSuccessful() const { return !this->value_ || this->value_->lastConversionSuccessful(); }
389
390            /// Checks if the MT contains no value.
391            inline bool null() const { return !this->value_; }
392
393            /// Conversion operator for all types
394            template <class T> operator T()  const { return this->get<T>(); }
395
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; }
398
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; }
405
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            {
413                assert(sizeof(Type) <= 8);
414                *static_cast<uint8_t*>(mem) = static_cast<uint8_t>(this->getType());
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            {
421                assert(sizeof(Type) <= 8);
422                this->setType(static_cast<Type>(*static_cast<uint8_t*>(mem)));
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
443        private:
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            }
460
461            /// Resets the value and changes the internal type to the given type.
462            inline void setType(Type type) { this->reset(); this->convert(type); this->resetValue(); }
463            /// Returns the current type.
464            inline Type getType() const { return (this->value_) ? this->value_->type_ : Type::Null; }
465            /// Converts the current value to the given type.
466            bool convert(Type type);
467
468            /// Changes the value container.
469            template <typename T> inline void changeValueContainer(const T& value)
470            {
471                if (this->value_)
472                    delete this->value_;
473                this->createNewValueContainer(value);
474            }
475            /// Creates a new value container (works only with specialized types).
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            }
489
490            MT_ValueBase* value_; //!< A pointer to the value container
491    };
492
493    /// Puts the MultiType on a stream by using the native << operator of the current type.
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    }
500
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;           }
524
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); }
527
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; }
531
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);
555}
556
557#endif /* _MultiType_H__ */
Note: See TracBrowser for help on using the repository browser.