Chris@102
|
1 // Copyright Kevlin Henney, 2000-2005.
|
Chris@102
|
2 // Copyright Alexander Nasonov, 2006-2010.
|
Chris@102
|
3 // Copyright Antony Polukhin, 2011-2014.
|
Chris@102
|
4 //
|
Chris@102
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@102
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
8 //
|
Chris@102
|
9 // what: lexical_cast custom keyword cast
|
Chris@102
|
10 // who: contributed by Kevlin Henney,
|
Chris@102
|
11 // enhanced with contributions from Terje Slettebo,
|
Chris@102
|
12 // with additional fixes and suggestions from Gennaro Prota,
|
Chris@102
|
13 // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
|
Chris@102
|
14 // Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
|
Chris@102
|
15 // Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
|
Chris@102
|
16 // when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2014
|
Chris@102
|
17
|
Chris@102
|
18 #ifndef BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
|
Chris@102
|
19 #define BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_STREAMS_HPP
|
Chris@102
|
20
|
Chris@102
|
21 #include <boost/config.hpp>
|
Chris@102
|
22 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@102
|
23 # pragma once
|
Chris@102
|
24 #endif
|
Chris@102
|
25
|
Chris@102
|
26
|
Chris@102
|
27 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
|
Chris@102
|
28 #define BOOST_LCAST_NO_WCHAR_T
|
Chris@102
|
29 #endif
|
Chris@102
|
30
|
Chris@102
|
31 #include <cstddef>
|
Chris@102
|
32 #include <string>
|
Chris@102
|
33 #include <cstring>
|
Chris@102
|
34 #include <cstdio>
|
Chris@102
|
35 #include <boost/limits.hpp>
|
Chris@102
|
36 #include <boost/mpl/if.hpp>
|
Chris@102
|
37 #include <boost/type_traits/ice.hpp>
|
Chris@102
|
38 #include <boost/type_traits/is_pointer.hpp>
|
Chris@102
|
39 #include <boost/static_assert.hpp>
|
Chris@102
|
40 #include <boost/detail/workaround.hpp>
|
Chris@102
|
41
|
Chris@102
|
42
|
Chris@102
|
43 #ifndef BOOST_NO_STD_LOCALE
|
Chris@102
|
44 # include <locale>
|
Chris@102
|
45 #else
|
Chris@102
|
46 # ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
Chris@102
|
47 // Getting error at this point means, that your STL library is old/lame/misconfigured.
|
Chris@102
|
48 // If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
|
Chris@102
|
49 // but beware: lexical_cast will understand only 'C' locale delimeters and thousands
|
Chris@102
|
50 // separators.
|
Chris@102
|
51 # error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
|
Chris@102
|
52 # error "boost::lexical_cast to use only 'C' locale during conversions."
|
Chris@102
|
53 # endif
|
Chris@102
|
54 #endif
|
Chris@102
|
55
|
Chris@102
|
56 #ifdef BOOST_NO_STRINGSTREAM
|
Chris@102
|
57 #include <strstream>
|
Chris@102
|
58 #else
|
Chris@102
|
59 #include <sstream>
|
Chris@102
|
60 #endif
|
Chris@102
|
61
|
Chris@102
|
62 #include <boost/lexical_cast/detail/lcast_char_constants.hpp>
|
Chris@102
|
63 #include <boost/lexical_cast/detail/lcast_unsigned_converters.hpp>
|
Chris@102
|
64 #include <boost/lexical_cast/detail/inf_nan.hpp>
|
Chris@102
|
65
|
Chris@102
|
66 #include <istream>
|
Chris@102
|
67
|
Chris@102
|
68 #ifndef BOOST_NO_CXX11_HDR_ARRAY
|
Chris@102
|
69 #include <array>
|
Chris@102
|
70 #endif
|
Chris@102
|
71
|
Chris@102
|
72 #include <boost/array.hpp>
|
Chris@102
|
73 #include <boost/type_traits/make_unsigned.hpp>
|
Chris@102
|
74 #include <boost/type_traits/is_integral.hpp>
|
Chris@102
|
75 #include <boost/type_traits/is_float.hpp>
|
Chris@102
|
76 #include <boost/range/iterator_range_core.hpp>
|
Chris@102
|
77 #include <boost/container/container_fwd.hpp>
|
Chris@102
|
78 #include <boost/integer.hpp>
|
Chris@102
|
79 #include <boost/detail/basic_pointerbuf.hpp>
|
Chris@102
|
80 #include <boost/noncopyable.hpp>
|
Chris@102
|
81 #ifndef BOOST_NO_CWCHAR
|
Chris@102
|
82 # include <cwchar>
|
Chris@102
|
83 #endif
|
Chris@102
|
84
|
Chris@102
|
85 namespace boost {
|
Chris@102
|
86
|
Chris@102
|
87 namespace detail // basic_unlockedbuf
|
Chris@102
|
88 {
|
Chris@102
|
89 // acts as a stream buffer which wraps around a pair of pointers
|
Chris@102
|
90 // and gives acces to internals
|
Chris@102
|
91 template <class BufferType, class CharT>
|
Chris@102
|
92 class basic_unlockedbuf : public basic_pointerbuf<CharT, BufferType> {
|
Chris@102
|
93 public:
|
Chris@102
|
94 typedef basic_pointerbuf<CharT, BufferType> base_type;
|
Chris@102
|
95 typedef BOOST_DEDUCED_TYPENAME base_type::streamsize streamsize;
|
Chris@102
|
96
|
Chris@102
|
97 #ifndef BOOST_NO_USING_TEMPLATE
|
Chris@102
|
98 using base_type::pptr;
|
Chris@102
|
99 using base_type::pbase;
|
Chris@102
|
100 using base_type::setbuf;
|
Chris@102
|
101 #else
|
Chris@102
|
102 charT* pptr() const { return base_type::pptr(); }
|
Chris@102
|
103 charT* pbase() const { return base_type::pbase(); }
|
Chris@102
|
104 BufferType* setbuf(char_type* s, streamsize n) { return base_type::setbuf(s, n); }
|
Chris@102
|
105 #endif
|
Chris@102
|
106 };
|
Chris@102
|
107 }
|
Chris@102
|
108
|
Chris@102
|
109 namespace detail
|
Chris@102
|
110 {
|
Chris@102
|
111 struct do_not_construct_out_stream_t{};
|
Chris@102
|
112
|
Chris@102
|
113 template <class CharT, class Traits>
|
Chris@102
|
114 struct out_stream_helper_trait {
|
Chris@102
|
115 #if defined(BOOST_NO_STRINGSTREAM)
|
Chris@102
|
116 typedef std::ostrstream out_stream_t;
|
Chris@102
|
117 typedef void buffer_t;
|
Chris@102
|
118 #elif defined(BOOST_NO_STD_LOCALE)
|
Chris@102
|
119 typedef std::ostringstream out_stream_t;
|
Chris@102
|
120 typedef basic_unlockedbuf<std::streambuf, char> buffer_t;
|
Chris@102
|
121 #else
|
Chris@102
|
122 typedef std::basic_ostringstream<CharT, Traits>
|
Chris@102
|
123 out_stream_t;
|
Chris@102
|
124 typedef basic_unlockedbuf<std::basic_streambuf<CharT, Traits>, CharT>
|
Chris@102
|
125 buffer_t;
|
Chris@102
|
126 #endif
|
Chris@102
|
127 };
|
Chris@102
|
128 }
|
Chris@102
|
129
|
Chris@102
|
130 namespace detail // optimized stream wrappers
|
Chris@102
|
131 {
|
Chris@102
|
132 template< class CharT // a result of widest_char transformation
|
Chris@102
|
133 , class Traits
|
Chris@102
|
134 , bool RequiresStringbuffer
|
Chris@102
|
135 , std::size_t CharacterBufferSize
|
Chris@102
|
136 >
|
Chris@102
|
137 class lexical_istream_limited_src: boost::noncopyable {
|
Chris@102
|
138 typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::buffer_t
|
Chris@102
|
139 buffer_t;
|
Chris@102
|
140
|
Chris@102
|
141 typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::out_stream_t
|
Chris@102
|
142 out_stream_t;
|
Chris@102
|
143
|
Chris@102
|
144 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
Chris@102
|
145 RequiresStringbuffer,
|
Chris@102
|
146 out_stream_t,
|
Chris@102
|
147 do_not_construct_out_stream_t
|
Chris@102
|
148 >::type deduced_out_stream_t;
|
Chris@102
|
149
|
Chris@102
|
150 // A string representation of Source is written to `buffer`.
|
Chris@102
|
151 deduced_out_stream_t out_stream;
|
Chris@102
|
152 CharT buffer[CharacterBufferSize];
|
Chris@102
|
153
|
Chris@102
|
154 // After the `operator <<` finishes, `[start, finish)` is
|
Chris@102
|
155 // the range to output by `operator >>`
|
Chris@102
|
156 const CharT* start;
|
Chris@102
|
157 const CharT* finish;
|
Chris@102
|
158
|
Chris@102
|
159 public:
|
Chris@102
|
160 lexical_istream_limited_src() BOOST_NOEXCEPT
|
Chris@102
|
161 : start(buffer)
|
Chris@102
|
162 , finish(buffer + CharacterBufferSize)
|
Chris@102
|
163 {}
|
Chris@102
|
164
|
Chris@102
|
165 const CharT* cbegin() const BOOST_NOEXCEPT {
|
Chris@102
|
166 return start;
|
Chris@102
|
167 }
|
Chris@102
|
168
|
Chris@102
|
169 const CharT* cend() const BOOST_NOEXCEPT {
|
Chris@102
|
170 return finish;
|
Chris@102
|
171 }
|
Chris@102
|
172
|
Chris@102
|
173 private:
|
Chris@102
|
174 // Undefined:
|
Chris@102
|
175 lexical_istream_limited_src(lexical_istream_limited_src const&);
|
Chris@102
|
176 void operator=(lexical_istream_limited_src const&);
|
Chris@102
|
177
|
Chris@102
|
178 /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
|
Chris@102
|
179 bool shl_char(CharT ch) BOOST_NOEXCEPT {
|
Chris@102
|
180 Traits::assign(buffer[0], ch);
|
Chris@102
|
181 finish = start + 1;
|
Chris@102
|
182 return true;
|
Chris@102
|
183 }
|
Chris@102
|
184
|
Chris@102
|
185 #ifndef BOOST_LCAST_NO_WCHAR_T
|
Chris@102
|
186 template <class T>
|
Chris@102
|
187 bool shl_char(T ch) {
|
Chris@102
|
188 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
|
Chris@102
|
189 "boost::lexical_cast does not support narrowing of char types."
|
Chris@102
|
190 "Use boost::locale instead" );
|
Chris@102
|
191 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
Chris@102
|
192 std::locale loc;
|
Chris@102
|
193 CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
|
Chris@102
|
194 #else
|
Chris@102
|
195 CharT const w = static_cast<CharT>(ch);
|
Chris@102
|
196 #endif
|
Chris@102
|
197 Traits::assign(buffer[0], w);
|
Chris@102
|
198 finish = start + 1;
|
Chris@102
|
199 return true;
|
Chris@102
|
200 }
|
Chris@102
|
201 #endif
|
Chris@102
|
202
|
Chris@102
|
203 bool shl_char_array(CharT const* str) BOOST_NOEXCEPT {
|
Chris@102
|
204 start = str;
|
Chris@102
|
205 finish = start + Traits::length(str);
|
Chris@102
|
206 return true;
|
Chris@102
|
207 }
|
Chris@102
|
208
|
Chris@102
|
209 template <class T>
|
Chris@102
|
210 bool shl_char_array(T const* str) {
|
Chris@102
|
211 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
|
Chris@102
|
212 "boost::lexical_cast does not support narrowing of char types."
|
Chris@102
|
213 "Use boost::locale instead" );
|
Chris@102
|
214 return shl_input_streamable(str);
|
Chris@102
|
215 }
|
Chris@102
|
216
|
Chris@102
|
217 bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT {
|
Chris@102
|
218 start = str;
|
Chris@102
|
219 finish = std::find(start, start + max_size, Traits::to_char_type(0));
|
Chris@102
|
220 return true;
|
Chris@102
|
221 }
|
Chris@102
|
222
|
Chris@102
|
223 template<typename InputStreamable>
|
Chris@102
|
224 bool shl_input_streamable(InputStreamable& input) {
|
Chris@102
|
225 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
|
Chris@102
|
226 // If you have compilation error at this point, than your STL library
|
Chris@102
|
227 // does not support such conversions. Try updating it.
|
Chris@102
|
228 BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
|
Chris@102
|
229 #endif
|
Chris@102
|
230
|
Chris@102
|
231 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@102
|
232 out_stream.exceptions(std::ios::badbit);
|
Chris@102
|
233 try {
|
Chris@102
|
234 #endif
|
Chris@102
|
235 bool const result = !(out_stream << input).fail();
|
Chris@102
|
236 const buffer_t* const p = static_cast<buffer_t*>(
|
Chris@102
|
237 static_cast<std::basic_streambuf<CharT, Traits>*>(out_stream.rdbuf())
|
Chris@102
|
238 );
|
Chris@102
|
239 start = p->pbase();
|
Chris@102
|
240 finish = p->pptr();
|
Chris@102
|
241 return result;
|
Chris@102
|
242 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@102
|
243 } catch (const ::std::ios_base::failure& /*f*/) {
|
Chris@102
|
244 return false;
|
Chris@102
|
245 }
|
Chris@102
|
246 #endif
|
Chris@102
|
247 }
|
Chris@102
|
248
|
Chris@102
|
249 template <class T>
|
Chris@102
|
250 inline bool shl_unsigned(const T n) {
|
Chris@102
|
251 CharT* tmp_finish = buffer + CharacterBufferSize;
|
Chris@102
|
252 start = lcast_put_unsigned<Traits, T, CharT>(n, tmp_finish).convert();
|
Chris@102
|
253 finish = tmp_finish;
|
Chris@102
|
254 return true;
|
Chris@102
|
255 }
|
Chris@102
|
256
|
Chris@102
|
257 template <class T>
|
Chris@102
|
258 inline bool shl_signed(const T n) {
|
Chris@102
|
259 CharT* tmp_finish = buffer + CharacterBufferSize;
|
Chris@102
|
260 typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type utype;
|
Chris@102
|
261 CharT* tmp_start = lcast_put_unsigned<Traits, utype, CharT>(lcast_to_unsigned(n), tmp_finish).convert();
|
Chris@102
|
262 if (n < 0) {
|
Chris@102
|
263 --tmp_start;
|
Chris@102
|
264 CharT const minus = lcast_char_constants<CharT>::minus;
|
Chris@102
|
265 Traits::assign(*tmp_start, minus);
|
Chris@102
|
266 }
|
Chris@102
|
267 start = tmp_start;
|
Chris@102
|
268 finish = tmp_finish;
|
Chris@102
|
269 return true;
|
Chris@102
|
270 }
|
Chris@102
|
271
|
Chris@102
|
272 template <class T, class SomeCharT>
|
Chris@102
|
273 bool shl_real_type(const T& val, SomeCharT* /*begin*/) {
|
Chris@102
|
274 lcast_set_precision(out_stream, &val);
|
Chris@102
|
275 return shl_input_streamable(val);
|
Chris@102
|
276 }
|
Chris@102
|
277
|
Chris@102
|
278 bool shl_real_type(float val, char* begin) {
|
Chris@102
|
279 using namespace std;
|
Chris@102
|
280 const double val_as_double = val;
|
Chris@102
|
281 finish = start +
|
Chris@102
|
282 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
Chris@102
|
283 sprintf_s(begin, CharacterBufferSize,
|
Chris@102
|
284 #else
|
Chris@102
|
285 sprintf(begin,
|
Chris@102
|
286 #endif
|
Chris@102
|
287 "%.*g", static_cast<int>(boost::detail::lcast_get_precision<float>()), val_as_double);
|
Chris@102
|
288 return finish > start;
|
Chris@102
|
289 }
|
Chris@102
|
290
|
Chris@102
|
291 bool shl_real_type(double val, char* begin) {
|
Chris@102
|
292 using namespace std;
|
Chris@102
|
293 finish = start +
|
Chris@102
|
294 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
Chris@102
|
295 sprintf_s(begin, CharacterBufferSize,
|
Chris@102
|
296 #else
|
Chris@102
|
297 sprintf(begin,
|
Chris@102
|
298 #endif
|
Chris@102
|
299 "%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val);
|
Chris@102
|
300 return finish > start;
|
Chris@102
|
301 }
|
Chris@102
|
302
|
Chris@102
|
303 #ifndef __MINGW32__
|
Chris@102
|
304 bool shl_real_type(long double val, char* begin) {
|
Chris@102
|
305 using namespace std;
|
Chris@102
|
306 finish = start +
|
Chris@102
|
307 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
Chris@102
|
308 sprintf_s(begin, CharacterBufferSize,
|
Chris@102
|
309 #else
|
Chris@102
|
310 sprintf(begin,
|
Chris@102
|
311 #endif
|
Chris@102
|
312 "%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double>()), val );
|
Chris@102
|
313 return finish > start;
|
Chris@102
|
314 }
|
Chris@102
|
315 #endif
|
Chris@102
|
316
|
Chris@102
|
317
|
Chris@102
|
318 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
|
Chris@102
|
319 bool shl_real_type(float val, wchar_t* begin) {
|
Chris@102
|
320 using namespace std;
|
Chris@102
|
321 const double val_as_double = val;
|
Chris@102
|
322 finish = start + swprintf(begin, CharacterBufferSize,
|
Chris@102
|
323 L"%.*g",
|
Chris@102
|
324 static_cast<int>(boost::detail::lcast_get_precision<float >()),
|
Chris@102
|
325 val_as_double );
|
Chris@102
|
326 return finish > start;
|
Chris@102
|
327 }
|
Chris@102
|
328
|
Chris@102
|
329 bool shl_real_type(double val, wchar_t* begin) {
|
Chris@102
|
330 using namespace std;
|
Chris@102
|
331 finish = start + swprintf(begin, CharacterBufferSize,
|
Chris@102
|
332 L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
|
Chris@102
|
333 return finish > start;
|
Chris@102
|
334 }
|
Chris@102
|
335
|
Chris@102
|
336 bool shl_real_type(long double val, wchar_t* begin) {
|
Chris@102
|
337 using namespace std;
|
Chris@102
|
338 finish = start + swprintf(begin, CharacterBufferSize,
|
Chris@102
|
339 L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
|
Chris@102
|
340 return finish > start;
|
Chris@102
|
341 }
|
Chris@102
|
342 #endif
|
Chris@102
|
343 template <class T>
|
Chris@102
|
344 bool shl_real(T val) {
|
Chris@102
|
345 CharT* tmp_finish = buffer + CharacterBufferSize;
|
Chris@102
|
346 if (put_inf_nan(buffer, tmp_finish, val)) {
|
Chris@102
|
347 finish = tmp_finish;
|
Chris@102
|
348 return true;
|
Chris@102
|
349 }
|
Chris@102
|
350
|
Chris@102
|
351 return shl_real_type(val, static_cast<CharT*>(buffer));
|
Chris@102
|
352 }
|
Chris@102
|
353
|
Chris@102
|
354 /************************************ OPERATORS << ( ... ) ********************************/
|
Chris@102
|
355 public:
|
Chris@102
|
356 template<class Alloc>
|
Chris@102
|
357 bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT {
|
Chris@102
|
358 start = str.data();
|
Chris@102
|
359 finish = start + str.length();
|
Chris@102
|
360 return true;
|
Chris@102
|
361 }
|
Chris@102
|
362
|
Chris@102
|
363 template<class Alloc>
|
Chris@102
|
364 bool operator<<(boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT {
|
Chris@102
|
365 start = str.data();
|
Chris@102
|
366 finish = start + str.length();
|
Chris@102
|
367 return true;
|
Chris@102
|
368 }
|
Chris@102
|
369
|
Chris@102
|
370 bool operator<<(bool value) BOOST_NOEXCEPT {
|
Chris@102
|
371 CharT const czero = lcast_char_constants<CharT>::zero;
|
Chris@102
|
372 Traits::assign(buffer[0], Traits::to_char_type(czero + value));
|
Chris@102
|
373 finish = start + 1;
|
Chris@102
|
374 return true;
|
Chris@102
|
375 }
|
Chris@102
|
376
|
Chris@102
|
377 template <class C>
|
Chris@102
|
378 BOOST_DEDUCED_TYPENAME boost::disable_if<boost::is_const<C>, bool>::type
|
Chris@102
|
379 operator<<(const iterator_range<C*>& rng) BOOST_NOEXCEPT {
|
Chris@102
|
380 return (*this) << iterator_range<const C*>(rng.begin(), rng.end());
|
Chris@102
|
381 }
|
Chris@102
|
382
|
Chris@102
|
383 bool operator<<(const iterator_range<const CharT*>& rng) BOOST_NOEXCEPT {
|
Chris@102
|
384 start = rng.begin();
|
Chris@102
|
385 finish = rng.end();
|
Chris@102
|
386 return true;
|
Chris@102
|
387 }
|
Chris@102
|
388
|
Chris@102
|
389 bool operator<<(const iterator_range<const signed char*>& rng) BOOST_NOEXCEPT {
|
Chris@102
|
390 return (*this) << iterator_range<const char*>(
|
Chris@102
|
391 reinterpret_cast<const char*>(rng.begin()),
|
Chris@102
|
392 reinterpret_cast<const char*>(rng.end())
|
Chris@102
|
393 );
|
Chris@102
|
394 }
|
Chris@102
|
395
|
Chris@102
|
396 bool operator<<(const iterator_range<const unsigned char*>& rng) BOOST_NOEXCEPT {
|
Chris@102
|
397 return (*this) << iterator_range<const char*>(
|
Chris@102
|
398 reinterpret_cast<const char*>(rng.begin()),
|
Chris@102
|
399 reinterpret_cast<const char*>(rng.end())
|
Chris@102
|
400 );
|
Chris@102
|
401 }
|
Chris@102
|
402
|
Chris@102
|
403 bool operator<<(char ch) { return shl_char(ch); }
|
Chris@102
|
404 bool operator<<(unsigned char ch) { return ((*this) << static_cast<char>(ch)); }
|
Chris@102
|
405 bool operator<<(signed char ch) { return ((*this) << static_cast<char>(ch)); }
|
Chris@102
|
406 #if !defined(BOOST_LCAST_NO_WCHAR_T)
|
Chris@102
|
407 bool operator<<(wchar_t const* str) { return shl_char_array(str); }
|
Chris@102
|
408 bool operator<<(wchar_t * str) { return shl_char_array(str); }
|
Chris@102
|
409 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
Chris@102
|
410 bool operator<<(wchar_t ch) { return shl_char(ch); }
|
Chris@102
|
411 #endif
|
Chris@102
|
412 #endif
|
Chris@102
|
413 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
Chris@102
|
414 bool operator<<(char16_t ch) { return shl_char(ch); }
|
Chris@102
|
415 bool operator<<(char16_t * str) { return shl_char_array(str); }
|
Chris@102
|
416 bool operator<<(char16_t const * str) { return shl_char_array(str); }
|
Chris@102
|
417 #endif
|
Chris@102
|
418 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
Chris@102
|
419 bool operator<<(char32_t ch) { return shl_char(ch); }
|
Chris@102
|
420 bool operator<<(char32_t * str) { return shl_char_array(str); }
|
Chris@102
|
421 bool operator<<(char32_t const * str) { return shl_char_array(str); }
|
Chris@102
|
422 #endif
|
Chris@102
|
423 bool operator<<(unsigned char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
|
Chris@102
|
424 bool operator<<(unsigned char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
|
Chris@102
|
425 bool operator<<(signed char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
|
Chris@102
|
426 bool operator<<(signed char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
|
Chris@102
|
427 bool operator<<(char const* str) { return shl_char_array(str); }
|
Chris@102
|
428 bool operator<<(char* str) { return shl_char_array(str); }
|
Chris@102
|
429 bool operator<<(short n) { return shl_signed(n); }
|
Chris@102
|
430 bool operator<<(int n) { return shl_signed(n); }
|
Chris@102
|
431 bool operator<<(long n) { return shl_signed(n); }
|
Chris@102
|
432 bool operator<<(unsigned short n) { return shl_unsigned(n); }
|
Chris@102
|
433 bool operator<<(unsigned int n) { return shl_unsigned(n); }
|
Chris@102
|
434 bool operator<<(unsigned long n) { return shl_unsigned(n); }
|
Chris@102
|
435
|
Chris@102
|
436 #if defined(BOOST_HAS_LONG_LONG)
|
Chris@102
|
437 bool operator<<(boost::ulong_long_type n) { return shl_unsigned(n); }
|
Chris@102
|
438 bool operator<<(boost::long_long_type n) { return shl_signed(n); }
|
Chris@102
|
439 #elif defined(BOOST_HAS_MS_INT64)
|
Chris@102
|
440 bool operator<<(unsigned __int64 n) { return shl_unsigned(n); }
|
Chris@102
|
441 bool operator<<( __int64 n) { return shl_signed(n); }
|
Chris@102
|
442 #endif
|
Chris@102
|
443
|
Chris@102
|
444 #ifdef BOOST_HAS_INT128
|
Chris@102
|
445 bool operator<<(const boost::uint128_type& n) { return shl_unsigned(n); }
|
Chris@102
|
446 bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
|
Chris@102
|
447 #endif
|
Chris@102
|
448 bool operator<<(float val) { return shl_real(val); }
|
Chris@102
|
449 bool operator<<(double val) { return shl_real(val); }
|
Chris@102
|
450 bool operator<<(long double val) {
|
Chris@102
|
451 #ifndef __MINGW32__
|
Chris@102
|
452 return shl_real(val);
|
Chris@102
|
453 #else
|
Chris@102
|
454 return shl_real(static_cast<double>(val));
|
Chris@102
|
455 #endif
|
Chris@102
|
456 }
|
Chris@102
|
457
|
Chris@102
|
458 // Adding constness to characters. Constness does not change layout
|
Chris@102
|
459 template <class C, std::size_t N>
|
Chris@102
|
460 BOOST_DEDUCED_TYPENAME boost::disable_if<boost::is_const<C>, bool>::type
|
Chris@102
|
461 operator<<(boost::array<C, N> const& input) BOOST_NOEXCEPT {
|
Chris@102
|
462 BOOST_STATIC_ASSERT_MSG(
|
Chris@102
|
463 (sizeof(boost::array<const C, N>) == sizeof(boost::array<C, N>)),
|
Chris@102
|
464 "boost::array<C, N> and boost::array<const C, N> must have exactly the same layout."
|
Chris@102
|
465 );
|
Chris@102
|
466 return ((*this) << reinterpret_cast<boost::array<const C, N> const& >(input));
|
Chris@102
|
467 }
|
Chris@102
|
468
|
Chris@102
|
469 template <std::size_t N>
|
Chris@102
|
470 bool operator<<(boost::array<const CharT, N> const& input) BOOST_NOEXCEPT {
|
Chris@102
|
471 return shl_char_array_limited(input.begin(), N);
|
Chris@102
|
472 }
|
Chris@102
|
473
|
Chris@102
|
474 template <std::size_t N>
|
Chris@102
|
475 bool operator<<(boost::array<const unsigned char, N> const& input) BOOST_NOEXCEPT {
|
Chris@102
|
476 return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input));
|
Chris@102
|
477 }
|
Chris@102
|
478
|
Chris@102
|
479 template <std::size_t N>
|
Chris@102
|
480 bool operator<<(boost::array<const signed char, N> const& input) BOOST_NOEXCEPT {
|
Chris@102
|
481 return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input));
|
Chris@102
|
482 }
|
Chris@102
|
483
|
Chris@102
|
484 #ifndef BOOST_NO_CXX11_HDR_ARRAY
|
Chris@102
|
485 // Making a Boost.Array from std::array
|
Chris@102
|
486 template <class C, std::size_t N>
|
Chris@102
|
487 bool operator<<(std::array<C, N> const& input) BOOST_NOEXCEPT {
|
Chris@102
|
488 BOOST_STATIC_ASSERT_MSG(
|
Chris@102
|
489 (sizeof(std::array<C, N>) == sizeof(boost::array<C, N>)),
|
Chris@102
|
490 "std::array and boost::array must have exactly the same layout. "
|
Chris@102
|
491 "Bug in implementation of std::array or boost::array."
|
Chris@102
|
492 );
|
Chris@102
|
493 return ((*this) << reinterpret_cast<boost::array<C, N> const& >(input));
|
Chris@102
|
494 }
|
Chris@102
|
495 #endif
|
Chris@102
|
496 template <class InStreamable>
|
Chris@102
|
497 bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
|
Chris@102
|
498 };
|
Chris@102
|
499
|
Chris@102
|
500
|
Chris@102
|
501 template <class CharT, class Traits>
|
Chris@102
|
502 class lexical_ostream_limited_src: boost::noncopyable {
|
Chris@102
|
503 //`[start, finish)` is the range to output by `operator >>`
|
Chris@102
|
504 const CharT* start;
|
Chris@102
|
505 const CharT* const finish;
|
Chris@102
|
506
|
Chris@102
|
507 public:
|
Chris@102
|
508 lexical_ostream_limited_src(const CharT* begin, const CharT* end) BOOST_NOEXCEPT
|
Chris@102
|
509 : start(begin)
|
Chris@102
|
510 , finish(end)
|
Chris@102
|
511 {}
|
Chris@102
|
512
|
Chris@102
|
513 /************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
|
Chris@102
|
514 private:
|
Chris@102
|
515 template <typename Type>
|
Chris@102
|
516 bool shr_unsigned(Type& output) {
|
Chris@102
|
517 if (start == finish) return false;
|
Chris@102
|
518 CharT const minus = lcast_char_constants<CharT>::minus;
|
Chris@102
|
519 CharT const plus = lcast_char_constants<CharT>::plus;
|
Chris@102
|
520 bool const has_minus = Traits::eq(minus, *start);
|
Chris@102
|
521
|
Chris@102
|
522 /* We won`t use `start' any more, so no need in decrementing it after */
|
Chris@102
|
523 if (has_minus || Traits::eq(plus, *start)) {
|
Chris@102
|
524 ++start;
|
Chris@102
|
525 }
|
Chris@102
|
526
|
Chris@102
|
527 bool const succeed = lcast_ret_unsigned<Traits, Type, CharT>(output, start, finish).convert();
|
Chris@102
|
528
|
Chris@102
|
529 if (has_minus) {
|
Chris@102
|
530 output = static_cast<Type>(0u - output);
|
Chris@102
|
531 }
|
Chris@102
|
532
|
Chris@102
|
533 return succeed;
|
Chris@102
|
534 }
|
Chris@102
|
535
|
Chris@102
|
536 template <typename Type>
|
Chris@102
|
537 bool shr_signed(Type& output) {
|
Chris@102
|
538 if (start == finish) return false;
|
Chris@102
|
539 CharT const minus = lcast_char_constants<CharT>::minus;
|
Chris@102
|
540 CharT const plus = lcast_char_constants<CharT>::plus;
|
Chris@102
|
541 typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
|
Chris@102
|
542 utype out_tmp = 0;
|
Chris@102
|
543 bool const has_minus = Traits::eq(minus, *start);
|
Chris@102
|
544
|
Chris@102
|
545 /* We won`t use `start' any more, so no need in decrementing it after */
|
Chris@102
|
546 if (has_minus || Traits::eq(plus, *start)) {
|
Chris@102
|
547 ++start;
|
Chris@102
|
548 }
|
Chris@102
|
549
|
Chris@102
|
550 bool succeed = lcast_ret_unsigned<Traits, utype, CharT>(out_tmp, start, finish).convert();
|
Chris@102
|
551 if (has_minus) {
|
Chris@102
|
552 utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
|
Chris@102
|
553 succeed = succeed && out_tmp<=comp_val;
|
Chris@102
|
554 output = static_cast<Type>(0u - out_tmp);
|
Chris@102
|
555 } else {
|
Chris@102
|
556 utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
|
Chris@102
|
557 succeed = succeed && out_tmp<=comp_val;
|
Chris@102
|
558 output = static_cast<Type>(out_tmp);
|
Chris@102
|
559 }
|
Chris@102
|
560 return succeed;
|
Chris@102
|
561 }
|
Chris@102
|
562
|
Chris@102
|
563 template<typename InputStreamable>
|
Chris@102
|
564 bool shr_using_base_class(InputStreamable& output)
|
Chris@102
|
565 {
|
Chris@102
|
566 BOOST_STATIC_ASSERT_MSG(
|
Chris@102
|
567 (!boost::is_pointer<InputStreamable>::value),
|
Chris@102
|
568 "boost::lexical_cast can not convert to pointers"
|
Chris@102
|
569 );
|
Chris@102
|
570
|
Chris@102
|
571 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
|
Chris@102
|
572 BOOST_STATIC_ASSERT_MSG((boost::is_same<char, CharT>::value),
|
Chris@102
|
573 "boost::lexical_cast can not convert, because your STL library does not "
|
Chris@102
|
574 "support such conversions. Try updating it."
|
Chris@102
|
575 );
|
Chris@102
|
576 #endif
|
Chris@102
|
577 typedef BOOST_DEDUCED_TYPENAME out_stream_helper_trait<CharT, Traits>::buffer_t
|
Chris@102
|
578 buffer_t;
|
Chris@102
|
579
|
Chris@102
|
580 #if defined(BOOST_NO_STRINGSTREAM)
|
Chris@102
|
581 std::istrstream stream(start, finish - start);
|
Chris@102
|
582 #else
|
Chris@102
|
583
|
Chris@102
|
584 buffer_t buf;
|
Chris@102
|
585 // Usually `istream` and `basic_istream` do not modify
|
Chris@102
|
586 // content of buffer; `buffer_t` assures that this is true
|
Chris@102
|
587 buf.setbuf(const_cast<CharT*>(start), finish - start);
|
Chris@102
|
588 #if defined(BOOST_NO_STD_LOCALE)
|
Chris@102
|
589 std::istream stream(&buf);
|
Chris@102
|
590 #else
|
Chris@102
|
591 std::basic_istream<CharT, Traits> stream(&buf);
|
Chris@102
|
592 #endif // BOOST_NO_STD_LOCALE
|
Chris@102
|
593 #endif // BOOST_NO_STRINGSTREAM
|
Chris@102
|
594
|
Chris@102
|
595 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@102
|
596 stream.exceptions(std::ios::badbit);
|
Chris@102
|
597 try {
|
Chris@102
|
598 #endif
|
Chris@102
|
599 stream.unsetf(std::ios::skipws);
|
Chris@102
|
600 lcast_set_precision(stream, static_cast<InputStreamable*>(0));
|
Chris@102
|
601
|
Chris@102
|
602 return (stream >> output)
|
Chris@102
|
603 && (stream.get() == Traits::eof());
|
Chris@102
|
604
|
Chris@102
|
605 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@102
|
606 } catch (const ::std::ios_base::failure& /*f*/) {
|
Chris@102
|
607 return false;
|
Chris@102
|
608 }
|
Chris@102
|
609 #endif
|
Chris@102
|
610 }
|
Chris@102
|
611
|
Chris@102
|
612 template<class T>
|
Chris@102
|
613 inline bool shr_xchar(T& output) BOOST_NOEXCEPT {
|
Chris@102
|
614 BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
|
Chris@102
|
615 "boost::lexical_cast does not support narrowing of character types."
|
Chris@102
|
616 "Use boost::locale instead" );
|
Chris@102
|
617 bool const ok = (finish - start == 1);
|
Chris@102
|
618 if (ok) {
|
Chris@102
|
619 CharT out;
|
Chris@102
|
620 Traits::assign(out, *start);
|
Chris@102
|
621 output = static_cast<T>(out);
|
Chris@102
|
622 }
|
Chris@102
|
623 return ok;
|
Chris@102
|
624 }
|
Chris@102
|
625
|
Chris@102
|
626 template <std::size_t N, class ArrayT>
|
Chris@102
|
627 bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT {
|
Chris@102
|
628 using namespace std;
|
Chris@102
|
629 const std::size_t size = static_cast<std::size_t>(finish - start);
|
Chris@102
|
630 if (size > N - 1) { // `-1` because we need to store \0 at the end
|
Chris@102
|
631 return false;
|
Chris@102
|
632 }
|
Chris@102
|
633
|
Chris@102
|
634 memcpy(&output[0], start, size * sizeof(CharT));
|
Chris@102
|
635 output[size] = Traits::to_char_type(0);
|
Chris@102
|
636 return true;
|
Chris@102
|
637 }
|
Chris@102
|
638
|
Chris@102
|
639 /************************************ OPERATORS >> ( ... ) ********************************/
|
Chris@102
|
640 public:
|
Chris@102
|
641 bool operator>>(unsigned short& output) { return shr_unsigned(output); }
|
Chris@102
|
642 bool operator>>(unsigned int& output) { return shr_unsigned(output); }
|
Chris@102
|
643 bool operator>>(unsigned long int& output) { return shr_unsigned(output); }
|
Chris@102
|
644 bool operator>>(short& output) { return shr_signed(output); }
|
Chris@102
|
645 bool operator>>(int& output) { return shr_signed(output); }
|
Chris@102
|
646 bool operator>>(long int& output) { return shr_signed(output); }
|
Chris@102
|
647 #if defined(BOOST_HAS_LONG_LONG)
|
Chris@102
|
648 bool operator>>(boost::ulong_long_type& output) { return shr_unsigned(output); }
|
Chris@102
|
649 bool operator>>(boost::long_long_type& output) { return shr_signed(output); }
|
Chris@102
|
650 #elif defined(BOOST_HAS_MS_INT64)
|
Chris@102
|
651 bool operator>>(unsigned __int64& output) { return shr_unsigned(output); }
|
Chris@102
|
652 bool operator>>(__int64& output) { return shr_signed(output); }
|
Chris@102
|
653 #endif
|
Chris@102
|
654
|
Chris@102
|
655 #ifdef BOOST_HAS_INT128
|
Chris@102
|
656 bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); }
|
Chris@102
|
657 bool operator>>(boost::int128_type& output) { return shr_signed(output); }
|
Chris@102
|
658 #endif
|
Chris@102
|
659
|
Chris@102
|
660 bool operator>>(char& output) { return shr_xchar(output); }
|
Chris@102
|
661 bool operator>>(unsigned char& output) { return shr_xchar(output); }
|
Chris@102
|
662 bool operator>>(signed char& output) { return shr_xchar(output); }
|
Chris@102
|
663 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
Chris@102
|
664 bool operator>>(wchar_t& output) { return shr_xchar(output); }
|
Chris@102
|
665 #endif
|
Chris@102
|
666 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
Chris@102
|
667 bool operator>>(char16_t& output) { return shr_xchar(output); }
|
Chris@102
|
668 #endif
|
Chris@102
|
669 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
Chris@102
|
670 bool operator>>(char32_t& output) { return shr_xchar(output); }
|
Chris@102
|
671 #endif
|
Chris@102
|
672 template<class Alloc>
|
Chris@102
|
673 bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) {
|
Chris@102
|
674 str.assign(start, finish); return true;
|
Chris@102
|
675 }
|
Chris@102
|
676
|
Chris@102
|
677 template<class Alloc>
|
Chris@102
|
678 bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) {
|
Chris@102
|
679 str.assign(start, finish); return true;
|
Chris@102
|
680 }
|
Chris@102
|
681
|
Chris@102
|
682 template <std::size_t N>
|
Chris@102
|
683 bool operator>>(boost::array<CharT, N>& output) BOOST_NOEXCEPT {
|
Chris@102
|
684 return shr_std_array<N>(output);
|
Chris@102
|
685 }
|
Chris@102
|
686
|
Chris@102
|
687 template <std::size_t N>
|
Chris@102
|
688 bool operator>>(boost::array<unsigned char, N>& output) BOOST_NOEXCEPT {
|
Chris@102
|
689 return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
|
Chris@102
|
690 }
|
Chris@102
|
691
|
Chris@102
|
692 template <std::size_t N>
|
Chris@102
|
693 bool operator>>(boost::array<signed char, N>& output) BOOST_NOEXCEPT {
|
Chris@102
|
694 return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
|
Chris@102
|
695 }
|
Chris@102
|
696
|
Chris@102
|
697 #ifndef BOOST_NO_CXX11_HDR_ARRAY
|
Chris@102
|
698 template <class C, std::size_t N>
|
Chris@102
|
699 bool operator>>(std::array<C, N>& output) BOOST_NOEXCEPT {
|
Chris@102
|
700 BOOST_STATIC_ASSERT_MSG(
|
Chris@102
|
701 (sizeof(boost::array<C, N>) == sizeof(boost::array<C, N>)),
|
Chris@102
|
702 "std::array<C, N> and boost::array<C, N> must have exactly the same layout."
|
Chris@102
|
703 );
|
Chris@102
|
704 return ((*this) >> reinterpret_cast<boost::array<C, N>& >(output));
|
Chris@102
|
705 }
|
Chris@102
|
706 #endif
|
Chris@102
|
707
|
Chris@102
|
708 bool operator>>(bool& output) BOOST_NOEXCEPT {
|
Chris@102
|
709 output = false; // Suppress warning about uninitalized variable
|
Chris@102
|
710
|
Chris@102
|
711 if (start == finish) return false;
|
Chris@102
|
712 CharT const zero = lcast_char_constants<CharT>::zero;
|
Chris@102
|
713 CharT const plus = lcast_char_constants<CharT>::plus;
|
Chris@102
|
714 CharT const minus = lcast_char_constants<CharT>::minus;
|
Chris@102
|
715
|
Chris@102
|
716 const CharT* const dec_finish = finish - 1;
|
Chris@102
|
717 output = Traits::eq(*dec_finish, zero + 1);
|
Chris@102
|
718 if (!output && !Traits::eq(*dec_finish, zero)) {
|
Chris@102
|
719 return false; // Does not ends on '0' or '1'
|
Chris@102
|
720 }
|
Chris@102
|
721
|
Chris@102
|
722 if (start == dec_finish) return true;
|
Chris@102
|
723
|
Chris@102
|
724 // We may have sign at the beginning
|
Chris@102
|
725 if (Traits::eq(plus, *start) || (Traits::eq(minus, *start) && !output)) {
|
Chris@102
|
726 ++ start;
|
Chris@102
|
727 }
|
Chris@102
|
728
|
Chris@102
|
729 // Skipping zeros
|
Chris@102
|
730 while (start != dec_finish) {
|
Chris@102
|
731 if (!Traits::eq(zero, *start)) {
|
Chris@102
|
732 return false; // Not a zero => error
|
Chris@102
|
733 }
|
Chris@102
|
734
|
Chris@102
|
735 ++ start;
|
Chris@102
|
736 }
|
Chris@102
|
737
|
Chris@102
|
738 return true;
|
Chris@102
|
739 }
|
Chris@102
|
740
|
Chris@102
|
741 private:
|
Chris@102
|
742 // Not optimised converter
|
Chris@102
|
743 template <class T>
|
Chris@102
|
744 bool float_types_converter_internal(T& output) {
|
Chris@102
|
745 if (parse_inf_nan(start, finish, output)) return true;
|
Chris@102
|
746 bool const return_value = shr_using_base_class(output);
|
Chris@102
|
747
|
Chris@102
|
748 /* Some compilers and libraries successfully
|
Chris@102
|
749 * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
|
Chris@102
|
750 * We are trying to provide a unified behaviour,
|
Chris@102
|
751 * so we just forbid such conversions (as some
|
Chris@102
|
752 * of the most popular compilers/libraries do)
|
Chris@102
|
753 * */
|
Chris@102
|
754 CharT const minus = lcast_char_constants<CharT>::minus;
|
Chris@102
|
755 CharT const plus = lcast_char_constants<CharT>::plus;
|
Chris@102
|
756 CharT const capital_e = lcast_char_constants<CharT>::capital_e;
|
Chris@102
|
757 CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
|
Chris@102
|
758 if ( return_value &&
|
Chris@102
|
759 (
|
Chris@102
|
760 Traits::eq(*(finish-1), lowercase_e) // 1.0e
|
Chris@102
|
761 || Traits::eq(*(finish-1), capital_e) // 1.0E
|
Chris@102
|
762 || Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E-
|
Chris@102
|
763 || Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+
|
Chris@102
|
764 )
|
Chris@102
|
765 ) return false;
|
Chris@102
|
766
|
Chris@102
|
767 return return_value;
|
Chris@102
|
768 }
|
Chris@102
|
769
|
Chris@102
|
770 public:
|
Chris@102
|
771 bool operator>>(float& output) { return float_types_converter_internal(output); }
|
Chris@102
|
772 bool operator>>(double& output) { return float_types_converter_internal(output); }
|
Chris@102
|
773 bool operator>>(long double& output) { return float_types_converter_internal(output); }
|
Chris@102
|
774
|
Chris@102
|
775 // Generic istream-based algorithm.
|
Chris@102
|
776 // lcast_streambuf_for_target<InputStreamable>::value is true.
|
Chris@102
|
777 template <typename InputStreamable>
|
Chris@102
|
778 bool operator>>(InputStreamable& output) {
|
Chris@102
|
779 return shr_using_base_class(output);
|
Chris@102
|
780 }
|
Chris@102
|
781 };
|
Chris@102
|
782 }
|
Chris@102
|
783 } // namespace boost
|
Chris@102
|
784
|
Chris@102
|
785 #undef BOOST_LCAST_NO_WCHAR_T
|
Chris@102
|
786
|
Chris@102
|
787 #endif // BOOST_LEXICAL_CAST_DETAIL_CONVERTER_LEXICAL_HPP
|
Chris@102
|
788
|