]> git.lyx.org Git - lyx.git/blob - boost/boost/lexical_cast.hpp
Update boost to 1.53.0
[lyx.git] / boost / boost / lexical_cast.hpp
1 #ifndef BOOST_LEXICAL_CAST_INCLUDED
2 #define BOOST_LEXICAL_CAST_INCLUDED
3
4 // MS compatible compilers support #pragma once
5
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 # pragma once
8 #endif
9
10 // Boost lexical_cast.hpp header  -------------------------------------------//
11 //
12 // See http://www.boost.org/libs/conversion for documentation.
13 // See end of this header for rights and permissions.
14 //
15 // what:  lexical_cast custom keyword cast
16 // who:   contributed by Kevlin Henney,
17 //        enhanced with contributions from Terje Slettebo,
18 //        with additional fixes and suggestions from Gennaro Prota,
19 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
20 //        Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
21 //        Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
22 // when:  November 2000, March 2003, June 2005, June 2006, March 2011 - 2012
23
24 #include <boost/config.hpp>
25 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
26 #define BOOST_LCAST_NO_WCHAR_T
27 #endif
28
29 #include <climits>
30 #include <cstddef>
31 #include <string>
32 #include <cstring>
33 #include <cstdio>
34 #include <typeinfo>
35 #include <exception>
36 #include <boost/limits.hpp>
37 #include <boost/mpl/if.hpp>
38 #include <boost/throw_exception.hpp>
39 #include <boost/type_traits/ice.hpp>
40 #include <boost/type_traits/is_pointer.hpp>
41 #include <boost/static_assert.hpp>
42 #include <boost/detail/lcast_precision.hpp>
43 #include <boost/detail/workaround.hpp>
44
45
46 #ifndef BOOST_NO_STD_LOCALE
47 #   include <locale>
48 #else
49 #   ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
50         // Getting error at this point means, that your STL library is old/lame/misconfigured.
51         // If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
52         // but beware: lexical_cast will understand only 'C' locale delimeters and thousands
53         // separators.
54 #       error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
55 #       error "boost::lexical_cast to use only 'C' locale during conversions."
56 #   endif
57 #endif
58
59 #ifdef BOOST_NO_STRINGSTREAM
60 #include <strstream>
61 #else
62 #include <sstream>
63 #endif
64
65 #ifdef BOOST_NO_TYPEID
66 #define BOOST_LCAST_THROW_BAD_CAST(S, T) throw_exception(bad_lexical_cast())
67 #else
68 #define BOOST_LCAST_THROW_BAD_CAST(Source, Target) \
69     throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)))
70 #endif
71
72 namespace boost
73 {
74     // exception used to indicate runtime lexical_cast failure
75     class BOOST_SYMBOL_VISIBLE bad_lexical_cast :
76     // workaround MSVC bug with std::bad_cast when _HAS_EXCEPTIONS == 0 
77 #if defined(BOOST_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS 
78         public std::exception 
79 #else 
80         public std::bad_cast 
81 #endif 
82
83 #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
84         // under bcc32 5.5.1 bad_cast doesn't derive from exception
85         , public std::exception
86 #endif
87
88     {
89     public:
90         bad_lexical_cast() BOOST_NOEXCEPT :
91 #ifndef BOOST_NO_TYPEID
92           source(&typeid(void)), target(&typeid(void))
93 #else
94           source(0), target(0) // this breaks getters
95 #endif
96         {
97         }
98
99         bad_lexical_cast(
100             const std::type_info &source_type_arg,
101             const std::type_info &target_type_arg) BOOST_NOEXCEPT :
102             source(&source_type_arg), target(&target_type_arg)
103         {
104         }
105
106         const std::type_info &source_type() const
107         {
108             return *source;
109         }
110         const std::type_info &target_type() const
111         {
112             return *target;
113         }
114
115 #ifndef BOOST_NO_CXX11_NOEXCEPT
116         virtual const char *what() const noexcept
117 #else
118         virtual const char *what() const throw()
119 #endif
120         {
121             return "bad lexical cast: "
122                    "source type value could not be interpreted as target";
123         }
124
125 #ifndef BOOST_NO_CXX11_NOEXCEPT
126         virtual ~bad_lexical_cast() BOOST_NOEXCEPT
127 #else
128         virtual ~bad_lexical_cast() throw()
129 #endif
130         {}
131     private:
132         const std::type_info *source;
133         const std::type_info *target;
134     };
135
136     namespace detail // widest_char
137     {
138         template <typename TargetChar, typename SourceChar>
139         struct widest_char
140         {
141             typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
142                 (sizeof(TargetChar) > sizeof(SourceChar))
143                 , TargetChar
144                 , SourceChar >::type type;
145         };
146     }
147 } // namespace boost
148
149 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) && !defined(__PGIC__)
150
151 #include <cmath>
152 #include <istream>
153
154 #ifndef BOOST_NO_CXX11_HDR_ARRAY
155 #include <array>
156 #endif
157
158 #include <boost/array.hpp>
159 #include <boost/numeric/conversion/cast.hpp>
160 #include <boost/type_traits/make_unsigned.hpp>
161 #include <boost/type_traits/is_signed.hpp>
162 #include <boost/type_traits/is_integral.hpp>
163 #include <boost/type_traits/is_arithmetic.hpp>
164 #include <boost/type_traits/remove_pointer.hpp>
165 #include <boost/type_traits/has_left_shift.hpp>
166 #include <boost/type_traits/has_right_shift.hpp>
167 #include <boost/math/special_functions/sign.hpp>
168 #include <boost/math/special_functions/fpclassify.hpp>
169 #include <boost/range/iterator_range_core.hpp>
170 #include <boost/container/container_fwd.hpp>
171 #ifndef BOOST_NO_CWCHAR
172 #   include <cwchar>
173 #endif
174
175 namespace boost {
176
177     namespace detail // is_char_or_wchar<...>
178     {
179         // returns true, if T is one of the character types
180         template < typename T >
181         struct is_char_or_wchar
182         {
183             typedef boost::type_traits::ice_or<
184                     boost::is_same< T, char >::value,
185                     #ifndef BOOST_LCAST_NO_WCHAR_T
186                         boost::is_same< T, wchar_t >::value,
187                     #endif
188                     #ifndef BOOST_NO_CXX11_CHAR16_T
189                         boost::is_same< T, char16_t >::value,
190                     #endif
191                     #ifndef BOOST_NO_CXX11_CHAR32_T
192                         boost::is_same< T, char32_t >::value,
193                     #endif
194                     boost::is_same< T, unsigned char >::value,
195                     boost::is_same< T, signed char >::value
196             > result_type;
197
198             BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
199         };
200     }
201
202     namespace detail // normalize_single_byte_char<Char>
203     {
204         // Converts signed/unsigned char to char
205         template < class Char >
206         struct normalize_single_byte_char 
207         {
208             typedef Char type;
209         };
210
211         template <>
212         struct normalize_single_byte_char< signed char >
213         {
214             typedef char type;
215         };
216
217         template <>
218         struct normalize_single_byte_char< unsigned char >
219         {
220             typedef char type;
221         };
222     }
223
224     namespace detail // deduce_character_type_later<T>
225     {
226         // Helper type, meaning that stram character for T must be deduced 
227         // at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
228         template < class T > struct deduce_character_type_later {};
229     }
230
231     namespace detail // stream_char_common<T>
232     {
233         // Selectors to choose stream character type (common for Source and Target)
234         // Returns one of char, wchar_t, char16_t, char32_t or deduce_character_type_later<T> types
235         // Executed on Stage 1 (See deduce_source_char<T> and deduce_target_char<T>)
236         template < typename Type >
237         struct stream_char_common: public boost::mpl::if_c<
238             boost::detail::is_char_or_wchar< Type >::value,
239             Type,
240             boost::detail::deduce_character_type_later< Type >
241         > {};
242
243         template < typename Char >
244         struct stream_char_common< Char* >: public boost::mpl::if_c<
245             boost::detail::is_char_or_wchar< Char >::value,
246             Char,
247             boost::detail::deduce_character_type_later< Char* >
248         > {};
249
250         template < typename Char >
251         struct stream_char_common< const Char* >: public boost::mpl::if_c<
252             boost::detail::is_char_or_wchar< Char >::value,
253             Char,
254             boost::detail::deduce_character_type_later< const Char* >
255         > {};
256
257         template < typename Char >
258         struct stream_char_common< boost::iterator_range< Char* > >: public boost::mpl::if_c<
259             boost::detail::is_char_or_wchar< Char >::value,
260             Char,
261             boost::detail::deduce_character_type_later< boost::iterator_range< Char* > >
262         > {};
263     
264         template < typename Char >
265         struct stream_char_common< boost::iterator_range< const Char* > >: public boost::mpl::if_c<
266             boost::detail::is_char_or_wchar< Char >::value,
267             Char,
268             boost::detail::deduce_character_type_later< boost::iterator_range< const Char* > >
269         > {};
270
271         template < class Char, class Traits, class Alloc >
272         struct stream_char_common< std::basic_string< Char, Traits, Alloc > >
273         {
274             typedef Char type;
275         };
276
277         template < class Char, class Traits, class Alloc >
278         struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
279         {
280             typedef Char type;
281         };
282
283         template < typename Char, std::size_t N >
284         struct stream_char_common< boost::array< Char, N > >: public boost::mpl::if_c<
285             boost::detail::is_char_or_wchar< Char >::value,
286             Char,
287             boost::detail::deduce_character_type_later< boost::array< Char, N > >
288         > {};
289
290         template < typename Char, std::size_t N >
291         struct stream_char_common< boost::array< const Char, N > >: public boost::mpl::if_c<
292             boost::detail::is_char_or_wchar< Char >::value,
293             Char,
294             boost::detail::deduce_character_type_later< boost::array< const Char, N > >
295         > {};
296
297 #ifndef BOOST_NO_CXX11_HDR_ARRAY
298         template < typename Char, std::size_t N >
299         struct stream_char_common< std::array<Char, N > >: public boost::mpl::if_c<
300             boost::detail::is_char_or_wchar< Char >::value,
301             Char,
302             boost::detail::deduce_character_type_later< std::array< Char, N > >
303         > {};
304
305         template < typename Char, std::size_t N >
306         struct stream_char_common< std::array< const Char, N > >: public boost::mpl::if_c<
307             boost::detail::is_char_or_wchar< Char >::value,
308             Char,
309             boost::detail::deduce_character_type_later< std::array< const Char, N > >
310         > {};
311 #endif
312
313 #if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
314         template <>
315         struct stream_char_common< wchar_t >
316         {
317             typedef char type;
318         };
319 #endif
320     }
321
322     namespace detail // deduce_source_char_impl<T>
323     {
324         // If type T is `deduce_character_type_later` type, then tries to deduce
325         // character type using boost::has_left_shift<T> metafunction.
326         // Otherwise supplied type T is a character type, that must be normalized
327         // using normalize_single_byte_char<Char>.
328         // Executed at Stage 2  (See deduce_source_char<T> and deduce_target_char<T>)
329         template < class Char > 
330         struct deduce_source_char_impl
331         { 
332             typedef BOOST_DEDUCED_TYPENAME boost::detail::normalize_single_byte_char< Char >::type type; 
333         };
334         
335         template < class T > 
336         struct deduce_source_char_impl< deduce_character_type_later< T > > 
337         {
338             typedef boost::has_left_shift< std::basic_ostream< char >, T > result_t;
339
340 #if defined(BOOST_LCAST_NO_WCHAR_T)
341             BOOST_STATIC_ASSERT_MSG((result_t::value), 
342                 "Source type is not std::ostream`able and std::wostream`s are not supported by your STL implementation");
343             typedef char type;
344 #else
345             typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
346                 result_t::value, char, wchar_t
347             >::type type;
348
349             BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_left_shift< std::basic_ostream< type >, T >::value), 
350                 "Source type is neither std::ostream`able nor std::wostream`able");
351 #endif
352         };
353     }
354
355     namespace detail  // deduce_target_char_impl<T>
356     {
357         // If type T is `deduce_character_type_later` type, then tries to deduce
358         // character type using boost::has_right_shift<T> metafunction.
359         // Otherwise supplied type T is a character type, that must be normalized
360         // using normalize_single_byte_char<Char>.
361         // Executed at Stage 2  (See deduce_source_char<T> and deduce_target_char<T>)
362         template < class Char > 
363         struct deduce_target_char_impl 
364         { 
365             typedef BOOST_DEDUCED_TYPENAME normalize_single_byte_char< Char >::type type; 
366         };
367         
368         template < class T > 
369         struct deduce_target_char_impl< deduce_character_type_later<T> > 
370         { 
371             typedef boost::has_right_shift<std::basic_istream<char>, T > result_t;
372
373 #if defined(BOOST_LCAST_NO_WCHAR_T)
374             BOOST_STATIC_ASSERT_MSG((result_t::value), 
375                 "Target type is not std::istream`able and std::wistream`s are not supported by your STL implementation");
376             typedef char type;
377 #else
378             typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
379                 result_t::value, char, wchar_t
380             >::type type;
381             
382             BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value), 
383                 "Target type is neither std::istream`able nor std::wistream`able");
384 #endif
385         };
386     } 
387
388     namespace detail  // deduce_target_char<T> and deduce_source_char<T>
389     {
390         // We deduce stream character types in two stages.
391         //
392         // Stage 1 is common for Target and Source. At Stage 1 we get 
393         // non normalized character type (may contain unsigned/signed char)
394         // or deduce_character_type_later<T> where T is the original type.
395         // Stage 1 is executed by stream_char_common<T>
396         //
397         // At Stage 2 we normalize character types or try to deduce character 
398         // type using metafunctions. 
399         // Stage 2 is executed by deduce_target_char_impl<T> and 
400         // deduce_source_char_impl<T>
401         //
402         // deduce_target_char<T> and deduce_source_char<T> functions combine 
403         // both stages
404
405         template < class T >
406         struct deduce_target_char
407         {
408             typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
409             typedef BOOST_DEDUCED_TYPENAME deduce_target_char_impl< stage1_type >::type stage2_type;
410
411             typedef stage2_type type;
412         };
413
414         template < class T >
415         struct deduce_source_char
416         {
417             typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
418             typedef BOOST_DEDUCED_TYPENAME deduce_source_char_impl< stage1_type >::type stage2_type;
419
420             typedef stage2_type type;
421         };
422     }
423
424     namespace detail // deduce_char_traits template
425     {
426         // We are attempting to get char_traits<> from Source or Tagret
427         // template parameter. Otherwise we'll be using std::char_traits<Char>
428         template < class Char, class Target, class Source >
429         struct deduce_char_traits
430         {
431             typedef std::char_traits< Char > type;
432         };
433
434         template < class Char, class Traits, class Alloc, class Source >
435         struct deduce_char_traits< Char
436                                  , std::basic_string< Char, Traits, Alloc >
437                                  , Source
438                                  >
439         {
440             typedef Traits type;
441         };
442
443         template < class Char, class Target, class Traits, class Alloc >
444         struct deduce_char_traits< Char
445                                  , Target
446                                  , std::basic_string< Char, Traits, Alloc >
447                                  >
448         {
449             typedef Traits type;
450         };
451
452         template < class Char, class Traits, class Alloc, class Source >
453         struct deduce_char_traits< Char
454                                  , boost::container::basic_string< Char, Traits, Alloc >
455                                  , Source
456                                  >
457         {
458             typedef Traits type;
459         };
460
461         template < class Char, class Target, class Traits, class Alloc >
462         struct deduce_char_traits< Char
463                                  , Target
464                                  , boost::container::basic_string< Char, Traits, Alloc >
465                                  >
466         {
467             typedef Traits type;
468         };
469
470         template < class Char, class Traits, class Alloc1, class Alloc2 >
471         struct deduce_char_traits< Char
472                                  , std::basic_string< Char, Traits, Alloc1 >
473                                  , std::basic_string< Char, Traits, Alloc2 >
474                                  >
475         {
476             typedef Traits type;
477         };
478
479         template<class Char, class Traits, class Alloc1, class Alloc2>
480         struct deduce_char_traits< Char
481                                  , boost::container::basic_string< Char, Traits, Alloc1 >
482                                  , boost::container::basic_string< Char, Traits, Alloc2 >
483                                  >
484         {
485             typedef Traits type;
486         };
487
488         template < class Char, class Traits, class Alloc1, class Alloc2 >
489         struct deduce_char_traits< Char
490                                  , boost::container::basic_string< Char, Traits, Alloc1 >
491                                  , std::basic_string< Char, Traits, Alloc2 >
492                                  >
493         {
494             typedef Traits type;
495         };
496
497         template < class Char, class Traits, class Alloc1, class Alloc2 >
498         struct deduce_char_traits< Char
499                                  , std::basic_string< Char, Traits, Alloc1 >
500                                  , boost::container::basic_string< Char, Traits, Alloc2 >
501                                  >
502         {
503             typedef Traits type;
504         };
505     }
506
507     namespace detail // array_to_pointer_decay<T>
508     {
509         template<class T>
510         struct array_to_pointer_decay
511         {
512             typedef T type;
513         };
514
515         template<class T, std::size_t N>
516         struct array_to_pointer_decay<T[N]>
517         {
518             typedef const T * type;
519         };
520     }
521
522     namespace detail // is_this_float_conversion_optimized<Float, Char>
523     {
524         // this metafunction evaluates to true, if we have optimized comnversion 
525         // from Float type to Char array. 
526         // Must be in sync with lexical_stream_limited_src<Char, ...>::shl_real_type(...)
527         template <typename Float, typename Char>
528         struct is_this_float_conversion_optimized 
529         {
530             typedef boost::type_traits::ice_and<
531                 boost::is_float<Float>::value,
532 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
533                 boost::type_traits::ice_or<
534                     boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value,
535                     boost::is_same<Char, wchar_t>::value
536                 >::value
537 #else
538                 boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value
539 #endif
540             > result_type;
541
542             BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
543         };
544     }
545     
546     namespace detail // lcast_src_length
547     {
548         // Return max. length of string representation of Source;
549         template< class Source // Source type of lexical_cast.
550                 >
551         struct lcast_src_length
552         {
553             BOOST_STATIC_CONSTANT(std::size_t, value = 1);
554             // To check coverage, build the test with
555             // bjam --v2 profile optimization=off
556             static void check_coverage() {}
557         };
558
559         // Helper for integral types.
560         // Notes on length calculation:
561         // Max length for 32bit int with grouping "\1" and thousands_sep ',':
562         // "-2,1,4,7,4,8,3,6,4,7"
563         //  ^                    - is_signed
564         //   ^                   - 1 digit not counted by digits10
565         //    ^^^^^^^^^^^^^^^^^^ - digits10 * 2
566         //
567         // Constant is_specialized is used instead of constant 1
568         // to prevent buffer overflow in a rare case when
569         // <boost/limits.hpp> doesn't add missing specialization for
570         // numeric_limits<T> for some integral type T.
571         // When is_specialized is false, the whole expression is 0.
572         template<class Source>
573         struct lcast_src_length_integral
574         {
575 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
576             BOOST_STATIC_CONSTANT(std::size_t, value =
577                   std::numeric_limits<Source>::is_signed +
578                   std::numeric_limits<Source>::is_specialized + /* == 1 */
579                   std::numeric_limits<Source>::digits10 * 2
580               );
581 #else
582             BOOST_STATIC_CONSTANT(std::size_t, value = 156);
583             BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
584 #endif
585         };
586
587 #define BOOST_LCAST_DEF(T)               \
588     template<> struct lcast_src_length<T> \
589         : lcast_src_length_integral<T>           \
590     { static void check_coverage() {} };
591
592         BOOST_LCAST_DEF(short)
593         BOOST_LCAST_DEF(unsigned short)
594         BOOST_LCAST_DEF(int)
595         BOOST_LCAST_DEF(unsigned int)
596         BOOST_LCAST_DEF(long)
597         BOOST_LCAST_DEF(unsigned long)
598 #if defined(BOOST_HAS_LONG_LONG)
599         BOOST_LCAST_DEF(boost::ulong_long_type)
600         BOOST_LCAST_DEF(boost::long_long_type )
601 #elif defined(BOOST_HAS_MS_INT64)
602         BOOST_LCAST_DEF(unsigned __int64)
603         BOOST_LCAST_DEF(         __int64)
604 #endif
605
606 #undef BOOST_LCAST_DEF
607
608 #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
609         // Helper for floating point types.
610         // -1.23456789e-123456
611         // ^                   sign
612         //  ^                  leading digit
613         //   ^                 decimal point 
614         //    ^^^^^^^^         lcast_precision<Source>::value
615         //            ^        "e"
616         //             ^       exponent sign
617         //              ^^^^^^ exponent (assumed 6 or less digits)
618         // sign + leading digit + decimal point + "e" + exponent sign == 5
619         template<class Source>
620         struct lcast_src_length_floating
621         {
622             BOOST_STATIC_ASSERT(
623                     std::numeric_limits<Source>::max_exponent10 <=  999999L &&
624                     std::numeric_limits<Source>::min_exponent10 >= -999999L
625                 );
626             BOOST_STATIC_CONSTANT(std::size_t, value =
627                     5 + lcast_precision<Source>::value + 6
628                 );
629         };
630
631         template<>
632         struct lcast_src_length<float>
633           : lcast_src_length_floating<float>
634         {
635             static void check_coverage() {}
636         };
637
638         template<>
639         struct lcast_src_length<double>
640           : lcast_src_length_floating<double>
641         {
642             static void check_coverage() {}
643         };
644
645         template<>
646         struct lcast_src_length<long double>
647           : lcast_src_length_floating<long double>
648         {
649             static void check_coverage() {}
650         };
651
652 #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
653     }
654
655     namespace detail // lexical_cast_stream_traits<Source, Target>
656     {
657         template <class Source, class Target>
658         struct lexical_cast_stream_traits {
659             typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
660             typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<src>::type            no_cv_src;
661                 
662             typedef boost::detail::deduce_source_char<no_cv_src>                           deduce_src_char_metafunc;
663             typedef BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::type           src_char_t;
664             typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_target_char<Target>::type target_char_t;
665                 
666             typedef BOOST_DEDUCED_TYPENAME boost::detail::widest_char<
667                 target_char_t, src_char_t
668             >::type char_type;
669
670 #if !defined(BOOST_NO_CXX11_CHAR16_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
671             BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char16_t, src_char_t>::value
672                                         && !boost::is_same<char16_t, target_char_t>::value),
673                 "Your compiler does not have full support for char16_t" );
674 #endif
675 #if !defined(BOOST_NO_CXX11_CHAR32_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
676             BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char32_t, src_char_t>::value
677                                         && !boost::is_same<char32_t, target_char_t>::value),
678                 "Your compiler does not have full support for char32_t" );
679 #endif
680
681             typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_char_traits<
682                 char_type, Target, no_cv_src
683             >::type traits;
684
685             typedef boost::type_traits::ice_and<
686                 boost::is_same<char, src_char_t>::value,                                  // source is not a wide character based type
687                 boost::type_traits::ice_ne<sizeof(char), sizeof(target_char_t) >::value,  // target type is based on wide character
688                 boost::type_traits::ice_not<
689                     boost::detail::is_char_or_wchar<no_cv_src>::value                     // single character widening is optimized
690                 >::value                                                                  // and does not requires stringbuffer
691             >   is_string_widening_required_t;
692
693             typedef boost::type_traits::ice_not< boost::type_traits::ice_or<
694                 boost::is_integral<no_cv_src>::value,
695                 boost::detail::is_this_float_conversion_optimized<no_cv_src, char_type >::value,
696                 boost::detail::is_char_or_wchar<
697                     BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type          // if we did not get character type at stage1
698                 >::value                                                                  // then we have no optimization for that type
699             >::value >   is_source_input_not_optimized_t;
700
701             // If we have an optimized conversion for
702             // Source, we do not need to construct stringbuf.
703             BOOST_STATIC_CONSTANT(bool, requires_stringbuf = 
704                 (boost::type_traits::ice_or<
705                     is_string_widening_required_t::value, is_source_input_not_optimized_t::value
706                 >::value)
707             );
708             
709             typedef boost::detail::lcast_src_length<no_cv_src> len_t;
710         };
711     }
712
713     namespace detail // '0', '+' and '-' constants
714     {
715         template < typename Char > struct lcast_char_constants;
716
717         template<>
718         struct lcast_char_constants<char>
719         {
720             BOOST_STATIC_CONSTANT(char, zero  = '0');
721             BOOST_STATIC_CONSTANT(char, minus = '-');
722             BOOST_STATIC_CONSTANT(char, plus = '+');
723             BOOST_STATIC_CONSTANT(char, lowercase_e = 'e');
724             BOOST_STATIC_CONSTANT(char, capital_e = 'E');
725             BOOST_STATIC_CONSTANT(char, c_decimal_separator = '.');
726         };
727
728 #ifndef BOOST_LCAST_NO_WCHAR_T
729         template<>
730         struct lcast_char_constants<wchar_t>
731         {
732             BOOST_STATIC_CONSTANT(wchar_t, zero  = L'0');
733             BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
734             BOOST_STATIC_CONSTANT(wchar_t, plus = L'+');
735             BOOST_STATIC_CONSTANT(wchar_t, lowercase_e = L'e');
736             BOOST_STATIC_CONSTANT(wchar_t, capital_e = L'E');
737             BOOST_STATIC_CONSTANT(wchar_t, c_decimal_separator = L'.');
738         };
739 #endif
740
741 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
742         template<>
743         struct lcast_char_constants<char16_t>
744         {
745             BOOST_STATIC_CONSTANT(char16_t, zero  = u'0');
746             BOOST_STATIC_CONSTANT(char16_t, minus = u'-');
747             BOOST_STATIC_CONSTANT(char16_t, plus = u'+');
748             BOOST_STATIC_CONSTANT(char16_t, lowercase_e = u'e');
749             BOOST_STATIC_CONSTANT(char16_t, capital_e = u'E');
750             BOOST_STATIC_CONSTANT(char16_t, c_decimal_separator = u'.');
751         };
752 #endif
753
754 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
755         template<>
756         struct lcast_char_constants<char32_t>
757         {
758             BOOST_STATIC_CONSTANT(char32_t, zero  = U'0');
759             BOOST_STATIC_CONSTANT(char32_t, minus = U'-');
760             BOOST_STATIC_CONSTANT(char32_t, plus = U'+');
761             BOOST_STATIC_CONSTANT(char32_t, lowercase_e = U'e');
762             BOOST_STATIC_CONSTANT(char32_t, capital_e = U'E');
763             BOOST_STATIC_CONSTANT(char32_t, c_decimal_separator = U'.');
764         };
765 #endif
766     }
767
768     namespace detail // lcast_to_unsigned
769     {
770         template<class T>
771         inline
772         BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
773         {
774             typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
775             return static_cast<result_type>(
776                 value < 0 ? 0u - static_cast<result_type>(value) : value
777             );
778         }
779     }
780
781     namespace detail // lcast_put_unsigned
782     {
783         template<class Traits, class T, class CharT>
784         CharT* lcast_put_unsigned(const T n_param, CharT* finish)
785         {
786 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
787             BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
788 #endif
789
790             typedef typename Traits::int_type int_type;
791             CharT const czero = lcast_char_constants<CharT>::zero;
792             int_type const zero = Traits::to_int_type(czero);
793             BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
794                     (sizeof(int_type) > sizeof(T))
795                     , int_type
796                     , T
797             >::type n = n_param;
798
799 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
800             std::locale loc;
801             if (loc != std::locale::classic()) {
802                 typedef std::numpunct<CharT> numpunct;
803                 numpunct const& np = BOOST_USE_FACET(numpunct, loc);
804                 std::string const grouping = np.grouping();
805                 std::string::size_type const grouping_size = grouping.size();
806
807                 if ( grouping_size && grouping[0] > 0 )
808                 {
809
810 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
811                 // Check that ulimited group is unreachable:
812                 BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
813 #endif
814                     CharT thousands_sep = np.thousands_sep();
815                     std::string::size_type group = 0; // current group number
816                     char last_grp_size = grouping[0];
817                     char left = last_grp_size;
818
819                     do
820                     {
821                         if(left == 0)
822                         {
823                             ++group;
824                             if(group < grouping_size)
825                             {
826                                 char const grp_size = grouping[group];
827                                 last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
828                             }
829
830                             left = last_grp_size;
831                             --finish;
832                             Traits::assign(*finish, thousands_sep);
833                         }
834
835                         --left;
836
837                         --finish;
838                         int_type const digit = static_cast<int_type>(n % 10U);
839                         Traits::assign(*finish, Traits::to_char_type(zero + digit));
840                         n /= 10;
841                     } while(n);
842                     return finish;
843                 }
844             }
845 #endif
846             {
847                 do
848                 {
849                     --finish;
850                     int_type const digit = static_cast<int_type>(n % 10U);
851                     Traits::assign(*finish, Traits::to_char_type(zero + digit));
852                     n /= 10;
853                 } while(n);
854             }
855
856             return finish;
857         }
858     }
859
860     namespace detail // lcast_ret_unsigned
861     {
862         template<class Traits, class T, class CharT>
863         inline bool lcast_ret_unsigned(T& value, const CharT* const begin, const CharT* end)
864         {
865 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
866             BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
867 #endif
868             typedef typename Traits::int_type int_type;
869             CharT const czero = lcast_char_constants<CharT>::zero;
870             --end;
871             value = 0;
872
873             if (begin > end || *end < czero || *end >= czero + 10)
874                 return false;
875             value = *end - czero;
876             --end;
877             T multiplier = 1;
878             bool multiplier_overflowed = false;
879
880 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
881             std::locale loc;
882             if (loc != std::locale::classic()) {
883                 typedef std::numpunct<CharT> numpunct;
884                 numpunct const& np = BOOST_USE_FACET(numpunct, loc);
885                 std::string const& grouping = np.grouping();
886                 std::string::size_type const grouping_size = grouping.size();
887
888                 /* According to Programming languages - C++
889                  * we MUST check for correct grouping
890                  */
891                 if (grouping_size && grouping[0] > 0)
892                 {
893                     unsigned char current_grouping = 0;
894                     CharT const thousands_sep = np.thousands_sep();
895                     char remained = grouping[current_grouping] - 1;
896                     bool shall_we_return = true;
897
898                     for(;end>=begin; --end)
899                     {
900                         if (remained) {
901                             T const multiplier_10 = multiplier * 10;
902                             if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
903
904                             T const dig_value = *end - czero;
905                             T const new_sub_value = multiplier_10 * dig_value;
906
907                             if (*end < czero || *end >= czero + 10
908                                     /* detecting overflow */
909                                     || (dig_value && new_sub_value / dig_value != multiplier_10)
910                                     || static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
911                                     || (multiplier_overflowed && dig_value)
912                                     )
913                                 return false;
914
915                             value += new_sub_value;
916                             multiplier *= 10;
917                             --remained;
918                         } else {
919                             if ( !Traits::eq(*end, thousands_sep) ) //|| begin == end ) return false;
920                             {
921                                 /*
922                                  * According to Programming languages - C++
923                                  * Digit grouping is checked. That is, the positions of discarded
924                                  * separators is examined for consistency with
925                                  * use_facet<numpunct<charT> >(loc ).grouping()
926                                  *
927                                  * BUT what if there is no separators at all and grouping()
928                                  * is not empty? Well, we have no extraced separators, so we
929                                  * won`t check them for consistency. This will allow us to
930                                  * work with "C" locale from other locales
931                                  */
932                                 shall_we_return = false;
933                                 break;
934                             } else {
935                                 if ( begin == end ) return false;
936                                 if (current_grouping < grouping_size-1 ) ++current_grouping;
937                                 remained = grouping[current_grouping];
938                             }
939                         }
940                     }
941
942                     if (shall_we_return) return true;
943                 }
944             }
945 #endif
946             {
947                 while ( begin <= end )
948                 {
949                     T const multiplier_10 = multiplier * 10;
950                     if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
951
952                     T const dig_value = *end - czero;
953                     T const new_sub_value = multiplier_10 * dig_value;
954
955                     if (*end < czero || *end >= czero + 10
956                             /* detecting overflow */
957                             || (dig_value && new_sub_value / dig_value != multiplier_10)
958                             || static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
959                             || (multiplier_overflowed && dig_value)
960                             )
961                         return false;
962
963                     value += new_sub_value;
964                     multiplier *= 10;
965                     --end;
966                 }
967             }
968             return true;
969         }
970     }
971
972     namespace detail
973     {
974         template <class CharT>
975         bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) BOOST_NOEXCEPT {
976             for( unsigned int i=0; i < len; ++i ) {
977                 if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false;
978             }
979
980             return true;
981         }
982
983         /* Returns true and sets the correct value if found NaN or Inf. */
984         template <class CharT, class T>
985         inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
986             , const CharT* lc_NAN, const CharT* lc_nan
987             , const CharT* lc_INFINITY, const CharT* lc_infinity
988             , const CharT opening_brace, const CharT closing_brace) BOOST_NOEXCEPT
989         {
990             using namespace std;
991             if (begin == end) return false;
992             const CharT minus = lcast_char_constants<CharT>::minus;
993             const CharT plus = lcast_char_constants<CharT>::plus;
994             const int inifinity_size = 8;
995
996             bool has_minus = false;
997             /* Parsing +/- */
998             if( *begin == minus)
999             {
1000                 ++ begin;
1001                 has_minus = true;
1002             }
1003             else if( *begin == plus ) ++begin;
1004
1005             if( end-begin < 3 ) return false;
1006             if( lc_iequal(begin, lc_nan, lc_NAN, 3) )
1007             {
1008                 begin += 3;
1009                 if (end != begin) /* It is 'nan(...)' or some bad input*/
1010                 {
1011                     if(end-begin<2) return false; // bad input
1012                     -- end;
1013                     if( *begin != opening_brace || *end != closing_brace) return false; // bad input
1014                 }
1015
1016                 if( !has_minus ) value = std::numeric_limits<T>::quiet_NaN();
1017                 else value = (boost::math::changesign) (std::numeric_limits<T>::quiet_NaN());
1018                 return true;
1019             } else
1020             if (( /* 'INF' or 'inf' */
1021                   end-begin==3
1022                   &&
1023                   lc_iequal(begin, lc_infinity, lc_INFINITY, 3)
1024                 )
1025                 ||
1026                 ( /* 'INFINITY' or 'infinity' */
1027                   end-begin==inifinity_size
1028                   &&
1029                   lc_iequal(begin, lc_infinity, lc_INFINITY, inifinity_size)
1030                 )
1031              )
1032             {
1033                 if( !has_minus ) value = std::numeric_limits<T>::infinity();
1034                 else value = (boost::math::changesign) (std::numeric_limits<T>::infinity());
1035                 return true;
1036             }
1037
1038             return false;
1039         }
1040
1041         template <class CharT, class T>
1042         bool put_inf_nan_impl(CharT* begin, CharT*& end, const T& value
1043                          , const CharT* lc_nan
1044                          , const CharT* lc_infinity) BOOST_NOEXCEPT
1045         {
1046             using namespace std;
1047             const CharT minus = lcast_char_constants<CharT>::minus;
1048             if ( (boost::math::isnan)(value) )
1049             {
1050                 if ( (boost::math::signbit)(value) )
1051                 {
1052                     *begin = minus;
1053                     ++ begin;
1054                 }
1055
1056                 memcpy(begin, lc_nan, 3 * sizeof(CharT));
1057                 end = begin + 3;
1058                 return true;
1059             } else if ( (boost::math::isinf)(value) )
1060             {
1061                 if ( (boost::math::signbit)(value) )
1062                 {
1063                     *begin = minus;
1064                     ++ begin;
1065                 }
1066
1067                 memcpy(begin, lc_infinity, 3 * sizeof(CharT));
1068                 end = begin + 3;
1069                 return true;
1070             }
1071
1072             return false;
1073         }
1074
1075
1076 #ifndef BOOST_LCAST_NO_WCHAR_T
1077         template <class T>
1078         bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) BOOST_NOEXCEPT
1079         {
1080             return parse_inf_nan_impl(begin, end, value
1081                                , L"NAN", L"nan"
1082                                , L"INFINITY", L"infinity"
1083                                , L'(', L')');
1084         }
1085
1086         template <class T>
1087         bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) BOOST_NOEXCEPT
1088         {
1089             return put_inf_nan_impl(begin, end, value, L"nan", L"infinity");
1090         }
1091
1092 #endif
1093 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
1094         template <class T>
1095         bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) BOOST_NOEXCEPT
1096         {
1097             return parse_inf_nan_impl(begin, end, value
1098                                , u"NAN", u"nan"
1099                                , u"INFINITY", u"infinity"
1100                                , u'(', u')');
1101         }
1102
1103         template <class T>
1104         bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) BOOST_NOEXCEPT
1105         {
1106             return put_inf_nan_impl(begin, end, value, u"nan", u"infinity");
1107         }
1108 #endif
1109 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
1110         template <class T>
1111         bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) BOOST_NOEXCEPT
1112         {
1113             return parse_inf_nan_impl(begin, end, value
1114                                , U"NAN", U"nan"
1115                                , U"INFINITY", U"infinity"
1116                                , U'(', U')');
1117         }
1118
1119         template <class T>
1120         bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) BOOST_NOEXCEPT
1121         {
1122             return put_inf_nan_impl(begin, end, value, U"nan", U"infinity");
1123         }
1124 #endif
1125
1126         template <class CharT, class T>
1127         bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) BOOST_NOEXCEPT
1128         {
1129             return parse_inf_nan_impl(begin, end, value
1130                                , "NAN", "nan"
1131                                , "INFINITY", "infinity"
1132                                , '(', ')');
1133         }
1134
1135         template <class CharT, class T>
1136         bool put_inf_nan(CharT* begin, CharT*& end, const T& value) BOOST_NOEXCEPT
1137         {
1138             return put_inf_nan_impl(begin, end, value, "nan", "infinity");
1139         }
1140     }
1141
1142
1143     namespace detail // lcast_ret_float
1144     {
1145         template <class T>
1146         struct mantissa_holder_type
1147         {
1148             /* Can not be used with this type */
1149         };
1150
1151         template <>
1152         struct mantissa_holder_type<float>
1153         {
1154             typedef unsigned int type;
1155         };
1156
1157         template <>
1158         struct mantissa_holder_type<double>
1159         {
1160 #if defined(BOOST_HAS_LONG_LONG)
1161             typedef boost::ulong_long_type type;
1162 #elif defined(BOOST_HAS_MS_INT64)
1163             typedef unsigned __int64 type;
1164 #endif
1165         };
1166
1167         template<class Traits, class T, class CharT>
1168         inline bool lcast_ret_float(T& value, const CharT* begin, const CharT* end)
1169         {
1170
1171 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
1172             std::locale loc;
1173             typedef std::numpunct<CharT> numpunct;
1174             numpunct const& np = BOOST_USE_FACET(numpunct, loc);
1175             std::string const grouping(
1176                     (loc == std::locale::classic())
1177                     ? std::string()
1178                     : np.grouping()
1179             );
1180             std::string::size_type const grouping_size = grouping.size();
1181             CharT const thousands_sep = grouping_size ? np.thousands_sep() : 0;
1182             CharT const decimal_point = np.decimal_point();
1183             bool found_grouping = false;
1184             std::string::size_type last_grouping_pos = grouping_size - 1;
1185 #else
1186             CharT const decimal_point = lcast_char_constants<CharT>::c_decimal_separator;
1187 #endif
1188
1189             CharT const czero = lcast_char_constants<CharT>::zero;
1190             CharT const minus = lcast_char_constants<CharT>::minus;
1191             CharT const plus = lcast_char_constants<CharT>::plus;
1192             CharT const capital_e = lcast_char_constants<CharT>::capital_e;
1193             CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
1194
1195             value = static_cast<T>(0);
1196
1197             if (parse_inf_nan(begin, end, value)) return true;
1198
1199             typedef typename Traits::int_type int_type;
1200             typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::type mantissa_type;
1201             int_type const zero = Traits::to_int_type(czero);
1202             if (begin == end) return false;
1203
1204             /* Getting the plus/minus sign */
1205             bool has_minus = false;
1206             if (Traits::eq(*begin, minus) ) {
1207                 ++ begin;
1208                 has_minus = true;
1209                 if (begin == end) return false;
1210             } else if (Traits::eq(*begin, plus) ) {
1211                 ++begin;
1212                 if (begin == end) return false;
1213             }
1214
1215             bool found_decimal = false;
1216             bool found_number_before_exp = false;
1217             int pow_of_10 = 0;
1218             mantissa_type mantissa=0;
1219             bool is_mantissa_full = false;
1220
1221             char length_since_last_delim = 0;
1222
1223             while ( begin != end )
1224             {
1225                 if (found_decimal) {
1226                     /* We allow no thousand_separators after decimal point */
1227
1228                     mantissa_type tmp_mantissa = mantissa * 10u;
1229                     if (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) break;
1230                     if ( *begin < czero || *begin >= czero + 10 ) return false;
1231                     if (    is_mantissa_full
1232                             || tmp_mantissa / 10u != mantissa
1233                             || (std::numeric_limits<mantissa_type>::max)()-(*begin - zero) < tmp_mantissa
1234                             ) {
1235                         is_mantissa_full = true;
1236                         ++ begin;
1237                         continue;
1238                     }
1239
1240                     -- pow_of_10;
1241                     mantissa = tmp_mantissa;
1242                     mantissa += *begin - zero;
1243
1244                     found_number_before_exp = true;
1245                 } else {
1246
1247                     if (*begin >= czero && *begin < czero + 10) {
1248
1249                         /* Checking for mantissa overflow. If overflow will
1250                          * occur, them we only increase multiplyer
1251                          */
1252                         mantissa_type tmp_mantissa = mantissa * 10u;
1253                         if(     !is_mantissa_full
1254                                 && tmp_mantissa / 10u == mantissa
1255                                 && (std::numeric_limits<mantissa_type>::max)()-(*begin - zero) >= tmp_mantissa
1256                             )
1257                         {
1258                             mantissa = tmp_mantissa;
1259                             mantissa += *begin - zero;
1260                         } else
1261                         {
1262                             is_mantissa_full = true;
1263                             ++ pow_of_10;
1264                         }
1265
1266                         found_number_before_exp = true;
1267                         ++ length_since_last_delim;
1268                     } else if (Traits::eq(*begin, decimal_point) || Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) {
1269 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
1270                         /* If ( we need to check grouping
1271                          *      and (   grouping missmatches
1272                          *              or grouping position is incorrect
1273                          *              or we are using the grouping position 0 twice
1274                          *           )
1275                          *    ) then return error
1276                          */
1277                         if( grouping_size && found_grouping
1278                             && (
1279                                    length_since_last_delim != grouping[0]
1280                                    || last_grouping_pos>1
1281                                    || (last_grouping_pos==0 && grouping_size>1)
1282                                 )
1283                            ) return false;
1284 #endif
1285
1286                         if(Traits::eq(*begin, decimal_point)) {
1287                             ++ begin;
1288                             found_decimal = true;
1289                             if (!found_number_before_exp && begin==end) return false;
1290                             continue;
1291                         }else {
1292                             if (!found_number_before_exp) return false;
1293                             break;
1294                         }
1295                     }
1296 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
1297                     else if (grouping_size && Traits::eq(*begin, thousands_sep)){
1298                         if(found_grouping)
1299                         {
1300                             /* It is not he first time, when we find thousands separator,
1301                              * so we need to chek, is the distance between two groupings
1302                              * equal to grouping[last_grouping_pos] */
1303
1304                             if (length_since_last_delim != grouping[last_grouping_pos] )
1305                             {
1306                                 if (!last_grouping_pos) return false;
1307                                 else
1308                                 {
1309                                     -- last_grouping_pos;
1310                                     if (length_since_last_delim != grouping[last_grouping_pos]) return false;
1311                                 }
1312                             } else
1313                                 /* We are calling the grouping[0] twice, when grouping size is more than 1 */
1314                                 if (grouping_size>1u && last_grouping_pos+1<grouping_size) return false;
1315
1316                         } else {
1317                             /* Delimiter at the begining ',000' */
1318                             if (!length_since_last_delim) return false;
1319
1320                             found_grouping = true;
1321                             if (length_since_last_delim > grouping[last_grouping_pos] ) return false;
1322                         }
1323
1324                         length_since_last_delim = 0;
1325                         ++ begin;
1326
1327                         /* Delimiter at the end '100,' */
1328                         if (begin == end) return false;
1329                         continue;
1330                     }
1331 #endif
1332                     else return false;
1333                 }
1334
1335                 ++begin;
1336             }
1337
1338             // Exponent found
1339             if ( begin != end && (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) ) {
1340                 ++ begin;
1341                 if ( begin == end ) return false;
1342
1343                 bool exp_has_minus = false;
1344                 if(Traits::eq(*begin, minus)) {
1345                     exp_has_minus = true;
1346                     ++ begin;
1347                     if ( begin == end ) return false;
1348                 } else if (Traits::eq(*begin, plus)) {
1349                     ++ begin;
1350                     if ( begin == end ) return false;
1351                 }
1352
1353                 int exp_pow_of_10 = 0;
1354                 while ( begin != end )
1355                 {
1356                     if ( *begin < czero
1357                             || *begin >= czero + 10
1358                             || exp_pow_of_10 * 10 < exp_pow_of_10) /* Overflows are checked lower more precisely*/
1359                         return false;
1360
1361                     exp_pow_of_10 *= 10;
1362                     exp_pow_of_10 += *begin - zero;
1363                     ++ begin;
1364                 };
1365
1366                 if ( exp_pow_of_10 ) {
1367                     /* Overflows are checked lower */
1368                     if ( exp_has_minus ) {
1369                         pow_of_10 -= exp_pow_of_10;
1370                     } else {
1371                         pow_of_10 += exp_pow_of_10;
1372                     }
1373                 }
1374             }
1375
1376             /* We need a more accurate algorithm... We can not use current algorithm
1377              * with long doubles (and with doubles if sizeof(double)==sizeof(long double)).
1378              */
1379             long double result = std::pow(10.0L, pow_of_10) * mantissa;
1380             value = static_cast<T>( has_minus ? (boost::math::changesign)(result) : result);
1381
1382             if ( (boost::math::isinf)(value) || (boost::math::isnan)(value) ) return false;
1383
1384             return true;
1385         }
1386     }
1387
1388     namespace detail // stl_buf_unlocker
1389     {
1390         template< class BufferType, class CharT >
1391         class stl_buf_unlocker: public BufferType{
1392         public:
1393             typedef BufferType base_class;
1394 #ifndef BOOST_NO_USING_TEMPLATE
1395             using base_class::pptr;
1396             using base_class::pbase;
1397             using base_class::setg;
1398             using base_class::setp;
1399 #else
1400             CharT* pptr() const { return base_class::pptr(); }
1401             CharT* pbase() const { return base_class::pbase(); }
1402             void setg(CharT* gbeg, CharT* gnext, CharT* gend){ return base_class::setg(gbeg, gnext, gend); }
1403             void setp(CharT* pbeg, CharT* pend) { return setp(pbeg, pend); }
1404 #endif
1405         };
1406     }
1407
1408     namespace detail
1409     {
1410         struct do_not_construct_out_stream_t{};
1411     }
1412
1413     namespace detail // optimized stream wrapper
1414     {
1415         // String representation of Source has an upper limit.
1416         template< class CharT // a result of widest_char transformation
1417                 , class Traits // usually char_traits<CharT>
1418                 , bool RequiresStringbuffer
1419                 >
1420         class lexical_stream_limited_src
1421         {
1422
1423 #if defined(BOOST_NO_STRINGSTREAM)
1424             typedef std::ostrstream                         out_stream_t;
1425             typedef stl_buf_unlocker<std::strstreambuf, char>  unlocked_but_t;
1426 #elif defined(BOOST_NO_STD_LOCALE)
1427             typedef std::ostringstream                      out_stream_t;
1428             typedef stl_buf_unlocker<std::stringbuf, char>  unlocked_but_t;
1429 #else
1430             typedef std::basic_ostringstream<CharT, Traits>       out_stream_t;
1431             typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT> unlocked_but_t;
1432 #endif
1433             typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
1434                 RequiresStringbuffer,
1435                 out_stream_t,
1436                 do_not_construct_out_stream_t
1437             >::type deduced_out_stream_t;
1438
1439             // A string representation of Source is written to [start, finish).
1440             CharT* start;
1441             CharT* finish;
1442             deduced_out_stream_t out_stream;
1443
1444         public:
1445             lexical_stream_limited_src(CharT* sta, CharT* fin)
1446               : start(sta)
1447               , finish(fin)
1448             {}
1449
1450         private:
1451             // Undefined:
1452             lexical_stream_limited_src(lexical_stream_limited_src const&);
1453             void operator=(lexical_stream_limited_src const&);
1454
1455 /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
1456             bool shl_char(CharT ch) BOOST_NOEXCEPT
1457             {
1458                 Traits::assign(*start, ch);
1459                 finish = start + 1;
1460                 return true;
1461             }
1462
1463 #ifndef BOOST_LCAST_NO_WCHAR_T
1464             template <class T>
1465             bool shl_char(T ch)
1466             {
1467                 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
1468                     "boost::lexical_cast does not support narrowing of char types."
1469                     "Use boost::locale instead" );
1470 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
1471                 std::locale loc;
1472                 CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
1473 #else
1474                 CharT const w = static_cast<CharT>(ch);
1475 #endif
1476                 Traits::assign(*start, w);
1477                 finish = start + 1;
1478                 return true;
1479             }
1480 #endif
1481
1482             bool shl_char_array(CharT const* str) BOOST_NOEXCEPT
1483             {
1484                 start = const_cast<CharT*>(str);
1485                 finish = start + Traits::length(str);
1486                 return true;
1487             }
1488
1489             template <class T>
1490             bool shl_char_array(T const* str)
1491             {
1492                 BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
1493                     "boost::lexical_cast does not support narrowing of char types."
1494                     "Use boost::locale instead" );
1495                 return shl_input_streamable(str);
1496             }
1497             
1498             bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT
1499             {
1500                 start = const_cast<CharT*>(str);
1501                 finish = std::find(start, start + max_size, Traits::to_char_type(0));
1502                 return true;
1503             }
1504
1505             template<typename InputStreamable>
1506             bool shl_input_streamable(InputStreamable& input)
1507             {
1508 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
1509                 // If you have compilation error at this point, than your STL library
1510                 // does not support such conversions. Try updating it.
1511                 BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
1512 #endif
1513                 bool const result = !(out_stream << input).fail();
1514                 const unlocked_but_t* const p
1515                         = static_cast<unlocked_but_t*>(out_stream.rdbuf()) ;
1516                 start = p->pbase();
1517                 finish = p->pptr();
1518                 return result;
1519             }
1520
1521             template <class T>
1522             inline bool shl_signed(T n)
1523             {
1524                 start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
1525                 if(n < 0)
1526                 {
1527                     --start;
1528                     CharT const minus = lcast_char_constants<CharT>::minus;
1529                     Traits::assign(*start, minus);
1530                 }
1531                 return true;
1532             }
1533
1534             template <class T, class SomeCharT>
1535             bool shl_real_type(const T& val, SomeCharT* begin, SomeCharT*& end)
1536             {
1537                 if (put_inf_nan(begin, end, val)) return true;
1538                 lcast_set_precision(out_stream, &val);
1539                 return shl_input_streamable(val);
1540             }
1541
1542             static bool shl_real_type(float val, char* begin, char*& end)
1543             {   using namespace std;
1544                 if (put_inf_nan(begin, end, val)) return true;
1545                 const double val_as_double = val;
1546                 end = begin + 
1547 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
1548                     sprintf_s(begin, end-begin,
1549 #else
1550                     sprintf(begin, 
1551 #endif
1552                     "%.*g", static_cast<int>(boost::detail::lcast_get_precision<float>()), val_as_double);
1553                 return end > begin;
1554             }
1555
1556             static bool shl_real_type(double val, char* begin, char*& end)
1557             {   using namespace std;
1558                 if (put_inf_nan(begin, end, val)) return true;
1559                 end = begin + 
1560 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
1561                     sprintf_s(begin, end-begin,
1562 #else
1563                     sprintf(begin, 
1564 #endif
1565                     "%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val);
1566                 return end > begin;
1567             }
1568
1569 #ifndef __MINGW32__
1570             static bool shl_real_type(long double val, char* begin, char*& end)
1571             {   using namespace std;
1572                 if (put_inf_nan(begin, end, val)) return true;
1573                 end = begin + 
1574 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
1575                     sprintf_s(begin, end-begin,
1576 #else
1577                     sprintf(begin, 
1578 #endif
1579                     "%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double>()), val );
1580                 return end > begin;
1581             }
1582 #endif
1583
1584
1585 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
1586             static bool shl_real_type(float val, wchar_t* begin, wchar_t*& end)
1587             {   using namespace std;
1588                 if (put_inf_nan(begin, end, val)) return true;
1589                 const double val_as_double = val;
1590                 end = begin + swprintf(begin, end-begin,
1591                                        L"%.*g",
1592                                        static_cast<int>(boost::detail::lcast_get_precision<float >()),
1593                                        val_as_double );
1594                 return end > begin;
1595             }
1596
1597             static bool shl_real_type(double val, wchar_t* begin, wchar_t*& end)
1598             {   using namespace std;
1599                 if (put_inf_nan(begin, end, val)) return true;
1600                 end = begin + swprintf(begin, end-begin,
1601                                           L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
1602                 return end > begin;
1603             }
1604
1605             static bool shl_real_type(long double val, wchar_t* begin, wchar_t*& end)
1606             {   using namespace std;
1607                 if (put_inf_nan(begin, end, val)) return true;
1608                 end = begin + swprintf(begin, end-begin,
1609                                           L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
1610                 return end > begin;
1611             }
1612 #endif
1613
1614 /************************************ OPERATORS << ( ... ) ********************************/
1615         public:
1616             template<class Alloc>
1617             bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
1618             {
1619                 start = const_cast<CharT*>(str.data());
1620                 finish = start + str.length();
1621                 return true;
1622             }
1623
1624             template<class Alloc>
1625             bool operator<<(boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
1626             {
1627                 start = const_cast<CharT*>(str.data());
1628                 finish = start + str.length();
1629                 return true;
1630             }
1631
1632             bool operator<<(bool value) BOOST_NOEXCEPT
1633             {
1634                 CharT const czero = lcast_char_constants<CharT>::zero;
1635                 Traits::assign(*start, Traits::to_char_type(czero + value));
1636                 finish = start + 1;
1637                 return true;
1638             }
1639
1640             bool operator<<(const iterator_range<CharT*>& rng) BOOST_NOEXCEPT
1641             {
1642                 start = rng.begin();
1643                 finish = rng.end();
1644                 return true; 
1645             }
1646             
1647             bool operator<<(const iterator_range<const CharT*>& rng) BOOST_NOEXCEPT
1648             {
1649                 start = const_cast<CharT*>(rng.begin());
1650                 finish = const_cast<CharT*>(rng.end());
1651                 return true; 
1652             }
1653
1654             bool operator<<(const iterator_range<const signed char*>& rng) BOOST_NOEXCEPT
1655             {
1656                 return (*this) << iterator_range<char*>(
1657                     const_cast<char*>(reinterpret_cast<const char*>(rng.begin())),
1658                     const_cast<char*>(reinterpret_cast<const char*>(rng.end()))
1659                 );
1660             }
1661
1662             bool operator<<(const iterator_range<const unsigned char*>& rng) BOOST_NOEXCEPT
1663             {
1664                 return (*this) << iterator_range<char*>(
1665                     const_cast<char*>(reinterpret_cast<const char*>(rng.begin())),
1666                     const_cast<char*>(reinterpret_cast<const char*>(rng.end()))
1667                 );
1668             }
1669
1670             bool operator<<(const iterator_range<signed char*>& rng) BOOST_NOEXCEPT
1671             {
1672                 return (*this) << iterator_range<char*>(
1673                     reinterpret_cast<char*>(rng.begin()),
1674                     reinterpret_cast<char*>(rng.end())
1675                 );
1676             }
1677
1678             bool operator<<(const iterator_range<unsigned char*>& rng) BOOST_NOEXCEPT
1679             {
1680                 return (*this) << iterator_range<char*>(
1681                     reinterpret_cast<char*>(rng.begin()),
1682                     reinterpret_cast<char*>(rng.end())
1683                 );
1684             }
1685
1686             bool operator<<(char ch)                    { return shl_char(ch); }
1687             bool operator<<(unsigned char ch)           { return ((*this) << static_cast<char>(ch)); }
1688             bool operator<<(signed char ch)             { return ((*this) << static_cast<char>(ch)); }
1689 #if !defined(BOOST_LCAST_NO_WCHAR_T)
1690             bool operator<<(wchar_t const* str)         { return shl_char_array(str); }
1691             bool operator<<(wchar_t * str)              { return shl_char_array(str); }
1692 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
1693             bool operator<<(wchar_t ch)                 { return shl_char(ch); }
1694 #endif
1695 #endif
1696 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
1697             bool operator<<(char16_t ch)                { return shl_char(ch); }
1698             bool operator<<(char16_t * str)             { return shl_char_array(str); }
1699             bool operator<<(char16_t const * str)       { return shl_char_array(str); }
1700 #endif
1701 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
1702             bool operator<<(char32_t ch)                { return shl_char(ch); }
1703             bool operator<<(char32_t * str)             { return shl_char_array(str); }
1704             bool operator<<(char32_t const * str)       { return shl_char_array(str); }
1705 #endif
1706             bool operator<<(unsigned char const* ch)    { return ((*this) << reinterpret_cast<char const*>(ch)); }
1707             bool operator<<(unsigned char * ch)         { return ((*this) << reinterpret_cast<char *>(ch)); }
1708             bool operator<<(signed char const* ch)      { return ((*this) << reinterpret_cast<char const*>(ch)); }
1709             bool operator<<(signed char * ch)           { return ((*this) << reinterpret_cast<char *>(ch)); }
1710             bool operator<<(char const* str)            { return shl_char_array(str); }
1711             bool operator<<(char* str)                  { return shl_char_array(str); }
1712             bool operator<<(short n)                    { return shl_signed(n); }
1713             bool operator<<(int n)                      { return shl_signed(n); }
1714             bool operator<<(long n)                     { return shl_signed(n); }
1715             bool operator<<(unsigned short n)           { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1716             bool operator<<(unsigned int n)             { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1717             bool operator<<(unsigned long n)            { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1718
1719 #if defined(BOOST_HAS_LONG_LONG)
1720             bool operator<<(boost::ulong_long_type n)   { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1721             bool operator<<(boost::long_long_type n)    { return shl_signed(n); }
1722 #elif defined(BOOST_HAS_MS_INT64)
1723             bool operator<<(unsigned __int64 n)         { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1724             bool operator<<(         __int64 n)         { return shl_signed(n); }
1725 #endif
1726             bool operator<<(float val)                  { return shl_real_type(val, start, finish); }
1727             bool operator<<(double val)                 { return shl_real_type(val, start, finish); }
1728             bool operator<<(long double val)            {
1729 #ifndef __MINGW32__
1730                 return shl_real_type(val, start, finish);
1731 #else
1732                 return shl_real_type(static_cast<double>(val), start, finish);
1733 #endif
1734             }
1735             
1736             template <std::size_t N>
1737             bool operator<<(boost::array<CharT, N> const& input) BOOST_NOEXCEPT
1738             { return shl_char_array_limited(input.begin(), N); }
1739
1740             template <std::size_t N>
1741             bool operator<<(boost::array<unsigned char, N> const& input) BOOST_NOEXCEPT
1742             { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
1743
1744             template <std::size_t N>
1745             bool operator<<(boost::array<signed char, N> const& input) BOOST_NOEXCEPT
1746             { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
1747
1748             template <std::size_t N>
1749             bool operator<<(boost::array<const CharT, N> const& input) BOOST_NOEXCEPT
1750             { return shl_char_array_limited(input.begin(), N); }
1751
1752             template <std::size_t N>
1753             bool operator<<(boost::array<const unsigned char, N> const& input) BOOST_NOEXCEPT
1754             { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
1755
1756             template <std::size_t N>
1757             bool operator<<(boost::array<const signed char, N> const& input) BOOST_NOEXCEPT
1758             { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
1759  
1760 #ifndef BOOST_NO_CXX11_HDR_ARRAY
1761             template <std::size_t N>
1762             bool operator<<(std::array<CharT, N> const& input) BOOST_NOEXCEPT
1763             { 
1764                 if (input.size()) return shl_char_array_limited(&input[0], N);
1765                 else return true; 
1766             }
1767
1768             template <std::size_t N>
1769             bool operator<<(std::array<unsigned char, N> const& input) BOOST_NOEXCEPT
1770             { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
1771
1772             template <std::size_t N>
1773             bool operator<<(std::array<signed char, N> const& input) BOOST_NOEXCEPT
1774             { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
1775
1776             template <std::size_t N>
1777             bool operator<<(std::array<const CharT, N> const& input) BOOST_NOEXCEPT
1778             { 
1779                 if (input.size()) return shl_char_array_limited(&input[0], N);
1780                 else return true; 
1781             }
1782
1783             template <std::size_t N>
1784             bool operator<<(std::array<const unsigned char, N> const& input) BOOST_NOEXCEPT
1785             { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
1786
1787             template <std::size_t N>
1788             bool operator<<(std::array<const signed char, N> const& input) BOOST_NOEXCEPT
1789             { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
1790 #endif
1791             
1792             template <class InStreamable>
1793             bool operator<<(const InStreamable& input)  { return shl_input_streamable(input); }
1794
1795 /************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
1796         private:
1797
1798             template <typename Type>
1799             bool shr_unsigned(Type& output)
1800             {
1801                 if (start == finish) return false;
1802                 CharT const minus = lcast_char_constants<CharT>::minus;
1803                 CharT const plus = lcast_char_constants<CharT>::plus;
1804                 bool has_minus = false;
1805
1806                 /* We won`t use `start' any more, so no need in decrementing it after */
1807                 if ( Traits::eq(minus,*start) )
1808                 {
1809                     ++start;
1810                     has_minus = true;
1811                 } else if ( Traits::eq( plus, *start ) )
1812                 {
1813                     ++start;
1814                 }
1815
1816                 bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
1817
1818                 if (has_minus) {
1819                     output = static_cast<Type>(0u - output);
1820                 }
1821
1822                 return succeed;
1823             }
1824
1825             template <typename Type>
1826             bool shr_signed(Type& output)
1827             {
1828                 if (start == finish) return false;
1829                 CharT const minus = lcast_char_constants<CharT>::minus;
1830                 CharT const plus = lcast_char_constants<CharT>::plus;
1831                 typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
1832                 utype out_tmp =0;
1833                 bool has_minus = false;
1834
1835                 /* We won`t use `start' any more, so no need in decrementing it after */
1836                 if ( Traits::eq(minus,*start) )
1837                 {
1838                     ++start;
1839                     has_minus = true;
1840                 } else if ( Traits::eq(plus, *start) )
1841                 {
1842                     ++start;
1843                 }
1844
1845                 bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
1846                 if (has_minus) {
1847                     utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
1848                     succeed = succeed && out_tmp<=comp_val;
1849                     output = static_cast<Type>(0u - out_tmp);
1850                 } else {
1851                     utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
1852                     succeed = succeed && out_tmp<=comp_val;
1853                     output = out_tmp;
1854                 }
1855                 return succeed;
1856             }
1857
1858             template<typename InputStreamable>
1859             bool shr_using_base_class(InputStreamable& output)
1860             {
1861 #if (defined _MSC_VER)
1862 # pragma warning( push )
1863   // conditional expression is constant
1864 # pragma warning( disable : 4127 )
1865 #endif
1866                 if(is_pointer<InputStreamable>::value)
1867                     return false;
1868
1869 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
1870                 // If you have compilation error at this point, than your STL library
1871                 // unsupports such conversions. Try updating it.
1872                 BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
1873 #endif
1874
1875 #if defined(BOOST_NO_STRINGSTREAM)
1876                 std::istrstream stream(start, finish - start);
1877 #elif defined(BOOST_NO_STD_LOCALE)
1878                 std::istringstream stream;
1879 #else
1880                 std::basic_istringstream<CharT, Traits> stream;
1881 #endif
1882                 static_cast<unlocked_but_t*>(stream.rdbuf())
1883                         ->setg(start, start, finish);
1884
1885                 stream.unsetf(std::ios::skipws);
1886                 lcast_set_precision(stream, static_cast<InputStreamable*>(0));
1887 #if (defined _MSC_VER)
1888 # pragma warning( pop )
1889 #endif
1890                 return stream >> output &&
1891                     stream.get() ==
1892 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
1893         // GCC 2.9x lacks std::char_traits<>::eof().
1894         // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
1895         // configurations, which do provide std::char_traits<>::eof().
1896
1897                     EOF;
1898 #else
1899                 Traits::eof();
1900 #endif
1901             }
1902
1903             template<class T>
1904             inline bool shr_xchar(T& output)
1905             {
1906                 BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
1907                     "boost::lexical_cast does not support narrowing of character types."
1908                     "Use boost::locale instead" );
1909                 bool const ok = (finish - start == 1);
1910                 if (ok) {
1911                     CharT out;
1912                     Traits::assign(out, *start);
1913                     output = static_cast<T>(out);
1914                 }
1915                 return ok;
1916             }
1917
1918 /************************************ OPERATORS >> ( ... ) ********************************/
1919             public:
1920             bool operator>>(unsigned short& output)             { return shr_unsigned(output); }
1921             bool operator>>(unsigned int& output)               { return shr_unsigned(output); }
1922             bool operator>>(unsigned long int& output)          { return shr_unsigned(output); }
1923             bool operator>>(short& output)                      { return shr_signed(output); }
1924             bool operator>>(int& output)                        { return shr_signed(output); }
1925             bool operator>>(long int& output)                   { return shr_signed(output); }
1926 #if defined(BOOST_HAS_LONG_LONG)
1927             bool operator>>(boost::ulong_long_type& output)     { return shr_unsigned(output); }
1928             bool operator>>(boost::long_long_type& output)      { return shr_signed(output); }
1929 #elif defined(BOOST_HAS_MS_INT64)
1930             bool operator>>(unsigned __int64& output)           { return shr_unsigned(output); }
1931             bool operator>>(__int64& output)                    { return shr_signed(output); }
1932 #endif
1933             bool operator>>(char& output)                       { return shr_xchar(output); }
1934             bool operator>>(unsigned char& output)              { return shr_xchar(output); }
1935             bool operator>>(signed char& output)                { return shr_xchar(output); }
1936 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
1937             bool operator>>(wchar_t& output)                    { return shr_xchar(output); }
1938 #endif
1939 #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
1940             bool operator>>(char16_t& output)                   { return shr_xchar(output); }
1941 #endif
1942 #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
1943             bool operator>>(char32_t& output)                   { return shr_xchar(output); }
1944 #endif
1945             template<class Alloc>
1946             bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
1947
1948             template<class Alloc>
1949             bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
1950
1951             
1952     private:
1953             template <std::size_t N, class ArrayT>
1954             bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT
1955             {
1956                 using namespace std;
1957                 const std::size_t size = finish - start;
1958                 if (size > N - 1) { // `-1` because we need to store \0 at the end 
1959                     return false;
1960                 }
1961
1962                 memcpy(&output[0], start, size * sizeof(CharT));
1963                 output[size] = Traits::to_char_type(0);
1964                 return true;
1965             }
1966
1967     public:
1968
1969             template <std::size_t N>
1970             bool operator>>(boost::array<CharT, N>& output) BOOST_NOEXCEPT
1971             { 
1972                 return shr_std_array<N>(output); 
1973             }
1974
1975             template <std::size_t N>
1976             bool operator>>(boost::array<unsigned char, N>& output)   
1977             { 
1978                 return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output)); 
1979             }
1980
1981             template <std::size_t N>
1982             bool operator>>(boost::array<signed char, N>& output)   
1983             { 
1984                 return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output)); 
1985             }
1986  
1987 #ifndef BOOST_NO_CXX11_HDR_ARRAY
1988             template <std::size_t N>
1989             bool operator>>(std::array<CharT, N>& output) BOOST_NOEXCEPT
1990             { 
1991                 return shr_std_array<N>(output); 
1992             }
1993
1994             template <std::size_t N>
1995             bool operator>>(std::array<unsigned char, N>& output)   
1996             { 
1997                 return ((*this) >> reinterpret_cast<std::array<char, N>& >(output)); 
1998             }
1999
2000             template <std::size_t N>
2001             bool operator>>(std::array<signed char, N>& output)
2002             { 
2003                 return ((*this) >> reinterpret_cast<std::array<char, N>& >(output)); 
2004             }
2005 #endif
2006
2007
2008             /*
2009              * case "-0" || "0" || "+0" :   output = false; return true;
2010              * case "1" || "+1":            output = true;  return true;
2011              * default:                     return false;
2012              */
2013             bool operator>>(bool& output) BOOST_NOEXCEPT
2014             {
2015                 CharT const zero = lcast_char_constants<CharT>::zero;
2016                 CharT const plus = lcast_char_constants<CharT>::plus;
2017                 CharT const minus = lcast_char_constants<CharT>::minus;
2018
2019                 switch(finish-start)
2020                 {
2021                     case 1:
2022                         output = Traits::eq(start[0],  zero+1);
2023                         return output || Traits::eq(start[0], zero );
2024                     case 2:
2025                         if ( Traits::eq( plus, *start) )
2026                         {
2027                             ++start;
2028                             output = Traits::eq(start[0], zero +1);
2029                             return output || Traits::eq(start[0], zero );
2030                         } else
2031                         {
2032                             output = false;
2033                             return Traits::eq( minus, *start)
2034                                 && Traits::eq( zero, start[1]);
2035                         }
2036                     default:
2037                         output = false; // Suppress warning about uninitalized variable
2038                         return false;
2039                 }
2040             }
2041
2042             bool operator>>(float& output) { return lcast_ret_float<Traits>(output,start,finish); }
2043
2044         private:
2045             // Not optimised converter
2046             template <class T>
2047             bool float_types_converter_internal(T& output, int /*tag*/) {
2048                 if (parse_inf_nan(start, finish, output)) return true;
2049                 bool return_value = shr_using_base_class(output);
2050
2051                 /* Some compilers and libraries successfully
2052                  * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
2053                  * We are trying to provide a unified behaviour,
2054                  * so we just forbid such conversions (as some
2055                  * of the most popular compilers/libraries do)
2056                  * */
2057                 CharT const minus = lcast_char_constants<CharT>::minus;
2058                 CharT const plus = lcast_char_constants<CharT>::plus;
2059                 CharT const capital_e = lcast_char_constants<CharT>::capital_e;
2060                 CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
2061                 if ( return_value &&
2062                      (
2063                         Traits::eq(*(finish-1), lowercase_e)                   // 1.0e
2064                         || Traits::eq(*(finish-1), capital_e)                  // 1.0E
2065                         || Traits::eq(*(finish-1), minus)                      // 1.0e- or 1.0E-
2066                         || Traits::eq(*(finish-1), plus)                       // 1.0e+ or 1.0E+
2067                      )
2068                 ) return false;
2069
2070                 return return_value;
2071             }
2072
2073             // Optimised converter
2074             bool float_types_converter_internal(double& output,char /*tag*/) {
2075                 return lcast_ret_float<Traits>(output,start,finish);
2076             }
2077         public:
2078
2079             bool operator>>(double& output)
2080             {
2081                 /*
2082                  * Some compilers implement long double as double. In that case these types have
2083                  * same size, same precision, same max and min values... And it means,
2084                  * that current implementation of lcast_ret_float cannot be used for type
2085                  * double, because it will give a big precision loss.
2086                  * */
2087                 boost::mpl::if_c<
2088 #if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
2089                     boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
2090 #else
2091                      0
2092 #endif
2093                     int,
2094                     char
2095                 >::type tag = 0;
2096
2097                 return float_types_converter_internal(output, tag);
2098             }
2099
2100             bool operator>>(long double& output)
2101             {
2102                 int tag = 0;
2103                 return float_types_converter_internal(output, tag);
2104             }
2105
2106             // Generic istream-based algorithm.
2107             // lcast_streambuf_for_target<InputStreamable>::value is true.
2108             template<typename InputStreamable>
2109             bool operator>>(InputStreamable& output) { return shr_using_base_class(output); }
2110         };
2111     }
2112
2113     namespace detail
2114     {
2115         template<typename T>
2116         struct is_stdstring
2117         {
2118             BOOST_STATIC_CONSTANT(bool, value = false );
2119         };
2120
2121         template<typename CharT, typename Traits, typename Alloc>
2122         struct is_stdstring< std::basic_string<CharT, Traits, Alloc> >
2123         {
2124             BOOST_STATIC_CONSTANT(bool, value = true );
2125         };
2126
2127         template<typename CharT, typename Traits, typename Alloc>
2128         struct is_stdstring< boost::container::basic_string<CharT, Traits, Alloc> >
2129         {
2130             BOOST_STATIC_CONSTANT(bool, value = true );
2131         };
2132
2133         template<typename Target, typename Source>
2134         struct is_arithmetic_and_not_xchars
2135         {
2136             BOOST_STATIC_CONSTANT(bool, value =
2137                (
2138                    boost::type_traits::ice_and<
2139                            boost::is_arithmetic<Source>::value,
2140                            boost::is_arithmetic<Target>::value,
2141                            boost::type_traits::ice_not<
2142                                 detail::is_char_or_wchar<Target>::value
2143                            >::value,
2144                            boost::type_traits::ice_not<
2145                                 detail::is_char_or_wchar<Source>::value
2146                            >::value
2147                    >::value
2148                )
2149             );
2150         };
2151
2152         /*
2153          * is_xchar_to_xchar<Target, Source>::value is true, when
2154          * Target and Souce are the same char types, or when
2155          * Target and Souce are char types of the same size.
2156          */
2157         template<typename Target, typename Source>
2158         struct is_xchar_to_xchar
2159         {
2160             BOOST_STATIC_CONSTANT(bool, value =
2161                 (
2162                     boost::type_traits::ice_or<
2163                         boost::type_traits::ice_and<
2164                              is_same<Source,Target>::value,
2165                              is_char_or_wchar<Target>::value
2166                         >::value,
2167                         boost::type_traits::ice_and<
2168                              boost::type_traits::ice_eq< sizeof(char),sizeof(Target)>::value,
2169                              boost::type_traits::ice_eq< sizeof(char),sizeof(Source)>::value,
2170                              is_char_or_wchar<Target>::value,
2171                              is_char_or_wchar<Source>::value
2172                         >::value
2173                     >::value
2174                 )
2175             );
2176         };
2177
2178         template<typename Target, typename Source>
2179         struct is_char_array_to_stdstring
2180         {
2181             BOOST_STATIC_CONSTANT(bool, value = false );
2182         };
2183
2184         template<typename CharT, typename Traits, typename Alloc>
2185         struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, CharT* >
2186         {
2187             BOOST_STATIC_CONSTANT(bool, value = true );
2188         };
2189
2190         template<typename CharT, typename Traits, typename Alloc>
2191         struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, const CharT* >
2192         {
2193             BOOST_STATIC_CONSTANT(bool, value = true );
2194         };
2195
2196         template<typename CharT, typename Traits, typename Alloc>
2197         struct is_char_array_to_stdstring< boost::container::basic_string<CharT, Traits, Alloc>, CharT* >
2198         {
2199             BOOST_STATIC_CONSTANT(bool, value = true );
2200         };
2201
2202         template<typename CharT, typename Traits, typename Alloc>
2203         struct is_char_array_to_stdstring< boost::container::basic_string<CharT, Traits, Alloc>, const CharT* >
2204         {
2205             BOOST_STATIC_CONSTANT(bool, value = true );
2206         };
2207
2208 #if (defined _MSC_VER)
2209 # pragma warning( push )
2210 # pragma warning( disable : 4701 ) // possible use of ... before initialization
2211 # pragma warning( disable : 4702 ) // unreachable code
2212 # pragma warning( disable : 4267 ) // conversion from 'size_t' to 'unsigned int'
2213 #endif
2214         template<typename Target, typename Source>
2215         struct lexical_cast_do_cast
2216         {
2217             static inline Target lexical_cast_impl(const Source& arg)
2218             {
2219                 typedef lexical_cast_stream_traits<Source, Target>  stream_trait;
2220                 
2221                 typedef detail::lexical_stream_limited_src<
2222                     BOOST_DEDUCED_TYPENAME stream_trait::char_type, 
2223                     BOOST_DEDUCED_TYPENAME stream_trait::traits, 
2224                     stream_trait::requires_stringbuf 
2225                 > interpreter_type;
2226
2227                 // Target type must be default constructible
2228                 Target result;               
2229
2230                 BOOST_DEDUCED_TYPENAME stream_trait::char_type buf[stream_trait::len_t::value + 1];
2231                 stream_trait::len_t::check_coverage();
2232
2233                 interpreter_type interpreter(buf, buf + stream_trait::len_t::value + 1);
2234
2235                 // Disabling ADL, by directly specifying operators.
2236                 if(!(interpreter.operator <<(arg) && interpreter.operator >>(result)))
2237                   BOOST_LCAST_THROW_BAD_CAST(Source, Target);
2238
2239                 return result;
2240             }
2241         };
2242 #if (defined _MSC_VER)
2243 # pragma warning( pop )
2244 #endif
2245
2246         template <typename Source>
2247         struct lexical_cast_copy
2248         {
2249             static inline const Source& lexical_cast_impl(const Source &arg) BOOST_NOEXCEPT
2250             {
2251                 return arg;
2252             }
2253         };
2254
2255         template <class Source, class Target >
2256         struct detect_precision_loss
2257         {
2258          typedef boost::numeric::Trunc<Source> Rounder;
2259          typedef Source source_type ;
2260
2261          typedef BOOST_DEDUCED_TYPENAME mpl::if_<
2262             boost::is_arithmetic<Source>, Source, Source const&
2263           >::type argument_type ;
2264
2265          static source_type nearbyint ( argument_type s )
2266          {
2267             const source_type near_int = Rounder::nearbyint(s);
2268             if (near_int) {
2269                 const source_type orig_div_round = s / near_int;
2270                 const source_type eps = std::numeric_limits<source_type>::epsilon();
2271
2272                 if ((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps)
2273                     BOOST_LCAST_THROW_BAD_CAST(Source, Target);
2274             }
2275
2276             return s ;
2277          }
2278
2279          typedef typename Rounder::round_style round_style;
2280         } ;
2281
2282         template <class Source, class Target >
2283         struct nothrow_overflow_handler
2284         {
2285           void operator() ( boost::numeric::range_check_result r )
2286           {
2287             if (r != boost::numeric::cInRange)
2288                 BOOST_LCAST_THROW_BAD_CAST(Source, Target);
2289           }
2290         } ;
2291
2292         template <typename Target, typename Source>
2293         struct lexical_cast_dynamic_num_not_ignoring_minus
2294         {
2295             static inline Target lexical_cast_impl(const Source &arg)
2296             {
2297                 return boost::numeric::converter<
2298                         Target,
2299                         Source,
2300                         boost::numeric::conversion_traits<Target,Source>,
2301                         nothrow_overflow_handler<Source, Target>,
2302                         detect_precision_loss<Source, Target>
2303                 >::convert(arg);
2304             }
2305         };
2306
2307         template <typename Target, typename Source>
2308         struct lexical_cast_dynamic_num_ignoring_minus
2309         {
2310             static inline Target lexical_cast_impl(const Source &arg)
2311             {
2312                 typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if_c<
2313                         boost::is_float<Source>::value,
2314                         boost::mpl::identity<Source>,
2315                         boost::make_unsigned<Source>
2316                 >::type usource_t;
2317
2318                 typedef boost::numeric::converter<
2319                         Target,
2320                         usource_t,
2321                         boost::numeric::conversion_traits<Target,usource_t>,
2322                         nothrow_overflow_handler<usource_t, Target>,
2323                         detect_precision_loss<usource_t, Target>
2324                 > converter_t;
2325
2326                 return (
2327                     arg < 0 ? 0u - converter_t::convert(0u - arg) : converter_t::convert(arg)
2328                 );
2329             }
2330         };
2331
2332         /*
2333          * lexical_cast_dynamic_num follows the rules:
2334          * 1) If Source can be converted to Target without precision loss and
2335          * without overflows, then assign Source to Target and return
2336          *
2337          * 2) If Source is less than 0 and Target is an unsigned integer,
2338          * then negate Source, check the requirements of rule 1) and if
2339          * successful, assign static_casted Source to Target and return
2340          *
2341          * 3) Otherwise throw a bad_lexical_cast exception
2342          *
2343          *
2344          * Rule 2) required because boost::lexical_cast has the behavior of
2345          * stringstream, which uses the rules of scanf for conversions. And
2346          * in the C99 standard for unsigned input value minus sign is
2347          * optional, so if a negative number is read, no errors will arise
2348          * and the result will be the two's complement.
2349          */
2350         template <typename Target, typename Source>
2351         struct lexical_cast_dynamic_num
2352         {
2353             static inline Target lexical_cast_impl(const Source &arg)
2354             {
2355                 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
2356                     boost::type_traits::ice_and<
2357                         boost::type_traits::ice_or<
2358                             boost::is_signed<Source>::value,
2359                             boost::is_float<Source>::value
2360                         >::value,
2361                         boost::type_traits::ice_not<
2362                             boost::is_same<Source, bool>::value
2363                         >::value,
2364                         boost::type_traits::ice_not<
2365                             boost::is_same<Target, bool>::value
2366                         >::value,
2367                         boost::is_unsigned<Target>::value
2368                     >::value,
2369                     lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
2370                     lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
2371                 >::type caster_type;
2372
2373                 return caster_type::lexical_cast_impl(arg);
2374             }
2375         };
2376     }
2377
2378     template <typename Target, typename Source>
2379     inline Target lexical_cast(const Source &arg)
2380     {
2381         typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
2382
2383         typedef BOOST_DEDUCED_TYPENAME boost::type_traits::ice_or<
2384                 boost::detail::is_xchar_to_xchar<Target, src >::value,
2385                 boost::detail::is_char_array_to_stdstring<Target, src >::value,
2386                 boost::type_traits::ice_and<
2387                      boost::is_same<Target, src >::value,
2388                      boost::detail::is_stdstring<Target >::value
2389                 >::value
2390         > shall_we_copy_t;
2391
2392         typedef BOOST_DEDUCED_TYPENAME
2393                 boost::detail::is_arithmetic_and_not_xchars<Target, src > shall_we_copy_with_dynamic_check_t;
2394
2395         typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
2396             shall_we_copy_t::value,
2397             boost::detail::lexical_cast_copy<src >,
2398             BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
2399                  shall_we_copy_with_dynamic_check_t::value,
2400                  boost::detail::lexical_cast_dynamic_num<Target, src >,
2401                  boost::detail::lexical_cast_do_cast<Target, src >
2402             >::type
2403         >::type caster_type;
2404
2405         return caster_type::lexical_cast_impl(arg);
2406     }
2407
2408     template <typename Target, typename CharType>
2409     inline Target lexical_cast(const CharType* chars, std::size_t count)
2410     {
2411         BOOST_STATIC_ASSERT_MSG(boost::detail::is_char_or_wchar<CharType>::value, 
2412             "CharType must be a character or wide character type");
2413
2414         return boost::lexical_cast<Target>(
2415             boost::iterator_range<const CharType*>(chars, chars + count)
2416         );
2417     }
2418
2419 } // namespace boost
2420
2421 #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
2422
2423 namespace boost {
2424     namespace detail
2425     {
2426
2427         // selectors for choosing stream character type
2428         template<typename Type>
2429         struct stream_char
2430         {
2431             typedef char type;
2432         };
2433
2434 #ifndef BOOST_LCAST_NO_WCHAR_T
2435 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
2436         template<>
2437         struct stream_char<wchar_t>
2438         {
2439             typedef wchar_t type;
2440         };
2441 #endif
2442
2443         template<>
2444         struct stream_char<wchar_t *>
2445         {
2446             typedef wchar_t type;
2447         };
2448
2449         template<>
2450         struct stream_char<const wchar_t *>
2451         {
2452             typedef wchar_t type;
2453         };
2454
2455         template<>
2456         struct stream_char<std::wstring>
2457         {
2458             typedef wchar_t type;
2459         };
2460 #endif
2461
2462         // stream wrapper for handling lexical conversions
2463         template<typename Target, typename Source, typename Traits>
2464         class lexical_stream
2465         {
2466         private:
2467             typedef typename widest_char<
2468                 typename stream_char<Target>::type,
2469                 typename stream_char<Source>::type>::type char_type;
2470
2471             typedef Traits traits_type;
2472
2473         public:
2474             lexical_stream(char_type* = 0, char_type* = 0)
2475             {
2476                 stream.unsetf(std::ios::skipws);
2477                 lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
2478             }
2479             ~lexical_stream()
2480             {
2481                 #if defined(BOOST_NO_STRINGSTREAM)
2482                 stream.freeze(false);
2483                 #endif
2484             }
2485             bool operator<<(const Source &input)
2486             {
2487                 return !(stream << input).fail();
2488             }
2489             template<typename InputStreamable>
2490             bool operator>>(InputStreamable &output)
2491             {
2492                 return !is_pointer<InputStreamable>::value &&
2493                        stream >> output &&
2494                        stream.get() ==
2495 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
2496 // GCC 2.9x lacks std::char_traits<>::eof().
2497 // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
2498 // configurations, which do provide std::char_traits<>::eof().
2499
2500                            EOF;
2501 #else
2502                            traits_type::eof();
2503 #endif
2504             }
2505
2506             bool operator>>(std::string &output)
2507             {
2508                 #if defined(BOOST_NO_STRINGSTREAM)
2509                 stream << '\0';
2510                 #endif
2511                 stream.str().swap(output);
2512                 return true;
2513             }
2514             #ifndef BOOST_LCAST_NO_WCHAR_T
2515             bool operator>>(std::wstring &output)
2516             {
2517                 stream.str().swap(output);
2518                 return true;
2519             }
2520             #endif
2521
2522         private:
2523             #if defined(BOOST_NO_STRINGSTREAM)
2524             std::strstream stream;
2525             #elif defined(BOOST_NO_STD_LOCALE)
2526             std::stringstream stream;
2527             #else
2528             std::basic_stringstream<char_type,traits_type> stream;
2529             #endif
2530         };
2531     }
2532
2533     // call-by-value fallback version (deprecated)
2534
2535     template<typename Target, typename Source>
2536     Target lexical_cast(Source arg)
2537     {
2538         typedef typename detail::widest_char< 
2539             BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type 
2540           , BOOST_DEDUCED_TYPENAME detail::stream_char<Source>::type 
2541         >::type char_type; 
2542
2543         typedef std::char_traits<char_type> traits;
2544         detail::lexical_stream<Target, Source, traits> interpreter;
2545         Target result;
2546
2547         if(!(interpreter << arg && interpreter >> result))
2548           BOOST_LCAST_THROW_BAD_CAST(Source, Target);
2549         return result;
2550     }
2551
2552 } // namespace boost
2553
2554 #endif
2555
2556 // Copyright Kevlin Henney, 2000-2005.
2557 // Copyright Alexander Nasonov, 2006-2010.
2558 // Copyright Antony Polukhin, 2011-2012.
2559 //
2560 // Distributed under the Boost Software License, Version 1.0. (See
2561 // accompanying file LICENSE_1_0.txt or copy at
2562 // http://www.boost.org/LICENSE_1_0.txt)
2563
2564 #undef BOOST_LCAST_THROW_BAD_CAST
2565 #undef BOOST_LCAST_NO_WCHAR_T
2566
2567 #endif // BOOST_LEXICAL_CAST_INCLUDED
2568