Changeset 1743 for code/branches/core3
- Timestamp:
- Sep 8, 2008, 6:33:19 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core3/src/util/Convert.h
r1723 r1743 39 39 #include <string> 40 40 #include <sstream> 41 #include <istream> 42 #include <boost/static_assert.hpp> 41 43 42 44 #include "Math.h" … … 44 46 #include "SubString.h" 45 47 46 // disable annoying warning about forcing value to boolean 47 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC 48 #pragma warning(push) 49 #pragma warning(disable:4100 4800) 48 /////////////////////////////////// 49 // Explicit Conversion Functions // 50 /////////////////////////////////// 51 52 inline bool explicitConversion(std::string* output, const char input) 53 { 54 return true; 55 } 56 inline bool explicitConversion(std::string* output, const unsigned char input) 57 { 58 return true; 59 } 60 inline bool explicitConversion(char* output, const std::string input) 61 { 62 return true; 63 } 64 inline bool explicitConversion(unsigned char* output, const std::string input) 65 { 66 return true; 67 } 68 69 /////////////////////////// 70 // Static type detection // 71 /////////////////////////// 72 73 /* The idea to use the sizeof() operator on return functions to determine function existance 74 is described in 'Moder C++ design' by Alexandrescu (2001). */ 75 76 template <int a, int b> 77 struct TemplateDebugger 78 { 79 static int debug(int c, int d) { BOOST_STATIC_ASSERT(0); } 80 }; 81 82 namespace conversionTests 83 { 84 85 // Two struct with very different sizes 86 struct VerySmallStruct { char dummy[1]; }; 87 struct VeryBigStruct { char dummy[1024]; }; // Big is surely larger than Small, even with alignments 88 } 89 90 namespace generalFunctionTemplate 91 { 92 // Keep this function out of conversion namespaces because the compiler gives a general 93 // template in the same namesapace a higher priority than any specialisation. 94 // This function simply accepts anything but has lower priority to specialisations. 95 // It can be identified by the larger return value. 96 template <class AnyToType, class AnyFromType> 97 conversionTests::VeryBigStruct explicitConversion(AnyToType* output, const AnyFromType input) 98 { 99 // The function is exposed globally because of the "using namespace" in conversionTests. 100 // We have to make sure noboy uses it, so a good compiler error would be nice. 101 *output = (AnyToType)input; // Do not use this function! 102 BOOST_STATIC_ASSERT(0); // just to be sure 103 } 104 } 105 106 namespace conversionTests 107 { 108 using namespace generalFunctionTemplate; // Why in separate namespace? See above 109 110 template <class Any> 111 conversionTests::VeryBigStruct operator<<(std::ostream& outstream, const Any anything); 112 template <class Any> 113 conversionTests::VeryBigStruct operator>>(std::istream& instream, const Any anything); 114 115 template <class FromType, class ToType> 116 class ImplicitConversion 117 { 118 private: 119 static VerySmallStruct test(ToType); // only accepts ToType, but is preferred over '...' 120 static VeryBigStruct test(...); // accepts anything 121 static FromType object; // helper object to handle private c'tor and d'tor 122 public: 123 enum { exists = sizeof(test(object)) == sizeof(VerySmallStruct) }; 124 }; 125 126 template <class FromType, class ToType, int asdf> 127 class ExplicitConversion 128 { 129 private: 130 static FromType objectFromType; // helper object to handle private c'tor and d'tor 131 static ToType objectToType; // helper object to handle private c'tor and d'tor 132 public: 133 enum { exists = sizeof(explicitConversion(&objectToType, objectFromType)) == sizeof(VerySmallStruct) }; 134 static void test(); 135 }; 136 137 template <int asdf> 138 class ExplicitConversion<float, int, asdf> 139 { 140 private: 141 static float objectFromType; // helper object to handle private c'tor and d'tor 142 static int objectToType; // helper object to handle private c'tor and d'tor 143 public: 144 enum { exists = sizeof(explicitConversion(&objectToType, objectFromType)) == sizeof(VerySmallStruct) }; 145 static void test() { TemplateDebugger<sizeof(explicitConversion(&objectToType, objectFromType)), sizeof(VerySmallStruct)>::debug(1,2); } 146 }; 147 148 template <class Type> 149 class IStringStreamOperator 150 { 151 static std::istringstream istream_; // helper object to perform the '>>' operation 152 static Type object; // helper object to handle private c'tor and d'tor 153 public: 154 enum { exists = (sizeof(istream_ >> object) < sizeof(VerySmallStruct) + 512) }; 155 }; 156 157 template <class Type> 158 class OStringStreamOperator 159 { 160 static std::ostringstream ostream_; // helper object to perform the '<<' operation 161 static Type object; // helper object to handle private c'tor and d'tor 162 public: 163 enum { exists = (sizeof(ostream_ << object) < sizeof(VerySmallStruct) + 512) }; 164 }; 165 } 166 167 // shortcut without namespace 168 template <class FromType, class ToType> 169 struct ImplicitConversion 170 { enum { exists = conversionTests::ImplicitConversion<FromType, ToType>::exists }; }; 171 172 // shortcut without namespace 173 template <class FromType, class ToType> 174 struct ExplicitConversion 175 { enum { exists = conversionTests::ExplicitConversion<FromType, ToType, 4>::exists }; }; 176 177 // shortcut without namespace 178 template <class Type> 179 struct IStringStreamOperator 180 { enum { exists = conversionTests::IStringStreamOperator<Type>::exists }; }; 181 182 // shortcut without namespace 183 template <class Type> 184 struct OStringStreamOperator 185 { enum { exists = conversionTests::OStringStreamOperator<Type>::exists }; }; 186 187 188 /////////////////////////////// 189 // Conversion Template Stuff // 190 /////////////////////////////// 191 192 namespace conversion 193 { 194 // Maps bools to types in order to use function overloading instead of template specialisation (Alexandrescu 2001) 195 template <bool WhetherOrNot> 196 struct ImplicitPossible { }; 197 template <bool WhetherOrNot> 198 struct ExplicitPossible { }; 199 template <bool WhetherOrNot> 200 struct StringStreamPossible { }; 201 202 // No Conversion possible, default template 203 template <class ToType, class FromType, int Dummy> 204 struct Converter 205 { 206 static bool convert(ToType* output, FromType input) 207 { 208 // Do not allow impossible conversions 209 //(*output) = input; // this WILL trigger a compiler error 210 //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure.. 211 return false; 212 } 213 }; 214 215 216 /////////////////////// 217 //Explicit Conversion// 218 /////////////////////// 219 220 // We can cast explicitely, this overwrites any other possible cast 221 template <class ToType, class FromType> 222 inline bool convert(ToType* output, const FromType& input, ExplicitPossible<true>) 223 { 224 // This function can by anywhere globally! 225 //int a = TemplateDebugger<1,2>::debug(1,1); 226 //conversionTests::ExplicitConversion<FromType, ToType, 4>::test(); 227 //BOOST_STATIC_ASSERT(0); 228 return explicitConversion(output, input); 229 } 230 231 // No explict cast, try implicit 232 template <class ToType, class FromType> 233 inline bool convert(ToType* output, const FromType& input, ExplicitPossible<false>) 234 { 235 return convert(output, input, ImplicitPossible<ImplicitConversion<FromType, ToType>::exists>()); 236 } 237 238 239 ///////////////// 240 //Implicit Cast// 241 ///////////////// 242 243 // We can cast implicitely 244 template <class ToType, class FromType> 245 inline bool convert(ToType* output, const FromType& input, ImplicitPossible<true>) 246 { 247 (*output) = static_cast<ToType>(input); 248 return true; 249 } 250 251 // No implicit cast, leave it up to << and >> 252 template <class ToType, class FromType> 253 inline bool convert(ToType* output, const FromType& input, ImplicitPossible<false>) 254 { 255 return Converter<ToType, FromType, 0>::convert(output, input); 256 } 257 258 259 ///////////////// 260 //OStringStream// 261 ///////////////// 262 263 // Conversion via ostringstream 264 template <class FromType> 265 bool convertOStringStream(std::string* output, const FromType& input) 266 { 267 std::ostringstream oss; 268 if (oss << input) 269 { 270 (*output) = oss.str(); 271 return true; 272 } 273 else 274 return false; 275 } 276 277 // template that evaluates whether OStringStream is possible 278 template <class FromType, int Dummy> 279 struct Converter<std::string, FromType, Dummy> 280 { 281 // convert to std::string, probe for '<<' stringstream operator 282 static bool convert(std::string* output, const FromType& input) 283 { 284 return convert(output, input, StringStreamPossible<OStringStreamOperator<FromType>::exists>()); 285 //conversion::OStringStreamOperator<FromType>::test(); 286 } 287 288 // Conversion with ostringstream possible 289 static bool convert(std::string* output, const FromType& input, StringStreamPossible<true>) 290 { 291 return convertOStringStream(output, input); 292 } 293 294 // Conversion with ostringstream not possible 295 static bool convert(std::string* output, const FromType& input, StringStreamPossible<false>) 296 { 297 // Do not allow impossible conversions 298 //(*output) = input; // this WILL trigger a compiler error 299 //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure.. 300 return false; 301 } 302 }; 303 304 305 ///////////////// 306 //IStringStream// 307 ///////////////// 308 309 // conversion from std::string via istringstream 310 template <class ToType> 311 bool convertIStringStream(ToType* output, const std::string& input) 312 { 313 std::istringstream iss(input); 314 if (iss >> (*output)) 315 { 316 return true; 317 } 318 else 319 return false; 320 } 321 322 // template that evaluates whether IStringStream is possible 323 template <class ToType, int Dummy> 324 struct Converter<ToType, std::string, Dummy> 325 { 326 // convert from std::string, probe for '>>' stringstream operator 327 static bool convert(ToType* output, const std::string& input) 328 { 329 return convert(output, input, StringStreamPossible<IStringStreamOperator<ToType>::exists>()); 330 } 331 332 // Conversion with istringstream possible 333 static bool convert(ToType* output, const std::string& input, StringStreamPossible<true>) 334 { 335 return convertIStringStream(output, input); 336 } 337 338 // Conversion with istringstream not possible 339 static bool convert(ToType* output, const std::string& input, StringStreamPossible<false>) 340 { 341 // Do not allow impossible conversions 342 //(*output) = input; // this WILL trigger a compiler error 343 //BOOST_STATIC_ASSERT(sizeof(ToType) == 0); // just to be sure.. 344 return false; 345 } 346 }; 347 348 349 ///////////////// 350 //Special Cases// 351 ///////////////// 352 353 // delegate conversion from const char* via string 354 template <class ToType, int Dummy> 355 struct Converter<ToType, const char*, Dummy> 356 { 357 // convert from const char* via std::string 358 static bool convert(ToType* output, const char* input) 359 { return Converter<ToType, std::string>::convert(output, input); } 360 }; 361 #if 0 362 // conversion char to std::string leads to ambiguous operator << 363 template <int Dummy> 364 struct Converter<std::string, char, Dummy> 365 { 366 static bool convert(std::string* output, const char input) 367 { return convertOStringStream(output, input); } 368 }; 369 370 // conversion unsigned char to std::string leads to ambiguous operator << 371 template <int Dummy> 372 struct Converter<std::string, unsigned char, Dummy> 373 { 374 static bool convert(std::string* output, const char input) 375 { return convertOStringStream(output, input); } 376 }; 377 378 // conversion std::string to char leads to ambiguous operator >> 379 template <int Dummy> 380 struct Converter<char, std::string, Dummy> 381 { 382 static bool convert(char* output, const std::string input) 383 { return convertIStringStream(output, input); } 384 }; 385 386 // conversion std::string to unsigned char leads to ambiguous operator >> 387 template <int Dummy> 388 struct Converter<unsigned char, std::string, Dummy> 389 { 390 static bool convert(unsigned char* output, const std::string input) 391 { return convertIStringStream(output, input); } 392 }; 50 393 #endif 51 52 53 ////////// 54 // MAIN // 55 ////////// 56 57 // Enum to declare the wanted conversion preference in case of equal type-levels 58 enum ConversionPreference 59 { 60 CP_PreferToType, 61 CP_PreferFromType, 62 }; 63 64 // Helper classes to determine the preferred partial template specialization 65 class _ToType_ {}; 66 class _FromType_ {}; 67 class _Explicit_ {}; 68 69 70 // The default convert functions 71 template <class FromType, class ToType, class Type> 72 struct ConverterSpecialized 73 { 74 enum { specialized = false }; 75 static bool convert(ToType* output, const FromType& input) 76 { 77 COUT(2) << "Warning: Couldn't convert a value." << std::endl; 78 return false; 79 } 80 }; 81 82 83 // The default convert function if both types are the same 84 template <class BothTypes> 85 struct ConverterSpecialized<BothTypes, BothTypes, _Explicit_> 86 { 87 enum { specialized = true }; 88 static bool convert(BothTypes* output, const BothTypes& input) 89 { (*output) = input; return true; } 90 }; 91 92 93 // The possible levels 94 #define __low__ 0 // Everything that is or behaves like a primitive type (an can be converted with a typecast to every other low-level type) 95 #define __mid__ 1 // Everything that has overloaded << and >> operators to operate on a std::stream 96 #define __high__ 2 // Everything that doesn't fullfill the lowerlevel-requirements and therefore needs specialized conversions 97 98 // Defines the levels of all types: Default is __high__ so you don't have to define every high-level type 99 template <class T> struct ConverterLevel { enum { level = __high__ }; }; 100 template <> struct ConverterLevel<std::string> { enum { level = __mid__ }; }; 101 template <> struct ConverterLevel<orxonox::Radian> { enum { level = __mid__ }; }; 102 template <> struct ConverterLevel<orxonox::Degree> { enum { level = __mid__ }; }; 103 template <> struct ConverterLevel<int> { enum { level = __low__ }; }; 104 template <> struct ConverterLevel<unsigned int> { enum { level = __low__ }; }; 105 template <> struct ConverterLevel<char> { enum { level = __low__ }; }; 106 template <> struct ConverterLevel<unsigned char> { enum { level = __low__ }; }; 107 template <> struct ConverterLevel<short> { enum { level = __low__ }; }; 108 template <> struct ConverterLevel<unsigned short> { enum { level = __low__ }; }; 109 template <> struct ConverterLevel<long> { enum { level = __low__ }; }; 110 template <> struct ConverterLevel<unsigned long> { enum { level = __low__ }; }; 111 template <> struct ConverterLevel<long long> { enum { level = __low__ }; }; 112 template <> struct ConverterLevel<unsigned long long> { enum { level = __low__ }; }; 113 template <> struct ConverterLevel<float> { enum { level = __low__ }; }; 114 template <> struct ConverterLevel<double> { enum { level = __low__ }; }; 115 template <> struct ConverterLevel<long double> { enum { level = __low__ }; }; 116 template <> struct ConverterLevel<bool> { enum { level = __low__ }; }; 117 118 119 // Calculates the preference based on the levels of FromType and ToType 120 template <int from, int to> 121 struct ConverterPreference 122 { 123 enum 124 { 125 // The maximum of both levels: element of {0, 1, 2} 126 // max 0: Both types are primitives or have a similar behaviour 127 // max 1: At least one type is not a primitive, but both can be put on a std::stream 128 // max 2: There is at least one generic type that needs specialized conversions 129 max = (from > to) ? from : to, 130 131 // The difference between both levels limited to +-1: element of {-1, 0, 1} 132 // diff -1: The FromType has higher level than the ToType 133 // diff 0: Both types have the same level 134 // diff 1: The ToType has higher level than the FromType 135 diff = ((to - from) > 1) ? 1 : (((to - from) < -1) ? -1 : to - from) 136 }; 137 }; 138 139 140 // The default conversion: This usually does nothing 141 template <int max, class FromType, class ToType> 142 struct ConverterDefault 143 { 144 static bool convert(ToType* output, const FromType& input) 145 { 146 COUT(2) << "Warning: Couldn't convert a value." << std::endl; 147 return false; 148 } 149 }; 150 // The default conversion for primitives: A typecast (defined over two partial specialized templates to exclude all non-primitive types and classes) template <int max, class FromType, class ToType> 151 template <class FromType, class ToType> 152 struct ConverterDefault<0, FromType, ToType> 153 { 154 static bool convert(ToType* output, const FromType& input) 155 { 156 (*output) = (ToType)input; 157 return true; 158 } 159 }; 160 161 162 // Converter: Converts input of FromType into output of ToType 163 template <int diff, int max, class FromType, class ToType, ConversionPreference pref> 164 struct Converter 165 { 166 static bool convert(ToType* output, const FromType& input) 167 { 168 return false; 169 } 170 }; 171 // Converter: level{FromType} > level{ToType} 172 template <int max, class FromType, class ToType, ConversionPreference pref> 173 struct Converter<-1, max, FromType, ToType, pref> 174 { static bool convert(ToType* output, const FromType& input) 175 { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _FromType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _FromType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } }; 176 // Converter: level{FromType} < level{ToType} 177 template <int max, class FromType, class ToType, ConversionPreference pref> 178 struct Converter<1, max, FromType, ToType, pref> 179 { static bool convert(ToType* output, const FromType& input) 180 { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _ToType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _ToType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } }; 181 // Converter: level{FromType} = level{ToType} 182 // CP_PreferToType 183 template <int max, class FromType, class ToType> 184 struct Converter<0, max, FromType, ToType, CP_PreferToType> 185 { static bool convert(ToType* output, const FromType& input) 186 { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _ToType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _ToType_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _FromType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _FromType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } }; 187 // CP_PreferFromType 188 template <int max, class FromType, class ToType> 189 struct Converter<0, max, FromType, ToType, CP_PreferFromType> 190 { static bool convert(ToType* output, const FromType& input) 191 { return (ConverterSpecialized<FromType, ToType, _Explicit_>::specialized) ? (ConverterSpecialized<FromType, ToType, _Explicit_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _FromType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _FromType_>::convert(output, input)) : (ConverterSpecialized<FromType, ToType, _ToType_>::specialized) ? (ConverterSpecialized<FromType, ToType, _ToType_>::convert(output, input)) : (ConverterDefault<max, FromType, ToType>::convert(output, input)); } }; 192 193 194 // Calls the Converter::convertValue function with the correct template type parameters calculated by ConverterPreference 195 template <class FromType, class ToType> 196 static bool convertValue(ToType* output, const FromType& input, ConversionPreference preference = CP_PreferToType) 197 { 198 return (preference == CP_PreferToType) ? 199 Converter<ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::diff, 200 ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::max, 201 FromType, 202 ToType, 203 CP_PreferToType>::convert(output, input) 204 : Converter<ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::diff, 205 ConverterPreference<ConverterLevel<FromType>::level, ConverterLevel<ToType>::level>::max, 206 FromType, 207 ToType, 208 CP_PreferFromType>::convert(output, input); 209 } 210 211 212 ////////////////////// 213 // HELPER FUNCTIONS // 214 ////////////////////// 394 } 395 396 397 //////////////////// 398 //Public Functions// 399 //////////////////// 400 401 /** 402 @brief 403 Converts any value to any other as long as there exits a conversion. 404 Otherwise, the conversion will generate a runtime warning. 405 */ 406 template <class ToType, class FromType> 407 inline bool convertValue(ToType* output, const FromType& input) 408 { 409 // check whether we can convert one type to the other explicitely. 410 //conversionTests::ExplicitConversion<FromType, ToType, 4>::test(); 411 return conversion::convert(output, input, 412 conversion::ExplicitPossible<ExplicitConversion<FromType, ToType>::exists>()); 413 } 215 414 216 415 // Helper function: Calls convertValue with and without default value and returns true if the conversion was successful 217 416 template<class FromType, class ToType> 218 static bool ConvertValue(ToType* output, const FromType& input , ConversionPreference preference = CP_PreferToType)219 { 220 return convertValue(output, input , preference);417 static bool ConvertValue(ToType* output, const FromType& input) 418 { 419 return convertValue(output, input); 221 420 } 222 421 template<class FromType, class ToType> 223 static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback , ConversionPreference preference = CP_PreferToType)224 { 225 if (convertValue(output, input , preference))422 static bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback) 423 { 424 if (convertValue(output, input)) 226 425 return true; 227 426 … … 232 431 // Helper function: Calls convertValue with and without default value and returns the converted value 233 432 template<class FromType, class ToType> 234 static ToType getConvertedValue(const FromType& input , ConversionPreference preference = CP_PreferToType)433 static ToType getConvertedValue(const FromType& input) 235 434 { 236 435 ToType output = ToType(); 237 ConvertValue(&output, input , preference);436 ConvertValue(&output, input); 238 437 return output; 239 438 } 240 439 template<class FromType, class ToType> 241 static ToType getConvertedValue(const FromType& input, const ToType& fallback , ConversionPreference preference = CP_PreferToType)440 static ToType getConvertedValue(const FromType& input, const ToType& fallback) 242 441 { 243 442 ToType output = fallback; 244 ConvertValue(&output, input, fallback , preference);443 ConvertValue(&output, input, fallback); 245 444 return output; 246 445 } … … 283 482 */ 284 483 285 //////////// 286 // STRING // 287 //////////// 288 289 // convert to string 290 template <class FromType> 291 struct ConverterSpecialized<FromType, std::string, _ToType_> 292 { 293 enum { specialized = true }; 294 static bool convert(std::string* output, const FromType& input) 295 { 296 std::ostringstream oss; 297 if (oss << input) 298 { 299 (*output) = oss.str(); 300 return true; 301 } 302 else 303 return false; 304 } 305 }; 306 307 // convert from string 308 template <class ToType> 309 struct ConverterSpecialized<std::string, ToType, _FromType_> 310 { 311 enum { specialized = true }; 312 static bool convert(ToType* output, const std::string& input) 313 { 314 std::istringstream iss(input); 315 if (iss >> (*output)) 316 return true; 317 else 318 return false; 319 } 320 }; 321 484 485 ///////////////// 486 // CONST CHAR* // 487 ///////////////// 488 /* 489 // convert from const char* --> use conversions with std::string 490 template <class ToType, class Type> 491 struct ConverterSpecialized<const char*, ToType, Type> 492 { 493 enum { specialized = true }; 494 static bool convert(ToType* output, const char* input) 495 { 496 return ConverterSpecialized<std::string, ToType, Type>::convert(output, input); 497 } 498 }; 499 500 // convert from const char* --> use conversions with std::string 501 template <> 502 struct ConverterSpecialized<const char*, std::string, _ToType_> 503 { 504 enum { specialized = true }; 505 static bool convert(std::string* output, const char* input) 506 { 507 *output = input; 508 return true; 509 } 510 }; 511 512 // convert from const char* _Explicit_ --> use conversions with std::string 513 //template <class ToType> 514 //struct ConverterSpecialized<const char*, ToType, _Explicit_> 515 //{ 516 // enum { specialized = true }; 517 // static bool convert(ToType* output, const char* input) 518 // { 519 // return ConverterSpecialized<std::string, ToType, _Explicit_>::convert(output, input); 520 // } 521 //}; 522 523 // convert from char* without const is not allowed 524 //template <class ToType, class Type> 525 //struct ConverterSpecialized<char*, ToType, Type> 526 //{ 527 // enum { specialized = true }; 528 // static bool convert(ToType* output, const char* input) 529 // { 530 // BOOST_STATIC_ASSERT(sizeof(ToType) == 0); 531 // } 532 //}; 533 534 // No support for char* without const 535 //template <class ToType, class Type> 536 //struct ConverterSpecialized<char*, ToType, Type> 537 //{ 538 // enum { specialized = true }; 539 // static bool convert(ToType* output, const char* input) 540 // { 541 // BOOST_STATIC_ASSERT(sizeof(ToType) == 0); 542 // } 543 //}; 544 545 // convert to const char* is not supported (possible memory leak) 546 template <class FromType, class Type> 547 struct ConverterSpecialized<FromType, const char*, Type> 548 { 549 enum { specialized = true }; 550 static bool convert(const char** output, const FromType& input) 551 { 552 BOOST_STATIC_ASSERT(sizeof(FromType) == 0); 553 } 554 }; 555 556 // convert to char* is not supported (possible memory leak) 557 // Note: It actually does need both specializations for const char* and char* 558 //template <class FromType, class Type> 559 //struct ConverterSpecialized<FromType, char*, Type> 560 //{ 561 // enum { specialized = true }; 562 // static bool convert(char** output, const FromType& input) 563 // { 564 // BOOST_STATIC_ASSERT(sizeof(FromType) == 0); 565 // } 566 //}; 322 567 323 568 … … 549 794 } 550 795 }; 551 552 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC 553 #pragma warning(pop) 554 #endif 555 796 */ 556 797 #endif /* _Convert_H__ */
Note: See TracChangeset
for help on using the changeset viewer.