Changeset 11071 for code/trunk/src/libraries/util/MultiType.h
- Timestamp:
- Jan 17, 2016, 10:29:21 PM (9 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/util/MultiType.h
r10197 r11071 132 132 template <typename T> friend class MT_Value; 133 133 134 struct Type 134 /** 135 @brief Enum of all possible types of a MultiType. 136 */ 137 enum class Type : uint8_t 135 138 { 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 166 163 }; 167 164 … … 174 171 { 175 172 public: 176 inline MT_ValueBase(void* data, Type ::Enumtype) : 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() {} 178 175 179 176 virtual MT_ValueBase* clone() const = 0; … … 182 179 183 180 /// 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 } 187 197 188 198 /// Checks whether the value is a default one. … … 215 225 virtual bool setValue(const MultiType& other) = 0; 216 226 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 217 241 virtual bool getValue(char* value) const = 0; 218 242 virtual bool getValue(unsigned char* value) const = 0; … … 239 263 virtual bool getValue(orxonox::Degree* value) const = 0; 240 264 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 241 279 template <typename T> T get() const 242 280 { … … 257 295 virtual uint8_t getSize() const = 0; 258 296 259 Type ::Enum type_;///< The type of the current value297 Type type_; ///< The type of the current value 260 298 bool bLastConversionSuccessful; ///< True if the last conversion was successful 261 299 void* data_; ///< For direct access to the value if the type is known … … 266 304 267 305 /// 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) { } 269 307 /// Constructor: Assigns the given value and sets the type. 270 308 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); } 272 310 /// 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); } 274 312 275 313 /// Destructor: Deletes the MT_Value. … … 325 363 if (this->value_) 326 364 delete this->value_; 327 this->value_ = (other.value_) ? other.value_->clone() : 0;365 this->value_ = (other.value_) ? other.value_->clone() : nullptr; 328 366 } 329 367 … … 332 370 333 371 /// 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; } 335 373 /// Resets the value and changes the internal type to T. 336 374 template <typename T> inline void reset() { this->assignValue(typename Loki::TypeTraits<T>::UnqualifiedReferredType()); } … … 354 392 template <typename T> inline bool getValue(T* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } 355 393 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; } 359 400 360 401 … … 365 406 inline void exportData(uint8_t*& mem) const 366 407 { 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()); 369 410 mem += sizeof(uint8_t); 370 411 this->value_->exportData(mem); … … 373 414 inline void importData(uint8_t*& mem) 374 415 { 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))); 377 418 mem += sizeof(uint8_t); 378 419 this->value_->importData(mem); … … 414 455 415 456 /// Resets the value and changes the internal type to the given type. 416 inline void setType(Type ::Enumtype) { this->reset(); this->convert(type); this->resetValue(); }457 inline void setType(Type type) { this->reset(); this->convert(type); this->resetValue(); } 417 458 /// Returns the current type. 418 inline Type ::EnumgetType() const { return (this->value_) ? this->value_->type_ : Type::Null; }459 inline Type getType() const { return (this->value_) ? this->value_->type_ : Type::Null; } 419 460 /// Converts the current value to the given type. 420 bool convert(Type ::Enumtype);461 bool convert(Type type); 421 462 422 463 /// Changes the value container. … … 428 469 } 429 470 /// 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 } 431 484 432 485 MT_ValueBase* value_; //!< A pointer to the value container … … 471 524 template <> inline bool MultiType::isType<void>() const { return this->null(); } 472 525 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>()); }497 526 498 527 template <> _UtilExport void MultiType::createNewValueContainer(const char& value);
Note: See TracChangeset
for help on using the changeset viewer.