00001 // boost lexical_cast.hpp header -------------------------------------------// 00002 00003 // See http://www.boost.org for most recent version including documentation. 00004 00005 #ifndef BOOST_LEXICAL_CAST_INCLUDED 00006 #define BOOST_LEXICAL_CAST_INCLUDED 00007 00008 // what: lexical_cast custom keyword cast 00009 // who: contributed by Kevlin Henney, with alternative naming, behaviors 00010 // and fixes contributed by Dave Abrahams, Daryle Walker and other 00011 // Boosters on the list 00012 // when: November 2000 00013 // where: tested with MSVC 6.0, BCC 5.5, and g++ 2.91 00014 00015 #include <sstream> 00016 #include <typeinfo> 00017 #include <util/XmlBCfg.h> 00018 #include <stdio.h> 00019 #if __GNUC__ == 2 00020 // g++ 2.95.3 does only know limits.h 00021 #else 00022 # include <limits> 00023 #endif 00024 00025 #if defined(_WINDOWS) 00026 # if _MSC_VER >= 1400 /* _WINDOWS: 1200->VC++6.0, 1310->VC++7.1 (2003), 1400->VC++8.0 (2005) */ 00027 //# define XMLBLASTER_CPP_SNPRINTF snprintf0 00028 # define XMLBLASTER_CPP_SNPRINTF sprintf_s 00029 # else 00030 # define XMLBLASTER_CPP_SNPRINTF _snprintf 00031 # endif 00032 #else 00033 # define XMLBLASTER_CPP_SNPRINTF snprintf 00034 #endif 00035 00036 namespace org { namespace xmlBlaster { namespace util { 00037 00038 #if __sun__ 00039 # define DISABLE_WIDE_CHAR_SUPPORT 00040 #endif 00041 00042 #if __GNUC__ == 2 00043 // Marcel 2004-04-01: 00044 // Is buggy for lexical_cast<string>(string("")): empty strings throw a bad_lexical_cast 00045 // Newest version from boost handles it but did not compile on g++ 2.9x 00046 class Dll_Export bad_lexical_cast : public std::bad_cast 00047 { 00048 public: 00049 // constructors, destructors, and assignment operator defaulted 00050 00051 // function inlined for brevity and consistency with rest of library 00052 virtual const char * what() const throw() 00053 { 00054 return "bad lexical cast: " 00055 "source type value could not be interpreted as target"; 00056 } 00057 }; 00058 00066 template<typename Target, typename Source> 00067 Target lexical_cast(Source arg) 00068 { 00069 // # ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM 00070 // std::strstream interpreter; // for out-of-the-box g++ 2.95.2 00071 // # else 00072 std::stringstream interpreter; 00073 // # endif 00074 Target result; 00075 00076 // Precision fix for "double" and "long double" 00077 // Marcel Ruff 2004-01-17 00078 //int origPrecision = interpreter.precision(); // 6 digits 00079 if (typeid(arg) == typeid(double(1.7L))) 00080 interpreter.precision(15); 00081 if (typeid(arg) == typeid((long double)(1.7L))) 00082 interpreter.precision(18); 00083 00084 if(!(interpreter << arg) || !(interpreter >> result) || 00085 !(interpreter >> std::ws).eof()) 00086 throw bad_lexical_cast(); 00087 00088 //interpreter.precision(origPrecision); 00089 00090 return result; 00091 } 00092 #else 00093 // Marcel 2004-04-01: 00094 // Copy from current boost.org cvs, slightly modified 00095 // to be not depending on other boost headers, 00096 // and added more expressive exception.what() text 00097 00098 // exception used to indicate runtime lexical_cast failure 00099 class bad_lexical_cast : public std::bad_cast 00100 { 00101 public: 00102 bad_lexical_cast() : 00103 source(&typeid(void)), target(&typeid(void)) 00104 { 00105 } 00106 bad_lexical_cast( 00107 const std::type_info &s, 00108 const std::type_info &t) : 00109 source(&s), target(&t) 00110 { 00111 } 00112 const std::type_info &source_type() const 00113 { 00114 return *source; 00115 } 00116 const std::type_info &target_type() const 00117 { 00118 return *target; 00119 } 00120 virtual const char *what() const throw() 00121 { 00122 XMLBLASTER_CPP_SNPRINTF((char*)str_, 255, "bad lexical cast: source type value '%.50s' could not be interpreted as target '%.50s'", 00123 source->name(), target->name()); 00124 return str_; 00125 } 00126 virtual ~bad_lexical_cast() throw() 00127 { 00128 } 00129 private: 00130 const std::type_info *source; 00131 const std::type_info *target; 00132 char str_[256]; 00133 }; 00134 00135 namespace detail // selectors for choosing stream character type 00136 { 00137 template<typename Type> 00138 struct stream_char 00139 { 00140 typedef char type; 00141 }; 00142 00143 #ifndef DISABLE_WIDE_CHAR_SUPPORT 00144 template<> 00145 struct stream_char<wchar_t> 00146 { 00147 typedef wchar_t type; 00148 }; 00149 00150 template<> 00151 struct stream_char<wchar_t *> 00152 { 00153 typedef wchar_t type; 00154 }; 00155 00156 template<> 00157 struct stream_char<const wchar_t *> 00158 { 00159 typedef wchar_t type; 00160 }; 00161 00162 template<> 00163 struct stream_char<std::wstring> 00164 { 00165 typedef wchar_t type; 00166 }; 00167 #endif 00168 00169 template<typename TargetChar, typename SourceChar> 00170 struct widest_char 00171 { 00172 typedef TargetChar type; 00173 }; 00174 00175 template<> 00176 struct widest_char<char, wchar_t> 00177 { 00178 typedef wchar_t type; 00179 }; 00180 } 00181 00182 namespace detail // stream wrapper for handling lexical conversions 00183 { 00184 template<typename Target, typename Source> 00185 class lexical_stream 00186 { 00187 public: 00188 lexical_stream() 00189 { 00190 stream.unsetf(std::ios::skipws); 00191 00192 if(std::numeric_limits<Target>::is_specialized) 00193 stream.precision(std::numeric_limits<Target>::digits10 + 1); 00194 else if(std::numeric_limits<Source>::is_specialized) 00195 stream.precision(std::numeric_limits<Source>::digits10 + 1); 00196 } 00197 ~lexical_stream() 00198 { 00199 #if defined(BOOST_NO_STRINGSTREAM) 00200 stream.freeze(false); 00201 #endif 00202 } 00203 bool operator<<(const Source &input) 00204 { 00205 return !(stream << input).fail(); 00206 } 00207 template<typename InputStreamable> 00208 bool operator>>(InputStreamable &output) 00209 { 00210 return 00211 stream >> output && 00212 (stream >> std::ws).eof(); 00213 } 00214 bool operator>>(std::string &output) 00215 { 00216 #if defined(BOOST_NO_STRINGSTREAM) 00217 stream << '\0'; 00218 #endif 00219 output = stream.str(); 00220 return true; 00221 } 00222 #ifndef DISABLE_WIDE_CHAR_SUPPORT 00223 bool operator>>(std::wstring &output) 00224 { 00225 output = stream.str(); 00226 return true; 00227 } 00228 #endif 00229 private: 00230 typedef typename widest_char< 00231 typename stream_char<Target>::type, 00232 typename stream_char<Source>::type>::type char_type; 00233 00234 #if defined(BOOST_NO_STRINGSTREAM) 00235 std::strstream stream; 00236 #elif defined(BOOST_NO_STD_LOCALE) 00237 std::stringstream stream; 00238 #else 00239 std::basic_stringstream<char_type> stream; 00240 #endif 00241 }; 00242 } 00243 00244 template<typename Target, typename Source> 00245 Target lexical_cast(Source arg) 00246 { 00247 detail::lexical_stream<Target, Source> interpreter; 00248 Target result; 00249 00250 if(!(interpreter << arg && interpreter >> result)) 00251 throw bad_lexical_cast(typeid(Target), typeid(Source)); 00252 return result; 00253 } 00254 #endif 00255 00256 //#if __GNUC__ == 2 || defined(__sun) 00257 #if __GNUC__ == 2 || defined(__SUNPRO_CC) 00258 //#if __GNUC__ == 2 00259 // Problems with g++ 2.95.3 and template<> 00260 #else 00261 00265 template<> Dll_Export std::string lexical_cast(bool arg); // See Global.cpp 00266 00270 template<> Dll_Export const char * lexical_cast(bool arg); 00271 00278 template<> Dll_Export std::string lexical_cast(std::string arg); // See Global.cpp 00279 00284 template<> Dll_Export bool lexical_cast(std::string arg); // See Global.cpp 00285 template<> Dll_Export bool lexical_cast(const char* arg); // See Global.cpp 00286 00287 #endif 00288 }}} 00289 00290 00291 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00292 // 00293 // Permission to use, copy, modify, and distribute this software for any 00294 // purpose is hereby granted without fee, provided that this copyright and 00295 // permissions notice appear in all copies and derivatives. 00296 // 00297 // This software is provided "as is" without express or implied warranty. 00298 00299 #endif