1 //  boost lexical_cast.hpp header  -------------------------------------------//
  2 
  3 //  See http://www.boost.org for most recent version including documentation.
  4 
  5 #ifndef BOOST_LEXICAL_CAST_INCLUDED
  6 #define BOOST_LEXICAL_CAST_INCLUDED
  7 
  8 // what:  lexical_cast custom keyword cast
  9 // who:   contributed by Kevlin Henney, with alternative naming, behaviors
 10 //        and fixes contributed by Dave Abrahams, Daryle Walker and other
 11 //        Boosters on the list
 12 // when:  November 2000
 13 // where: tested with MSVC 6.0, BCC 5.5, and g++ 2.91
 14 
 15 #include <sstream>
 16 #include <typeinfo>
 17 #include <util/XmlBCfg.h>
 18 #include <stdio.h> 
 19 #if __GNUC__ == 2
 20   // g++ 2.95.3 does only know limits.h
 21 #else
 22 #  include <limits>
 23 #endif
 24 
 25 #if defined(_WINDOWS)
 26 #  if _MSC_VER >= 1400  /* _WINDOWS: 1200->VC++6.0, 1310->VC++7.1 (2003), 1400->VC++8.0 (2005) */
 27 //#    define XMLBLASTER_CPP_SNPRINTF snprintf0
 28 #    define XMLBLASTER_CPP_SNPRINTF sprintf_s
 29 #  else
 30 #    define XMLBLASTER_CPP_SNPRINTF _snprintf
 31 #  endif
 32 #else
 33 #  define XMLBLASTER_CPP_SNPRINTF snprintf
 34 #endif
 35 
 36 namespace org { namespace xmlBlaster { namespace util {
 37 
 38 #if __sun__
 39 # define DISABLE_WIDE_CHAR_SUPPORT
 40 #endif
 41 
 42 #if __GNUC__ == 2
 43    // Marcel 2004-04-01:
 44    // Is buggy for lexical_cast<string>(string("")): empty strings throw a bad_lexical_cast
 45    // Newest version from boost handles it but did not compile on g++ 2.9x
 46     class Dll_Export bad_lexical_cast : public std::bad_cast
 47     {
 48     public:
 49         // constructors, destructors, and assignment operator defaulted
 50 
 51         // function inlined for brevity and consistency with rest of library
 52         virtual const char * what() const throw()
 53         {
 54             return "bad lexical cast: "
 55                    "source type value could not be interpreted as target";
 56         }
 57     };
 58 
 59     /**
 60      * Note: The default double precision is 6 digits and will be rounded
 61      * You can use <code>interpreter.precision(15);</code> to increase the precision
 62      * A "double" has ANSI-C minium of 10 digits, on a PC Linux typically 15
 63      * A "long double" has ANSI-C minium of 10 digits, on a PC Linux typically 18
 64      * Marcel Ruff
 65      */
 66     template<typename Target, typename Source>
 67     Target lexical_cast(Source arg)
 68     {
 69 // # ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
 70 //        std::strstream interpreter; // for out-of-the-box g++ 2.95.2
 71 // # else
 72         std::stringstream interpreter;
 73 // # endif
 74         Target result;
 75 
 76         // Precision fix for "double" and "long double"
 77         // Marcel Ruff 2004-01-17
 78         //int origPrecision = interpreter.precision(); // 6 digits
 79         if (typeid(arg) == typeid(double(1.7L)))
 80             interpreter.precision(15);
 81         if (typeid(arg) == typeid((long double)(1.7L)))
 82             interpreter.precision(18);
 83 
 84         if(!(interpreter << arg) || !(interpreter >> result) ||
 85            !(interpreter >> std::ws).eof())
 86             throw bad_lexical_cast();
 87 
 88         //interpreter.precision(origPrecision);
 89 
 90         return result;
 91     }
 92 #else
 93    // Marcel 2004-04-01:
 94    // Copy from current boost.org cvs, slightly modified
 95    // to be not depending on other boost headers,
 96    // and added more expressive exception.what() text
 97 
 98     // exception used to indicate runtime lexical_cast failure
 99     class bad_lexical_cast : public std::bad_cast
100     {
101     public:
102         bad_lexical_cast() :
103         source(&typeid(void)), target(&typeid(void))
104         {
105         }
106         bad_lexical_cast(
107             const std::type_info &s,
108             const std::type_info &t) :
109             source(&s), target(&t)
110         {
111         }
112         const std::type_info &source_type() const
113         {
114             return *source;
115         }
116         const std::type_info &target_type() const
117         {
118             return *target;
119         }
120         virtual const char *what() const throw()
121         {
122             XMLBLASTER_CPP_SNPRINTF((char*)str_, 255, "bad lexical cast: source type value '%.50s' could not be interpreted as target '%.50s'", 
123                      source->name(), target->name());
124             return str_;
125         }
126         virtual ~bad_lexical_cast() throw()
127         {
128         }
129     private:
130         const std::type_info *source;
131         const std::type_info *target;
132         char str_[256];
133     };
134 
135     namespace detail // selectors for choosing stream character type
136     {
137         template<typename Type>
138         struct stream_char
139         {
140             typedef char type;
141         };
142 
143         #ifndef DISABLE_WIDE_CHAR_SUPPORT
144         template<>
145         struct stream_char<wchar_t>
146         {
147             typedef wchar_t type;
148         };
149 
150         template<>
151         struct stream_char<wchar_t *>
152         {
153             typedef wchar_t type;
154         };
155 
156         template<>
157         struct stream_char<const wchar_t *>
158         {
159             typedef wchar_t type;
160         };
161 
162         template<>
163         struct stream_char<std::wstring>
164         {
165             typedef wchar_t type;
166         };
167         #endif
168 
169         template<typename TargetChar, typename SourceChar>
170         struct widest_char
171         {
172             typedef TargetChar type;
173         };
174 
175         template<>
176         struct widest_char<char, wchar_t>
177         {
178             typedef wchar_t type;
179         };
180     }
181     
182     namespace detail // stream wrapper for handling lexical conversions
183     {
184         template<typename Target, typename Source>
185         class lexical_stream
186         {
187         public:
188             lexical_stream()
189             {
190                 stream.unsetf(std::ios::skipws);
191 
192                 if(std::numeric_limits<Target>::is_specialized)
193                     stream.precision(std::numeric_limits<Target>::digits10 + 1);
194                 else if(std::numeric_limits<Source>::is_specialized)
195                     stream.precision(std::numeric_limits<Source>::digits10 + 1);
196             }
197             ~lexical_stream()
198             {
199                 #if defined(BOOST_NO_STRINGSTREAM)
200                 stream.freeze(false);
201                 #endif
202             }
203             bool operator<<(const Source &input)
204             {
205                 return !(stream << input).fail();
206             }
207             template<typename InputStreamable>
208             bool operator>>(InputStreamable &output)
209             {
210                 return /*!is_pointer<InputStreamable>::value &&*/
211                        stream >> output &&
212                        (stream >> std::ws).eof();
213             }
214             bool operator>>(std::string &output)
215             {
216                 #if defined(BOOST_NO_STRINGSTREAM)
217                 stream << '\0';
218                 #endif
219                 output = stream.str();
220                 return true;
221             }
222             #ifndef DISABLE_WIDE_CHAR_SUPPORT
223             bool operator>>(std::wstring &output)
224             {
225                 output = stream.str();
226                 return true;
227             }
228             #endif
229         private:
230             typedef typename widest_char<
231                 typename stream_char<Target>::type,
232                 typename stream_char<Source>::type>::type char_type;
233 
234             #if defined(BOOST_NO_STRINGSTREAM)
235             std::strstream stream;
236             #elif defined(BOOST_NO_STD_LOCALE)
237             std::stringstream stream;
238             #else
239             std::basic_stringstream<char_type> stream;
240             #endif
241         };
242     }
243 
244     template<typename Target, typename Source>
245     Target lexical_cast(Source arg)
246     {
247         detail::lexical_stream<Target, Source> interpreter;
248         Target result;
249 
250         if(!(interpreter << arg && interpreter >> result))
251             throw bad_lexical_cast(typeid(Target), typeid(Source));
252         return result;
253     }
254 #endif
255 
256 //#if __GNUC__ == 2 || defined(__sun)
257 #if __GNUC__ == 2 || defined(__SUNPRO_CC)
258 //#if __GNUC__ == 2
259   // Problems with g++ 2.95.3 and template<>
260 #else
261    /**
262     * Specialization which returns "true" instead of "1". 
263     * replaces Global::getBoolAsString(bool)
264     */
265    template<> Dll_Export std::string lexical_cast(bool arg); // See Global.cpp
266 
267    /**
268     * Specialization which returns "true" instead of "1". 
269     */
270    template<> Dll_Export const char * lexical_cast(bool arg);
271 
272    /**
273     * Laghi 2004-07-04
274     * Have a separate string -> string mapper because '<< string' does strip everything
275     * after white spaces in the string and on SUN it results in an exception. 
276     * Don't try 'const string &' as it is not invoked!
277     */
278    template<> Dll_Export std::string lexical_cast(std::string arg); // See Global.cpp
279 
280    /**
281     * Laghi 2004-10-28
282     * transforming 'true' or 'false' to bool fails
283     */
284    template<> Dll_Export bool lexical_cast(std::string arg); // See Global.cpp
285    template<> Dll_Export bool lexical_cast(const char* arg); // See Global.cpp
286 
287 #endif
288 }}}
289 
290 
291 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
292 //
293 // Permission to use, copy, modify, and distribute this software for any
294 // purpose is hereby granted without fee, provided that this copyright and
295 // permissions notice appear in all copies and derivatives.
296 //
297 // This software is provided "as is" without express or implied warranty.
298 
299 #endif


syntax highlighted by Code2HTML, v. 0.9.1