Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jan 17, 2016, 10:29:21 PM (8 years ago)
Author:
landauf
Message:

merged branch cpp11_v3 back to trunk

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/util/MultiType.h

    r10197 r11071  
    132132        template <typename T> friend class MT_Value;
    133133
    134         struct Type
     134        /**
     135            @brief Enum of all possible types of a MultiType.
     136        */
     137        enum class Type : uint8_t
    135138        {
    136             /**
    137                 @brief Enum of all possible types of a MultiType.
    138             */
    139             enum Enum
    140             {
    141                 Null,
    142                 Char,
    143                 UnsignedChar,
    144                 Short,
    145                 UnsignedShort,
    146                 Int,
    147                 UnsignedInt,
    148                 Long,
    149                 UnsignedLong,
    150                 LongLong,
    151                 UnsignedLongLong,
    152                 Float,
    153                 Double,
    154                 LongDouble,
    155                 Bool,
    156                 VoidPointer,
    157                 String,
    158                 Vector2,
    159                 Vector3,
    160                 Vector4,
    161                 ColourValue,
    162                 Quaternion,
    163                 Radian,
    164                 Degree
    165             };
     139            Null,
     140            Char,
     141            UnsignedChar,
     142            Short,
     143            UnsignedShort,
     144            Int,
     145            UnsignedInt,
     146            Long,
     147            UnsignedLong,
     148            LongLong,
     149            UnsignedLongLong,
     150            Float,
     151            Double,
     152            LongDouble,
     153            Bool,
     154            VoidPointer,
     155            String,
     156            Vector2,
     157            Vector3,
     158            Vector4,
     159            ColourValue,
     160            Quaternion,
     161            Radian,
     162            Degree
    166163        };
    167164
     
    174171        {
    175172        public:
    176             inline MT_ValueBase(void* data, Type::Enum type) : type_(type), bLastConversionSuccessful(true), data_(data) {}
    177             inline virtual ~MT_ValueBase() {}
     173            inline MT_ValueBase(void* data, Type type) : type_(type), bLastConversionSuccessful(true), data_(data) {}
     174            virtual inline ~MT_ValueBase() {}
    178175
    179176            virtual MT_ValueBase* clone() const = 0;
     
    182179
    183180            /// Returns the type of the current value.
    184             inline const Type::Enum& getType() const { return this->type_; }
    185             /// Returns true if the type of the stored value is T.
    186             template <typename T> inline bool isType() const { return false; }
     181            inline const Type& getType() const { return this->type_; }
     182
     183            /// 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.
     184            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
     185            inline /*bool*/ isType() const
     186            {
     187                // If you reach this code, you used MultiType with an unsupported type T
     188                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     189                return false;
     190            }
     191            /// Implementation for enum classes: Returns true if the type of the stored value is the underlying type of T.
     192            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
     193            inline /*bool*/ isType() const
     194            {
     195                return this->isType<typename std::underlying_type<T>::type>();
     196            }
    187197
    188198            /// Checks whether the value is a default one.
     
    215225            virtual bool setValue(const MultiType& other)            = 0;
    216226
     227            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
     228            inline /*bool*/ setValue(const T& value)
     229            {
     230                // If you reach this code, you used MultiType with an unsupported type T
     231                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     232                return false;
     233            }
     234            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
     235            inline /*bool*/ setValue(const T& value)
     236            {
     237                typedef typename std::underlying_type<T>::type UnderlyingType;
     238                return this->setValue(reinterpret_cast<const UnderlyingType&>(value));
     239            }
     240
    217241            virtual bool getValue(char*                 value) const = 0;
    218242            virtual bool getValue(unsigned char*        value) const = 0;
     
    239263            virtual bool getValue(orxonox::Degree*      value) const = 0;
    240264
     265            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
     266            inline /*bool*/ getValue(T* value) const
     267            {
     268                // If you reach this code, you used MultiType with an unsupported type T
     269                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     270                return false;
     271            }
     272            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
     273            inline /*bool*/ getValue(T* value) const
     274            {
     275                typedef typename std::underlying_type<T>::type UnderlyingType;
     276                return this->getValue(reinterpret_cast<UnderlyingType*>(value));
     277            }
     278
    241279            template <typename T> T get() const
    242280            {
     
    257295            virtual uint8_t getSize() const = 0;
    258296
    259             Type::Enum type_;               ///< The type of the current value
     297            Type type_;                     ///< The type of the current value
    260298            bool bLastConversionSuccessful; ///< True if the last conversion was successful
    261299            void* data_;                    ///< For direct access to the value if the type is known
     
    266304
    267305            /// Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value.
    268             inline MultiType()                       : value_(0) { }
     306            inline MultiType()                       : value_(nullptr) { }
    269307            /// Constructor: Assigns the given value and sets the type.
    270308            template <typename V>
    271             inline MultiType(const V& value)         : value_(0) { this->set(value); }
     309            inline MultiType(const V& value)         : value_(nullptr) { this->set(value); }
    272310            /// Copyconstructor: Assigns value and type of the other MultiType.
    273             inline MultiType(const MultiType& other) : value_(0) { this->set(other); }
     311            inline MultiType(const MultiType& other) : value_(nullptr) { this->set(other); }
    274312
    275313            /// Destructor: Deletes the MT_Value.
     
    325363                if (this->value_)
    326364                    delete this->value_;
    327                 this->value_ = (other.value_) ? other.value_->clone() : 0;
     365                this->value_ = (other.value_) ? other.value_->clone() : nullptr;
    328366            }
    329367
     
    332370
    333371            /// Resets value and type. Type will be void afterwards and null() returns true.
    334             inline void reset() { if (this->value_) delete this->value_; this->value_ = 0; }
     372            inline void reset() { if (this->value_) delete this->value_; this->value_ = nullptr; }
    335373            /// Resets the value and changes the internal type to T.
    336374            template <typename T> inline void reset() { this->assignValue(typename Loki::TypeTraits<T>::UnqualifiedReferredType()); }
     
    354392            template <typename T> inline bool getValue(T* value) const { if (this->value_) { return this->value_->getValue(value); } return false; }
    355393
    356             /// Returns the current value, converted to the requested type. This base implementation works only for pointers. All other supported types are
    357             /// implemented in  specialized functions at the bottom of this file.
    358             template <typename T> inline T get() const { return static_cast<T>(this->get<void*>()); }
     394            /// Returns the current value, converted to the requested type.
     395            template <typename T> /* for normal types */ typename std::enable_if<!std::is_pointer<T>::value, T>::type
     396            inline /*T*/ get() const { return (this->value_ ? this->value_->get<T>() : NilValue<T>()); }
     397            /// Returns the current value, converted to a pointer of the requested type.
     398            template <typename T> /* for pointers */ typename std::enable_if<std::is_pointer<T>::value, T>::type
     399            inline /*T*/ get() const { return this->value_ ? static_cast<T>(this->value_->get<void*>()) : nullptr; }
    359400
    360401
     
    365406            inline void exportData(uint8_t*& mem) const
    366407            {
    367                 assert(sizeof(Type::Enum) <= 8);
    368                 *static_cast<uint8_t*>(mem) = this->getType();
     408                assert(sizeof(Type) <= 8);
     409                *static_cast<uint8_t*>(mem) = static_cast<uint8_t>(this->getType());
    369410                mem += sizeof(uint8_t);
    370411                this->value_->exportData(mem);
     
    373414            inline void importData(uint8_t*& mem)
    374415            {
    375                 assert(sizeof(Type::Enum) <= 8);
    376                 this->setType(static_cast<Type::Enum>(*static_cast<uint8_t*>(mem)));
     416                assert(sizeof(Type) <= 8);
     417                this->setType(static_cast<Type>(*static_cast<uint8_t*>(mem)));
    377418                mem += sizeof(uint8_t);
    378419                this->value_->importData(mem);
     
    414455
    415456            /// Resets the value and changes the internal type to the given type.
    416             inline void setType(Type::Enum type) { this->reset(); this->convert(type); this->resetValue(); }
     457            inline void setType(Type type) { this->reset(); this->convert(type); this->resetValue(); }
    417458            /// Returns the current type.
    418             inline Type::Enum getType() const { return (this->value_) ? this->value_->type_ : Type::Null; }
     459            inline Type getType() const { return (this->value_) ? this->value_->type_ : Type::Null; }
    419460            /// Converts the current value to the given type.
    420             bool convert(Type::Enum type);
     461            bool convert(Type type);
    421462
    422463            /// Changes the value container.
     
    428469            }
    429470            /// Creates a new value container (works only with specialized types).
    430             template <typename T> inline void createNewValueContainer(const T& value) { /* STATIC ASSERT */ *****value; return false; }
     471            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value>::type
     472            inline /*void*/ createNewValueContainer(const T& value)
     473            {
     474                // If you reach this code, you used MultiType with an unsupported type T
     475                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     476            }
     477            /// Creates a new value container (implementation for enum classes that must be cast to the underlying type).
     478            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value>::type
     479            inline /*void*/ createNewValueContainer(const T& value)
     480            {
     481                typedef typename std::underlying_type<T>::type UnderlyingType;
     482                this->createNewValueContainer<UnderlyingType>(reinterpret_cast<const UnderlyingType&>(value));
     483            }
    431484
    432485            MT_ValueBase* value_; //!< A pointer to the value container
     
    471524    template <> inline bool MultiType::isType<void>() const { return this->null(); }
    472525    template <> inline bool MultiType::convert<void>() { this->reset(); return true; }
    473 
    474     template <> inline char                 MultiType::get() const { return (this->value_ ? this->value_->get<char>()                 : 0); }
    475     template <> inline unsigned char        MultiType::get() const { return (this->value_ ? this->value_->get<unsigned char>()        : 0); }
    476     template <> inline short                MultiType::get() const { return (this->value_ ? this->value_->get<short>()                : 0); }
    477     template <> inline unsigned short       MultiType::get() const { return (this->value_ ? this->value_->get<unsigned short>()       : 0); }
    478     template <> inline int                  MultiType::get() const { return (this->value_ ? this->value_->get<int>()                  : 0); }
    479     template <> inline unsigned int         MultiType::get() const { return (this->value_ ? this->value_->get<unsigned int>()         : 0); }
    480     template <> inline long                 MultiType::get() const { return (this->value_ ? this->value_->get<long>()                 : 0); }
    481     template <> inline unsigned long        MultiType::get() const { return (this->value_ ? this->value_->get<unsigned long>()        : 0); }
    482     template <> inline long long            MultiType::get() const { return (this->value_ ? this->value_->get<long long>()            : 0); }
    483     template <> inline unsigned long long   MultiType::get() const { return (this->value_ ? this->value_->get<unsigned long long>()   : 0); }
    484     template <> inline float                MultiType::get() const { return (this->value_ ? this->value_->get<float>()                : 0); }
    485     template <> inline double               MultiType::get() const { return (this->value_ ? this->value_->get<double>()               : 0); }
    486     template <> inline long double          MultiType::get() const { return (this->value_ ? this->value_->get<long double>()          : 0); }
    487     template <> inline bool                 MultiType::get() const { return (this->value_ ? this->value_->get<bool>()                 : 0); }
    488     template <> inline void*                MultiType::get() const { return (this->value_ ? this->value_->get<void*>()                : 0); }
    489     template <> inline std::string          MultiType::get() const { return (this->value_ ? this->value_->get<std::string>()          : NilValue<std::string>()); }
    490     template <> inline orxonox::Vector2     MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Vector2>()     : NilValue<orxonox::Vector2>()); }
    491     template <> inline orxonox::Vector3     MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Vector3>()     : NilValue<orxonox::Vector3>()); }
    492     template <> inline orxonox::Vector4     MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Vector4>()     : NilValue<orxonox::Vector4>()); }
    493     template <> inline orxonox::ColourValue MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::ColourValue>() : NilValue<orxonox::ColourValue>()); }
    494     template <> inline orxonox::Quaternion  MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Quaternion>()  : NilValue<orxonox::Quaternion>()); }
    495     template <> inline orxonox::Radian      MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Radian>()      : NilValue<orxonox::Radian>()); }
    496     template <> inline orxonox::Degree      MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Degree>()      : NilValue<orxonox::Degree>()); }
    497526
    498527    template <> _UtilExport void MultiType::createNewValueContainer(const char& value);
Note: See TracChangeset for help on using the changeset viewer.