- Timestamp:
- Jul 20, 2010, 2:08:28 PM (14 years ago)
- Location:
- code/branches/presentation3/src/libraries
- Files:
-
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
code/branches/presentation3/src/libraries/core/ConfigFileManager.cc
r6536 r7155 33 33 #include "util/Convert.h" 34 34 #include "util/Math.h" 35 #include "util/StringUtils.h" 35 36 #include "ConsoleCommand.h" 36 37 #include "ConfigValueContainer.h" -
code/branches/presentation3/src/libraries/core/ConfigFileManager.h
r6536 r7155 39 39 40 40 #include "util/Singleton.h" 41 #include "util/StringUtils.h"42 41 43 42 namespace orxonox // tolua_export -
code/branches/presentation3/src/libraries/util/CMakeLists.txt
r7135 r7155 27 27 Clipboard.cc 28 28 Clock.cc 29 Convert.cc 29 30 CRC32.cc 30 31 ExprParser.cc -
code/branches/presentation3/src/libraries/util/Convert.cc
r7141 r7155 23 23 * Reto Grieder 24 24 * Fabian 'x3n' Landau 25 * Benjamin Grauer26 25 * Co-authors: 27 26 * ... 28 27 */ 29 28 30 /*! 31 @file 32 @brief Definition and Implementation of the Convert class. 33 */ 34 35 #ifndef _Converter_H__ 36 #define _Converter_H__ 37 38 #include "UtilPrereqs.h" 39 40 #include <string> 41 #include <sstream> 42 #include <typeinfo> 43 44 #include "Debug.h" 45 #include "TemplateUtils.h" 46 47 //////////////////////////////////// 48 //// ACTUAL CONVERSION SEQUENCE //// 49 //////////////////////////////////// 50 /* 51 There is a distinct priority when choosing the right conversion function: 52 Overwrite: 53 1. (Partial) template specialisation of ConverterExplicit::convert() 54 Fallbacks: 55 2. Any possible implicit conversion. This includes 'FooBar' --> 'int' if FooBar defines operator float(). 56 3. Global or member operators for stringstream when converting from or to std::string (or FROM const char*) 57 4. (Partial) template specialisation of ConverterFallback::convert() 58 5. Function that simply displays "Could not convert value" with type information obtained from typeid(). 59 60 Notes: 61 There has to be an exact type match when using template specialisations. 62 Template specialisations can be defined after including this file. Any implicit cast function or iostream 63 operator has to be declared BEFORE this file gets parsed. 64 65 Defining your own functions: 66 There are obviously 4 ways to specifiy a user defined conversion. What should I use? 67 68 Usually, ConverterFallback fits quite well. You won't have to deal with the conversion from 69 'MyClass' to 'MyClass' by using another explicit template specialisation to avoid ambiguities. 70 71 However if you want to overwrite an implicit conversion or an iostream operator, you really need to 72 make use of ConverterExplicit. 73 */ 29 #include "Convert.h" 30 #include "StringUtils.h" 74 31 75 32 namespace orxonox 76 33 { 77 namespace detail 34 //template <class FromType, class ToType> 35 bool ConverterExplicit<std::string, bool>::convert(bool* output, const std::string& input) 78 36 { 79 //! Little template that maps integers to entire types (Alexandrescu 2001) 80 template <int I> 81 struct Int2Type { }; 82 } 83 84 85 /////////////////// 86 // No Conversion // 87 /////////////////// 88 89 // Default template. No conversion available at all. 90 template <class FromType, class ToType> 91 struct ConverterFallback 92 { 93 FORCEINLINE static bool convert(ToType* output, const FromType& input) 37 const std::string& stripped = getLowercase(removeTrailingWhitespaces(input)); 38 if (stripped == "true" || stripped == "on" || stripped == "yes") 94 39 { 95 COUT(2) << "Could not convert value of type " << typeid(FromType).name() 96 << " to type " << typeid(ToType).name() << std::endl; 97 return false; 98 } 99 }; 100 101 // If all else fails, try a dynamic_cast for pointer types. 102 template <class FromType, class ToType> 103 struct ConverterFallback<FromType*, ToType*> 104 { 105 FORCEINLINE static bool convert(ToType** output, FromType* const input) 106 { 107 ToType* temp = dynamic_cast<ToType*>(input); 108 if (temp) 109 { 110 *output = temp; 111 return true; 112 } 113 else 114 return false; 115 } 116 }; 117 } 118 119 120 /////////////////////// 121 // ConverterFallback // 122 /////////////////////// 123 124 // Default template for stringstream 125 template <class FromType, class ToType> 126 struct ConverterStringStream 127 { 128 FORCEINLINE static bool convert(ToType* output, const FromType& input) 129 { 130 return orxonox::ConverterFallback<FromType, ToType>::convert(output, input); 131 } 132 }; 133 134 135 ///////////// 136 // OStream // 137 ///////////// 138 139 namespace fallbackTemplates 140 { 141 template <class FromType> 142 FORCEINLINE bool operator <<(std::ostream& outstream, const FromType& input) 143 { 144 std::string temp; 145 if (orxonox::ConverterFallback<FromType, std::string>::convert(&temp, input)) 146 { 147 std::operator <<(outstream, temp); 40 *output = true; 148 41 return true; 149 42 } 43 else if (stripped == "false" || stripped == "off" || stripped == "no") 44 { 45 *output = false; 46 return true; 47 } 48 49 std::istringstream iss(input); 50 if (iss >> (*output)) 51 return true; 150 52 else 151 53 return false; 152 54 } 153 55 } 154 155 // template that evaluates whether we can convert to std::string via ostringstream156 template <class FromType>157 struct ConverterStringStream<FromType, std::string>158 {159 FORCEINLINE static bool convert(std::string* output, const FromType& input)160 {161 using namespace fallbackTemplates;162 // this operator call only chooses fallbackTemplates::operator<< if there's no other fitting function163 std::ostringstream oss;164 if (oss << input)165 {166 (*output) = oss.str();167 return true;168 }169 else170 return false;171 }172 };173 174 175 /////////////176 // IStream //177 /////////////178 179 namespace fallbackTemplates180 {181 template <class ToType>182 FORCEINLINE bool operator >>(std::istream& instream, ToType& output)183 {184 return orxonox::ConverterFallback<std::string, ToType>185 ::convert(&output, static_cast<std::istringstream&>(instream).str());186 }187 }188 189 // template that evaluates whether we can convert from std::string via ostringstream190 template <class ToType>191 struct ConverterStringStream<std::string, ToType>192 {193 FORCEINLINE static bool convert(ToType* output, const std::string& input)194 {195 using namespace fallbackTemplates;196 std::istringstream iss(input);197 // this operator call only chooses fallbackTemplates::operator>> if there's no other fitting function198 if (iss >> (*output))199 {200 return true;201 }202 else203 return false;204 }205 };206 207 namespace orxonox208 {209 210 ///////////////////211 // Implicit Cast //212 ///////////////////213 214 // implicit cast not possible, try stringstream conversion next215 template <class FromType, class ToType>216 FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, detail::Int2Type<false>)217 {218 return ConverterStringStream<FromType, ToType>::convert(output, input);219 }220 221 // We can cast implicitely222 template <class FromType, class ToType>223 FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, detail::Int2Type<true>)224 {225 (*output) = static_cast<ToType>(input);226 return true;227 }228 229 230 ////////////////////////////////231 // ConverterExplicit Fallback //232 ////////////////////////////////233 234 // Default template if no specialisation is available235 template <class FromType, class ToType>236 struct ConverterExplicit237 {238 enum { probe = ImplicitConversion<FromType, ToType>::exists };239 FORCEINLINE static bool convert(ToType* output, const FromType& input)240 {241 // Try implict cast and probe first. If a simple cast is not possible, it will not compile242 // We therefore have to out source it into another template function243 return convertImplicitely(output, input, detail::Int2Type<probe>());244 }245 };246 247 248 //////////////////////249 // Public Functions //250 //////////////////////251 252 /**253 @brief254 Converts any value to any other as long as there exists a conversion.255 Otherwise, the conversion will generate a runtime warning and return false.256 For information about the different conversion methods (user defined too), see the section257 'Actual conversion sequence' in this file above.258 */259 template <class FromType, class ToType>260 FORCEINLINE bool convertValue(ToType* output, const FromType& input)261 {262 return ConverterExplicit<FromType, ToType>::convert(output, input);263 }264 265 // Calls convertValue and returns true if the conversion was successful.266 // Otherwise the fallback is used.267 /**268 @brief269 Converts any value to any other as long as there exists a conversion.270 Otherwise, the conversion will generate a runtime warning and return false.271 For information about the different conversion methods (user defined too), see the section272 'Actual conversion sequence' in this file above.273 If the conversion doesn't succeed, 'fallback' is written to '*output'.274 @param fallback275 A default value that gets written to '*output' if there is no conversion.276 */277 template<class FromType, class ToType>278 FORCEINLINE bool convertValue(ToType* output, const FromType& input, const ToType& fallback)279 {280 if (convertValue(output, input))281 return true;282 else283 {284 (*output) = fallback;285 return false;286 }287 }288 289 // Directly returns the converted value, even if the conversion was not successful.290 template<class FromType, class ToType>291 FORCEINLINE ToType getConvertedValue(const FromType& input)292 {293 ToType output;294 convertValue(&output, input);295 return output;296 }297 298 // Directly returns the converted value, but uses the fallback on failure.299 template<class FromType, class ToType>300 FORCEINLINE ToType getConvertedValue(const FromType& input, const ToType& fallback)301 {302 ToType output;303 convertValue(&output, input, fallback);304 return output;305 }306 307 // Like getConvertedValue, but the template argument order is in reverse.308 // That means you can call it exactly like static_cast<ToType>(fromTypeValue).309 template<class ToType, class FromType>310 FORCEINLINE ToType multi_cast(const FromType& input)311 {312 ToType output;313 convertValue(&output, input);314 return output;315 }316 317 ////////////////////////////////318 // Special string conversions //319 ////////////////////////////////320 321 // Delegate conversion from const char* to std::string322 template <class ToType>323 struct ConverterExplicit<const char*, ToType>324 {325 FORCEINLINE static bool convert(ToType* output, const char* input)326 {327 return convertValue<std::string, ToType>(output, input);328 }329 };330 331 // These conversions would exhibit ambiguous << or >> operators when using stringstream332 template <>333 struct ConverterExplicit<char, std::string>334 {335 FORCEINLINE static bool convert(std::string* output, const char input)336 {337 *output = input;338 return true;339 }340 };341 template <>342 struct ConverterExplicit<unsigned char, std::string>343 {344 FORCEINLINE static bool convert(std::string* output, const unsigned char input)345 {346 *output = input;347 return true;348 }349 };350 template <>351 struct ConverterExplicit<std::string, char>352 {353 FORCEINLINE static bool convert(char* output, const std::string& input)354 {355 if (!input.empty())356 *output = input[0];357 else358 *output = '\0';359 return true;360 }361 };362 template <>363 struct ConverterExplicit<std::string, unsigned char>364 {365 FORCEINLINE static bool convert(unsigned char* output, const std::string& input)366 {367 if (!input.empty())368 *output = input[0];369 else370 *output = '\0';371 return true;372 }373 };374 375 376 // bool to std::string377 template <>378 struct ConverterExplicit<bool, std::string>379 {380 FORCEINLINE static bool convert(std::string* output, const bool& input)381 {382 if (input)383 *output = "true";384 else385 *output = "false";386 return true;387 }388 };389 390 // Declarations to avoid StringUtils.h include391 _UtilExport std::string removeTrailingWhitespaces(const std::string& str);392 _UtilExport std::string getLowercase(const std::string& str);393 394 // std::string to bool395 template <>396 struct ConverterExplicit<std::string, bool>397 {398 static bool convert(bool* output, const std::string& input)399 {400 const std::string& stripped = getLowercase(removeTrailingWhitespaces(input));401 if (stripped == "true" || stripped == "on" || stripped == "yes")402 {403 *output = true;404 return true;405 }406 else if (stripped == "false" || stripped == "off" || stripped == "no")407 {408 *output = false;409 return true;410 }411 412 std::istringstream iss(input);413 if (iss >> (*output))414 return true;415 else416 return false;417 }418 };419 }420 421 #endif /* _Convert_H__ */ -
code/branches/presentation3/src/libraries/util/Convert.h
r6417 r7155 64 64 65 65 Defining your own functions: 66 There are obviously 4 ways to specif iy a user defined conversion. What should Iuse?66 There are obviously 4 ways to specify a user defined conversion. What should you use? 67 67 68 68 Usually, ConverterFallback fits quite well. You won't have to deal with the conversion from … … 70 70 71 71 However if you want to overwrite an implicit conversion or an iostream operator, you really need to 72 make use of ConverterExplicit. 72 make use of ConverterExplicit. We have to do this for the Ogre classes for instance because they 73 define stream operators we don't particulary like. 73 74 */ 74 75 … … 388 389 }; 389 390 390 // Declarations to avoid StringUtils.h include391 _UtilExport std::string removeTrailingWhitespaces(const std::string& str);392 _UtilExport std::string getLowercase(const std::string& str);393 394 391 // std::string to bool 395 392 template <> 396 struct ConverterExplicit<std::string, bool> 397 { 398 static bool convert(bool* output, const std::string& input) 399 { 400 const std::string& stripped = getLowercase(removeTrailingWhitespaces(input)); 401 if (stripped == "true" || stripped == "on" || stripped == "yes") 402 { 403 *output = true; 404 return true; 405 } 406 else if (stripped == "false" || stripped == "off" || stripped == "no") 407 { 408 *output = false; 409 return true; 410 } 411 412 std::istringstream iss(input); 413 if (iss >> (*output)) 414 return true; 415 else 416 return false; 417 } 393 struct _UtilExport ConverterExplicit<std::string, bool> 394 { 395 static bool convert(bool* output, const std::string& input); 418 396 }; 419 397 }
Note: See TracChangeset
for help on using the changeset viewer.