Changeset 11002
- Timestamp:
- Dec 30, 2015, 9:13:14 PM (9 years ago)
- Location:
- code/branches/cpp11_v2
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/cpp11_v2/src/libraries/network/synchronisable/Synchronisable.h
r10996 r11002 207 207 { 208 208 template <class T, bool = std::is_enum<T>::value> 209 struct RealType;209 struct UnderlyingType; 210 210 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; }; 212 212 template <class T> 213 struct RealType<T, false> { typedef T type; };213 struct UnderlyingType<T, false> { typedef T type; }; 214 214 } 215 215 … … 217 217 void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional) 218 218 { 219 typedef typename detail:: RealType<T>::type RealType;219 typedef typename detail::UnderlyingType<T>::type UnderlyingType; 220 220 if (bidirectional) 221 221 { 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)); 223 223 this->dataSize_ += syncList_.back()->getSize(state_); 224 224 } 225 225 else 226 226 { 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)); 228 228 if ( this->state_ == mode ) 229 229 this->dataSize_ += syncList_.back()->getSize(state_); … … 255 255 void Synchronisable::registerVariable( std::set<T>& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional) 256 256 { 257 typedef typename detail:: RealType<T>::type RealType;257 typedef typename detail::UnderlyingType<T>::type UnderlyingType; 258 258 SynchronisableVariableBase* sv; 259 259 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); 261 261 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); 263 263 syncList_.push_back(sv); 264 264 stringList_.push_back(sv); -
code/branches/cpp11_v2/src/libraries/util/Math.h
r10978 r11002 47 47 #include <cstdlib> 48 48 #include <random> 49 #include <type_traits> 49 50 50 51 #include <OgreMath.h> … … 178 179 @c Vector3 you get <tt>Vector3(0, 0, 0)</tt>. 179 180 */ 180 template <typename T> 181 inline Tzeroise()181 template <typename T> /* for normal classes */ typename std::enable_if<!std::is_enum<T>::value, T>::type 182 inline /*T*/ zeroise() 182 183 { 183 184 // If you reach this code, you abused zeroise()! 184 185 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>()); 185 192 } 186 193 -
code/branches/cpp11_v2/src/libraries/util/MultiType.h
r11001 r11002 183 183 /// Returns the type of the current value. 184 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; } 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 } 187 200 188 201 /// Checks whether the value is a default one. … … 215 228 virtual bool setValue(const MultiType& other) = 0; 216 229 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 217 244 virtual bool getValue(char* value) const = 0; 218 245 virtual bool getValue(unsigned char* value) const = 0; … … 239 266 virtual bool getValue(orxonox::Degree* value) const = 0; 240 267 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 241 282 template <typename T> T get() const 242 283 { … … 431 472 } 432 473 /// 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) 434 476 { 435 477 // If you reach this code, you used MultiType with an unsupported type T 436 478 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)); 437 486 } 438 487 -
code/branches/cpp11_v2/test/util/MultiTypeTest.cc
r10197 r11002 697 697 EXPECT_TRUE(mt.null()); 698 698 } 699 700 /////////////////////////////// 701 // Strongly typed enum class // 702 /////////////////////////////// 703 enum class EnumWithChar : unsigned char 704 { 705 ValueA = 'A', 706 ValueB = 'B', 707 ValueC = 'C', 708 }; 709 enum class EnumWithInt 710 { 711 Value1 = 50, 712 Value2 = 0, 713 Value3, 714 }; 715 716 TEST(MultiType, Enum_Constructor) 717 { 718 // Constructor: 719 { 720 MultiType mt = EnumWithChar::ValueA; 721 722 EXPECT_TRUE(mt.isType<EnumWithChar>()); 723 EXPECT_EQ(EnumWithChar::ValueA, mt.get<EnumWithChar>()); 724 } 725 { 726 MultiType mt = MultiType(EnumWithInt::Value1); 727 728 EXPECT_TRUE(mt.isType<EnumWithInt>()); 729 EXPECT_EQ(EnumWithInt::Value1, mt.get<EnumWithInt>()); 730 } 731 } 732 733 TEST(MultiType, Enum_Assignment) 734 { 735 // operator=: 736 MultiType mt; 737 mt = EnumWithChar::ValueB; 738 739 EXPECT_TRUE(mt.isType<EnumWithChar>()); 740 EXPECT_EQ(EnumWithChar::ValueB, mt.get<EnumWithChar>()); 741 } 742 743 TEST(MultiType, Enum_Set) 744 { 745 // set(value): 746 { 747 MultiType mt; 748 mt.set(EnumWithInt::Value2); // assign enum to an empty MultiType 749 750 EXPECT_TRUE(mt.isType<EnumWithInt>()); 751 EXPECT_EQ(EnumWithInt::Value2, mt.get<EnumWithInt>()); 752 } 753 { 754 MultiType mt = "string"; 755 mt.set(EnumWithChar::ValueC); // assign enum to a MultiType with type std::string 756 757 EXPECT_TRUE(mt.isType<std::string>()); 758 EXPECT_EQ("C", mt.get<std::string>()); 759 } 760 { 761 MultiType mt = EnumWithChar::ValueA; 762 mt.set(EnumWithChar::ValueB); // assign enum to a MultiType with type std::string 763 764 EXPECT_TRUE(mt.isType<EnumWithChar>()); 765 EXPECT_EQ(EnumWithChar::ValueB, mt.get<EnumWithChar>()); 766 } 767 { 768 MultiType mt = EnumWithInt::Value3; 769 mt.set("50"); // assign enum to a MultiType with type std::string 770 771 EXPECT_TRUE(mt.isType<EnumWithInt>()); 772 EXPECT_EQ(EnumWithInt::Value1, mt.get<EnumWithInt>()); 773 } 774 } 775 776 TEST(MultiType, Enum_Force) 777 { 778 // force(value): 779 { 780 MultiType mt = "string"; 781 EXPECT_TRUE(mt.isType<std::string>()); 782 EXPECT_EQ("string", mt.get<std::string>()); 783 784 mt.force<EnumWithChar>("C"); 785 786 EXPECT_TRUE(mt.isType<EnumWithChar>()); 787 EXPECT_EQ(EnumWithChar::ValueC, mt.get<EnumWithChar>()); 788 } 789 { 790 MultiType mt = EnumWithChar::ValueA; 791 EXPECT_TRUE(mt.isType<EnumWithChar>()); 792 EXPECT_EQ(EnumWithChar::ValueA, mt.get<EnumWithChar>()); 793 794 mt.force<std::string>(EnumWithChar::ValueB); 795 796 EXPECT_TRUE(mt.isType<std::string>()); 797 EXPECT_EQ("B", mt.get<std::string>()); 798 } 799 } 800 801 TEST(MultiType, Enum_Convert) 802 { 803 // convert(): 804 { 805 MultiType mt = "C"; 806 mt.convert<EnumWithChar>(); 807 808 EXPECT_TRUE(mt.isType<EnumWithChar>()); 809 EXPECT_EQ(EnumWithChar::ValueC, mt.get<EnumWithChar>()); 810 } 811 { 812 MultiType mt = EnumWithChar::ValueA; 813 mt.convert<std::string>(); 814 815 EXPECT_TRUE(mt.isType<std::string>()); 816 EXPECT_EQ("A", mt.get<std::string>()); 817 } 818 } 819 820 TEST(MultiType, Enum_Reset) 821 { 822 // reset(): 823 { 824 MultiType mt = EnumWithChar::ValueA; 825 mt.reset<EnumWithChar>(); 826 827 EXPECT_TRUE(mt.isType<EnumWithChar>()); 828 EXPECT_TRUE(mt.isType<unsigned char>()); 829 EXPECT_EQ('\0', mt.get<unsigned char>()); 830 } 831 { 832 MultiType mt = "string"; 833 mt.reset<EnumWithInt>(); 834 835 EXPECT_TRUE(mt.isType<EnumWithInt>()); 836 EXPECT_TRUE(mt.isType<int>()); 837 EXPECT_EQ(0, mt.get<int>()); 838 } 839 } 840 841 TEST(MultiType, Enum_IsType) 842 { 843 // isType(): 844 { 845 MultiType mt = EnumWithChar::ValueB; 846 EXPECT_TRUE(mt.isType<EnumWithChar>()); 847 EXPECT_TRUE(mt.isType<unsigned char>()); 848 EXPECT_FALSE(mt.isType<char>()); 849 EXPECT_FALSE(mt.isType<int>()); 850 EXPECT_FALSE(mt.isType<bool>()); 851 EXPECT_FALSE(mt.isType<std::string>()); 852 } 853 { 854 MultiType mt = EnumWithInt::Value3; 855 EXPECT_TRUE(mt.isType<EnumWithInt>()); 856 EXPECT_TRUE(mt.isType<int>()); 857 EXPECT_FALSE(mt.isType<unsigned char>()); 858 EXPECT_FALSE(mt.isType<char>()); 859 EXPECT_FALSE(mt.isType<bool>()); 860 EXPECT_FALSE(mt.isType<std::string>()); 861 } 862 } 863 864 TEST(MultiType, Enum_ConversionOperator) 865 { 866 // conversion operator: 867 { 868 MultiType mt = EnumWithChar::ValueA; 869 EnumWithChar value = mt; 870 EXPECT_EQ(EnumWithChar::ValueA, value); 871 } 872 { 873 MultiType mt = 'B'; 874 EnumWithChar value = mt; 875 EXPECT_EQ(EnumWithChar::ValueB, value); 876 } 877 { 878 MultiType mt = EnumWithInt::Value1; 879 std::string value = mt; 880 EXPECT_EQ("50", value); 881 } 882 } 883 884 TEST(MultiType, Enum_GetValue) 885 { 886 // getValue(): 887 { 888 MultiType mt = EnumWithChar::ValueA; 889 EnumWithChar value; 890 mt.getValue(&value); 891 EXPECT_EQ(EnumWithChar::ValueA, value); 892 } 893 { 894 MultiType mt = 'B'; 895 EnumWithChar value; 896 mt.getValue(&value); 897 EXPECT_EQ(EnumWithChar::ValueB, value); 898 } 899 { 900 MultiType mt = EnumWithInt::Value1; 901 std::string value; 902 mt.getValue(&value); 903 EXPECT_EQ("50", value); 904 } 905 } 906 907 TEST(MultiType, Enum_Get) 908 { 909 // get(): 910 { 911 MultiType mt = EnumWithChar::ValueB; 912 EXPECT_EQ(EnumWithChar::ValueB, mt.get<EnumWithChar>()); 913 914 EXPECT_EQ('B', mt.get<unsigned char>()); 915 EXPECT_EQ("B", mt.get<std::string>()); 916 EXPECT_EQ(66, mt.get<int>()); 917 EXPECT_TRUE(mt.get<bool>()); 918 } 919 { 920 MultiType mt = EnumWithInt::Value1; 921 EXPECT_EQ(EnumWithInt::Value1, mt.get<EnumWithInt>()); 922 923 EXPECT_EQ('2', mt.get<unsigned char>()); 924 EXPECT_EQ("50", mt.get<std::string>()); 925 EXPECT_EQ(50, mt.get<int>()); 926 EXPECT_TRUE(mt.get<bool>()); 927 } 928 { 929 MultiType mt = EnumWithInt::Value2; 930 EXPECT_EQ(EnumWithInt::Value2, mt.get<EnumWithInt>()); 931 932 EXPECT_EQ('\0', mt.get<unsigned char>()); 933 EXPECT_EQ("0", mt.get<std::string>()); 934 EXPECT_EQ(0, mt.get<int>()); 935 EXPECT_FALSE(mt.get<bool>()); 936 } 937 } 699 938 }
Note: See TracChangeset
for help on using the changeset viewer.