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