Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 30, 2015, 9:13:14 PM (8 years ago)
Author:
landauf
Message:

MultiType now supports strongly typed enum classes. Their values are cast to the underlying type.
MultiType now also uses additional static_asserts to ensure that it is only used with supported values.

Location:
code/branches/cpp11_v2/src/libraries
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • code/branches/cpp11_v2/src/libraries/network/synchronisable/Synchronisable.h

    r10996 r11002  
    207207  {
    208208    template <class T, bool = std::is_enum<T>::value>
    209     struct RealType;
     209    struct UnderlyingType;
    210210    template <class T>
    211     struct RealType<T, true> { typedef typename std::underlying_type<T>::type type; };
     211    struct UnderlyingType<T, true> { typedef typename std::underlying_type<T>::type type; };
    212212    template <class T>
    213     struct RealType<T, false> { typedef T type; };
     213    struct UnderlyingType<T, false> { typedef T type; };
    214214  }
    215215
     
    217217  void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
    218218  {
    219     typedef typename detail::RealType<T>::type RealType;
     219    typedef typename detail::UnderlyingType<T>::type UnderlyingType;
    220220    if (bidirectional)
    221221    {
    222       syncList_.push_back(new SynchronisableVariableBidirectional<RealType>(reinterpret_cast<RealType&>(variable), mode, cb));
     222      syncList_.push_back(new SynchronisableVariableBidirectional<UnderlyingType>(reinterpret_cast<UnderlyingType&>(variable), mode, cb));
    223223      this->dataSize_ += syncList_.back()->getSize(state_);
    224224    }
    225225    else
    226226    {
    227       syncList_.push_back(new SynchronisableVariable<RealType>(reinterpret_cast<RealType&>(variable), mode, cb));
     227      syncList_.push_back(new SynchronisableVariable<UnderlyingType>(reinterpret_cast<UnderlyingType&>(variable), mode, cb));
    228228      if ( this->state_ == mode )
    229229        this->dataSize_ += syncList_.back()->getSize(state_);
     
    255255  void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
    256256  {
    257     typedef typename detail::RealType<T>::type RealType;
     257    typedef typename detail::UnderlyingType<T>::type UnderlyingType;
    258258    SynchronisableVariableBase* sv;
    259259    if (bidirectional)
    260       sv = new SynchronisableVariableBidirectional<std::set<RealType>>(reinterpret_cast<std::set<RealType>&>(variable), mode, cb);
     260      sv = new SynchronisableVariableBidirectional<std::set<UnderlyingType>>(reinterpret_cast<std::set<UnderlyingType>&>(variable), mode, cb);
    261261    else
    262       sv = new SynchronisableVariable<std::set<RealType>>(reinterpret_cast<std::set<RealType>&>(variable), mode, cb);
     262      sv = new SynchronisableVariable<std::set<UnderlyingType>>(reinterpret_cast<std::set<UnderlyingType>&>(variable), mode, cb);
    263263    syncList_.push_back(sv);
    264264    stringList_.push_back(sv);
  • code/branches/cpp11_v2/src/libraries/util/Math.h

    r10978 r11002  
    4747#include <cstdlib>
    4848#include <random>
     49#include <type_traits>
    4950
    5051#include <OgreMath.h>
     
    178179        @c Vector3 you get <tt>Vector3(0, 0, 0)</tt>.
    179180    */
    180     template <typename T>
    181     inline T zeroise()
     181    template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, T>::type
     182    inline /*T*/ zeroise()
    182183    {
    183184        // If you reach this code, you abused zeroise()!
    184185        static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     186    }
     187    /// Implementation for enum classes: uses the underlying type to create a zero value.
     188    template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, T>::type
     189    inline /*T*/ zeroise()
     190    {
     191        return static_cast<T>(zeroise<typename std::underlying_type<T>::type>());
    185192    }
    186193
  • code/branches/cpp11_v2/src/libraries/util/MultiType.h

    r11001 r11002  
    183183            /// Returns the type of the current value.
    184184            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; }
     185
     186            /// 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.
     187            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
     188            inline /*bool*/ isType() const
     189            {
     190                // If you reach this code, you used MultiType with an unsupported type T
     191                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     192                return false;
     193            }
     194            /// Implementation for enum classes: Returns true if the type of the stored value is the underlying type of T.
     195            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
     196            inline /*bool*/ isType() const
     197            {
     198                return this->isType<typename std::underlying_type<T>::type>();
     199            }
    187200
    188201            /// Checks whether the value is a default one.
     
    215228            virtual bool setValue(const MultiType& other)            = 0;
    216229
     230            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
     231            inline /*bool*/ setValue(const T& value)
     232            {
     233                // If you reach this code, you used MultiType with an unsupported type T
     234                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     235                return false;
     236            }
     237            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
     238            inline /*bool*/ setValue(const T& value)
     239            {
     240                typedef typename std::underlying_type<T>::type UnderlyingType;
     241                return this->setValue(reinterpret_cast<const UnderlyingType&>(value));
     242            }
     243
    217244            virtual bool getValue(char*                 value) const = 0;
    218245            virtual bool getValue(unsigned char*        value) const = 0;
     
    239266            virtual bool getValue(orxonox::Degree*      value) const = 0;
    240267
     268            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, bool>::type
     269            inline /*bool*/ getValue(T* value) const
     270            {
     271                // If you reach this code, you used MultiType with an unsupported type T
     272                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     273                return false;
     274            }
     275            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value, bool>::type
     276            inline /*bool*/ getValue(T* value) const
     277            {
     278                typedef typename std::underlying_type<T>::type UnderlyingType;
     279                return this->getValue(reinterpret_cast<UnderlyingType*>(value));
     280            }
     281
    241282            template <typename T> T get() const
    242283            {
     
    431472            }
    432473            /// Creates a new value container (works only with specialized types).
    433             template <typename T> inline void createNewValueContainer(const T& value)
     474            template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value>::type
     475            inline /*void*/ createNewValueContainer(const T& value)
    434476            {
    435477                // If you reach this code, you used MultiType with an unsupported type T
    436478                static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
     479            }
     480            /// Creates a new value container (implementation for enum classes that must be cast to the underlying type).
     481            template <typename T> /* for enum classes */ typename std::enable_if<std::is_enum<T>::value>::type
     482            inline /*void*/ createNewValueContainer(const T& value)
     483            {
     484                typedef typename std::underlying_type<T>::type UnderlyingType;
     485                this->createNewValueContainer<UnderlyingType>(reinterpret_cast<const UnderlyingType&>(value));
    437486            }
    438487
Note: See TracChangeset for help on using the changeset viewer.