Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jan 17, 2016, 6:41:22 PM (8 years ago)
Author:
landauf
Message:

merged remaining commits from cpp11_v2 to cpp11_v3 (for some reason they were not merged in the first attempt)

Location:
code/branches/cpp11_v3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/cpp11_v3

  • code/branches/cpp11_v3/src/libraries/util/MultiType.h

    r11054 r11068  
    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) {}
     173            inline MT_ValueBase(void* data, Type type) : type_(type), bLastConversionSuccessful(true), data_(data) {}
    177174            virtual inline ~MT_ValueBase() {}
    178175
     
    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
     
    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)
     471            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value>::type
     472            inline /*void*/ createNewValueContainer(const T& value)
    431473            {
    432474                // If you reach this code, you used MultiType with an unsupported type T
    433475                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));
    434483            }
    435484
     
    475524    template <> inline bool MultiType::isType<void>() const { return this->null(); }
    476525    template <> inline bool MultiType::convert<void>() { this->reset(); return true; }
    477 
    478     template <> inline char                 MultiType::get() const { return (this->value_ ? this->value_->get<char>()                 : 0); }
    479     template <> inline unsigned char        MultiType::get() const { return (this->value_ ? this->value_->get<unsigned char>()        : 0); }
    480     template <> inline short                MultiType::get() const { return (this->value_ ? this->value_->get<short>()                : 0); }
    481     template <> inline unsigned short       MultiType::get() const { return (this->value_ ? this->value_->get<unsigned short>()       : 0); }
    482     template <> inline int                  MultiType::get() const { return (this->value_ ? this->value_->get<int>()                  : 0); }
    483     template <> inline unsigned int         MultiType::get() const { return (this->value_ ? this->value_->get<unsigned int>()         : 0); }
    484     template <> inline long                 MultiType::get() const { return (this->value_ ? this->value_->get<long>()                 : 0); }
    485     template <> inline unsigned long        MultiType::get() const { return (this->value_ ? this->value_->get<unsigned long>()        : 0); }
    486     template <> inline long long            MultiType::get() const { return (this->value_ ? this->value_->get<long long>()            : 0); }
    487     template <> inline unsigned long long   MultiType::get() const { return (this->value_ ? this->value_->get<unsigned long long>()   : 0); }
    488     template <> inline float                MultiType::get() const { return (this->value_ ? this->value_->get<float>()                : 0); }
    489     template <> inline double               MultiType::get() const { return (this->value_ ? this->value_->get<double>()               : 0); }
    490     template <> inline long double          MultiType::get() const { return (this->value_ ? this->value_->get<long double>()          : 0); }
    491     template <> inline bool                 MultiType::get() const { return (this->value_ ? this->value_->get<bool>()                 : 0); }
    492     template <> inline void*                MultiType::get() const { return (this->value_ ? this->value_->get<void*>()                : nullptr); }
    493     template <> inline std::string          MultiType::get() const { return (this->value_ ? this->value_->get<std::string>()          : NilValue<std::string>()); }
    494     template <> inline orxonox::Vector2     MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Vector2>()     : NilValue<orxonox::Vector2>()); }
    495     template <> inline orxonox::Vector3     MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Vector3>()     : NilValue<orxonox::Vector3>()); }
    496     template <> inline orxonox::Vector4     MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Vector4>()     : NilValue<orxonox::Vector4>()); }
    497     template <> inline orxonox::ColourValue MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::ColourValue>() : NilValue<orxonox::ColourValue>()); }
    498     template <> inline orxonox::Quaternion  MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Quaternion>()  : NilValue<orxonox::Quaternion>()); }
    499     template <> inline orxonox::Radian      MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Radian>()      : NilValue<orxonox::Radian>()); }
    500     template <> inline orxonox::Degree      MultiType::get() const { return (this->value_ ? this->value_->get<orxonox::Degree>()      : NilValue<orxonox::Degree>()); }
    501526
    502527    template <> _UtilExport void MultiType::createNewValueContainer(const char& value);
Note: See TracChangeset for help on using the changeset viewer.