]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/lexical_cast.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
bf41894499f91a5d987a716d77435529fa925a6f
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / lexical_cast.hpp
1 #ifndef BOOST_LEXICAL_CAST_INCLUDED\r
2 #define BOOST_LEXICAL_CAST_INCLUDED\r
3 \r
4 // Boost lexical_cast.hpp header  -------------------------------------------//\r
5 //\r
6 // See http://www.boost.org/libs/conversion for documentation.\r
7 // See end of this header for rights and permissions.\r
8 //\r
9 // what:  lexical_cast custom keyword cast\r
10 // who:   contributed by Kevlin Henney,\r
11 //        enhanced with contributions from Terje Slettebo,\r
12 //        with additional fixes and suggestions from Gennaro Prota,\r
13 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,\r
14 //        Alexander Nasonov and other Boosters\r
15 // when:  November 2000, March 2003, June 2005, June 2006\r
16 \r
17 #include <climits>\r
18 #include <cstddef>\r
19 #include <istream>\r
20 #include <string>\r
21 #include <typeinfo>\r
22 #include <exception>\r
23 #include <boost/config.hpp>\r
24 #include <boost/limits.hpp>\r
25 #include <boost/mpl/if.hpp>\r
26 #include <boost/throw_exception.hpp>\r
27 #include <boost/type_traits/is_pointer.hpp>\r
28 #include <boost/type_traits/make_unsigned.hpp>\r
29 #include <boost/call_traits.hpp>\r
30 #include <boost/static_assert.hpp>\r
31 #include <boost/detail/lcast_precision.hpp>\r
32 #include <boost/detail/workaround.hpp>\r
33 \r
34 #ifndef BOOST_NO_STD_LOCALE\r
35 #include <locale>\r
36 #endif\r
37 \r
38 #ifdef BOOST_NO_STRINGSTREAM\r
39 #include <strstream>\r
40 #else\r
41 #include <sstream>\r
42 #endif\r
43 \r
44 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)\r
45 #define BOOST_LCAST_NO_WCHAR_T\r
46 #endif\r
47 \r
48 #ifdef BOOST_NO_TYPEID\r
49 #define BOOST_LCAST_THROW_BAD_CAST(S, T) throw_exception(bad_lexical_cast())\r
50 #else\r
51 #define BOOST_LCAST_THROW_BAD_CAST(Source, Target) \\r
52     throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)))\r
53 #endif\r
54 \r
55 namespace boost\r
56 {\r
57     // exception used to indicate runtime lexical_cast failure\r
58     class bad_lexical_cast : public std::bad_cast\r
59 \r
60 #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )\r
61         // under bcc32 5.5.1 bad_cast doesn't derive from exception\r
62         , public std::exception\r
63 #endif\r
64 \r
65     {\r
66     public:\r
67         bad_lexical_cast() :\r
68 #ifndef BOOST_NO_TYPEID\r
69           source(&typeid(void)), target(&typeid(void))\r
70 #else\r
71           source(0), target(0) // this breaks getters\r
72 #endif\r
73         {\r
74         }\r
75 \r
76         bad_lexical_cast(\r
77             const std::type_info &source_type_arg,\r
78             const std::type_info &target_type_arg) :\r
79             source(&source_type_arg), target(&target_type_arg)\r
80         {\r
81         }\r
82 \r
83         const std::type_info &source_type() const\r
84         {\r
85             return *source;\r
86         }\r
87         const std::type_info &target_type() const\r
88         {\r
89             return *target;\r
90         }\r
91 \r
92         virtual const char *what() const throw()\r
93         {\r
94             return "bad lexical cast: "\r
95                    "source type value could not be interpreted as target";\r
96         }\r
97         virtual ~bad_lexical_cast() throw()\r
98         {\r
99         }\r
100     private:\r
101         const std::type_info *source;\r
102         const std::type_info *target;\r
103     };\r
104 \r
105     namespace detail // selectors for choosing stream character type\r
106     {\r
107         template<typename Type>\r
108         struct stream_char\r
109         {\r
110             typedef char type;\r
111         };\r
112 \r
113 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
114         template<class CharT, class Traits, class Alloc>\r
115         struct stream_char< std::basic_string<CharT,Traits,Alloc> >\r
116         {\r
117             typedef CharT type;\r
118         };\r
119 #endif\r
120 \r
121 #ifndef BOOST_LCAST_NO_WCHAR_T\r
122 #ifndef BOOST_NO_INTRINSIC_WCHAR_T\r
123         template<>\r
124         struct stream_char<wchar_t>\r
125         {\r
126             typedef wchar_t type;\r
127         };\r
128 #endif\r
129 \r
130         template<>\r
131         struct stream_char<wchar_t *>\r
132         {\r
133             typedef wchar_t type;\r
134         };\r
135 \r
136         template<>\r
137         struct stream_char<const wchar_t *>\r
138         {\r
139             typedef wchar_t type;\r
140         };\r
141 \r
142 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
143         template<>\r
144         struct stream_char<std::wstring>\r
145         {\r
146             typedef wchar_t type;\r
147         };\r
148 #endif\r
149 #endif\r
150 \r
151         template<typename TargetChar, typename SourceChar>\r
152         struct widest_char\r
153         {\r
154             typedef TargetChar type;\r
155         };\r
156 \r
157         template<>\r
158         struct widest_char<char, wchar_t>\r
159         {\r
160             typedef wchar_t type;\r
161         };\r
162     }\r
163 \r
164     namespace detail // deduce_char_traits template\r
165     {\r
166 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
167         template<class CharT, class Target, class Source>\r
168         struct deduce_char_traits\r
169         {\r
170             typedef std::char_traits<CharT> type;\r
171         };\r
172 \r
173         template<class CharT, class Traits, class Alloc, class Source>\r
174         struct deduce_char_traits< CharT\r
175                                  , std::basic_string<CharT,Traits,Alloc>\r
176                                  , Source\r
177                                  >\r
178         {\r
179             typedef Traits type;\r
180         };\r
181 \r
182         template<class CharT, class Target, class Traits, class Alloc>\r
183         struct deduce_char_traits< CharT\r
184                                  , Target\r
185                                  , std::basic_string<CharT,Traits,Alloc>\r
186                                  >\r
187         {\r
188             typedef Traits type;\r
189         };\r
190 \r
191         template<class CharT, class Traits, class Alloc1, class Alloc2>\r
192         struct deduce_char_traits< CharT\r
193                                  , std::basic_string<CharT,Traits,Alloc1>\r
194                                  , std::basic_string<CharT,Traits,Alloc2>\r
195                                  >\r
196         {\r
197             typedef Traits type;\r
198         };\r
199 #endif\r
200     }\r
201 \r
202     namespace detail // lcast_src_length\r
203     {\r
204         // Return max. length of string representation of Source;\r
205         // 0 if unlimited (with exceptions for some types, see below).\r
206         // Values with limited string representation are placed to\r
207         // the buffer locally defined in lexical_cast function.\r
208         // 1 is returned for few types such as CharT const* or\r
209         // std::basic_string<CharT> that already have an internal\r
210         // buffer ready to be reused by lexical_stream_limited_src.\r
211         // Each specialization should have a correspondent operator<<\r
212         // defined in lexical_stream_limited_src.\r
213         template< class CharT  // A result of widest_char transformation.\r
214                 , class Source // Source type of lexical_cast.\r
215                 >\r
216         struct lcast_src_length\r
217         {\r
218             BOOST_STATIC_CONSTANT(std::size_t, value = 0);\r
219             // To check coverage, build the test with\r
220             // bjam --v2 profile optimization=off\r
221             static void check_coverage() {}\r
222         };\r
223 \r
224         template<>\r
225         struct lcast_src_length<char, bool>\r
226         {\r
227             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
228             static void check_coverage() {}\r
229         };\r
230 \r
231         template<>\r
232         struct lcast_src_length<char, char>\r
233         {\r
234             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
235             static void check_coverage() {}\r
236         };\r
237 \r
238         // No specializations for:\r
239         // lcast_src_length<char, signed char>\r
240         // lcast_src_length<char, unsigned char>\r
241         // lcast_src_length<char, signed char*>\r
242         // lcast_src_length<char, unsigned char*>\r
243         // lcast_src_length<char, signed char const*>\r
244         // lcast_src_length<char, unsigned char const*>\r
245 \r
246 #ifndef BOOST_LCAST_NO_WCHAR_T\r
247         template<>\r
248         struct lcast_src_length<wchar_t, bool>\r
249         {\r
250             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
251             static void check_coverage() {}\r
252         };\r
253 \r
254         template<>\r
255         struct lcast_src_length<wchar_t, char>\r
256         {\r
257             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
258             static void check_coverage() {}\r
259         };\r
260 \r
261 #ifndef BOOST_NO_INTRINSIC_WCHAR_T\r
262         template<>\r
263         struct lcast_src_length<wchar_t, wchar_t>\r
264         {\r
265             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
266             static void check_coverage() {}\r
267         };\r
268 #endif\r
269 #endif\r
270 \r
271         template<>\r
272         struct lcast_src_length<char, char const*>\r
273         {\r
274             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
275             static void check_coverage() {}\r
276         };\r
277 \r
278         template<>\r
279         struct lcast_src_length<char, char*>\r
280         {\r
281             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
282             static void check_coverage() {}\r
283         };\r
284 \r
285 #ifndef BOOST_LCAST_NO_WCHAR_T\r
286         template<>\r
287         struct lcast_src_length<wchar_t, wchar_t const*>\r
288         {\r
289             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
290             static void check_coverage() {}\r
291         };\r
292 \r
293         template<>\r
294         struct lcast_src_length<wchar_t, wchar_t*>\r
295         {\r
296             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
297             static void check_coverage() {}\r
298         };\r
299 #endif\r
300 \r
301 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
302         template<class CharT, class Traits, class Alloc>\r
303         struct lcast_src_length< CharT, std::basic_string<CharT,Traits,Alloc> >\r
304         {\r
305             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
306             static void check_coverage() {}\r
307         };\r
308 #else\r
309         template<>\r
310         struct lcast_src_length< char, std::basic_string<char> >\r
311         {\r
312             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
313             static void check_coverage() {}\r
314         };\r
315 \r
316 #ifndef BOOST_LCAST_NO_WCHAR_T\r
317         template<>\r
318         struct lcast_src_length< wchar_t, std::basic_string<wchar_t> >\r
319         {\r
320             BOOST_STATIC_CONSTANT(std::size_t, value = 1);\r
321             static void check_coverage() {}\r
322         };\r
323 #endif\r
324 #endif\r
325 \r
326         // Helper for integral types.\r
327         // Notes on length calculation:\r
328         // Max length for 32bit int with grouping "\1" and thousands_sep ',':\r
329         // "-2,1,4,7,4,8,3,6,4,7"\r
330         //  ^                    - is_signed\r
331         //   ^                   - 1 digit not counted by digits10\r
332         //    ^^^^^^^^^^^^^^^^^^ - digits10 * 2\r
333         //\r
334         // Constant is_specialized is used instead of constant 1\r
335         // to prevent buffer overflow in a rare case when\r
336         // <boost/limits.hpp> doesn't add missing specialization for\r
337         // numeric_limits<T> for some integral type T.\r
338         // When is_specialized is false, the whole expression is 0.\r
339         template<class Source>\r
340         struct lcast_src_length_integral\r
341         {\r
342 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS\r
343             BOOST_STATIC_CONSTANT(std::size_t, value =\r
344                   std::numeric_limits<Source>::is_signed +\r
345                   std::numeric_limits<Source>::is_specialized + // == 1\r
346                   std::numeric_limits<Source>::digits10 * 2\r
347               );\r
348 #else\r
349             BOOST_STATIC_CONSTANT(std::size_t, value = 156);\r
350             BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);\r
351 #endif\r
352         };\r
353 \r
354 #define BOOST_LCAST_DEF1(CharT, T)               \\r
355     template<> struct lcast_src_length<CharT, T> \\r
356         : lcast_src_length_integral<T>           \\r
357     { static void check_coverage() {} };\r
358 \r
359 #ifdef BOOST_LCAST_NO_WCHAR_T\r
360 #define BOOST_LCAST_DEF(T) BOOST_LCAST_DEF1(char, T)\r
361 #else\r
362 #define BOOST_LCAST_DEF(T)          \\r
363         BOOST_LCAST_DEF1(char, T)   \\r
364         BOOST_LCAST_DEF1(wchar_t, T)\r
365 #endif\r
366 \r
367         BOOST_LCAST_DEF(short)\r
368         BOOST_LCAST_DEF(unsigned short)\r
369         BOOST_LCAST_DEF(int)\r
370         BOOST_LCAST_DEF(unsigned int)\r
371         BOOST_LCAST_DEF(long)\r
372         BOOST_LCAST_DEF(unsigned long)\r
373 #if defined(BOOST_HAS_LONG_LONG)\r
374         BOOST_LCAST_DEF(boost::ulong_long_type)\r
375         BOOST_LCAST_DEF(boost::long_long_type )\r
376 #elif defined(BOOST_HAS_MS_INT64)\r
377         BOOST_LCAST_DEF(unsigned __int64)\r
378         BOOST_LCAST_DEF(         __int64)\r
379 #endif\r
380 \r
381 #undef BOOST_LCAST_DEF\r
382 #undef BOOST_LCAST_DEF1\r
383 \r
384 #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION\r
385         // Helper for floating point types.\r
386         // -1.23456789e-123456\r
387         // ^                   sign\r
388         //  ^                  leading digit\r
389         //   ^                 decimal point \r
390         //    ^^^^^^^^         lcast_precision<Source>::value\r
391         //            ^        "e"\r
392         //             ^       exponent sign\r
393         //              ^^^^^^ exponent (assumed 6 or less digits)\r
394         // sign + leading digit + decimal point + "e" + exponent sign == 5\r
395         template<class Source>\r
396         struct lcast_src_length_floating\r
397         {\r
398             BOOST_STATIC_ASSERT(\r
399                     std::numeric_limits<Source>::max_exponent10 <=  999999L &&\r
400                     std::numeric_limits<Source>::min_exponent10 >= -999999L\r
401                 );\r
402             BOOST_STATIC_CONSTANT(std::size_t, value =\r
403                     5 + lcast_precision<Source>::value + 6\r
404                 );\r
405         };\r
406 \r
407         template<>\r
408         struct lcast_src_length<char,float>\r
409           : lcast_src_length_floating<float>\r
410         {\r
411             static void check_coverage() {}\r
412         };\r
413 \r
414         template<>\r
415         struct lcast_src_length<char,double>\r
416           : lcast_src_length_floating<double>\r
417         {\r
418             static void check_coverage() {}\r
419         };\r
420 \r
421         template<>\r
422         struct lcast_src_length<char,long double>\r
423           : lcast_src_length_floating<long double>\r
424         {\r
425             static void check_coverage() {}\r
426         };\r
427 \r
428 #ifndef BOOST_LCAST_NO_WCHAR_T\r
429     template<>\r
430     struct lcast_src_length<wchar_t,float>\r
431       : lcast_src_length_floating<float>\r
432     {\r
433         static void check_coverage() {}\r
434     };\r
435 \r
436     template<>\r
437     struct lcast_src_length<wchar_t,double>\r
438       : lcast_src_length_floating<double>\r
439     {\r
440         static void check_coverage() {}\r
441     };\r
442 \r
443     template<>\r
444     struct lcast_src_length<wchar_t,long double>\r
445       : lcast_src_length_floating<long double>\r
446     {\r
447         static void check_coverage() {}\r
448     };\r
449 \r
450 #endif // #ifndef BOOST_LCAST_NO_WCHAR_T\r
451 #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION\r
452     }\r
453 \r
454     namespace detail // '0' and '-' constants\r
455     {\r
456         template<typename CharT> struct lcast_char_constants;\r
457 \r
458         template<>\r
459         struct lcast_char_constants<char>\r
460         {\r
461             BOOST_STATIC_CONSTANT(char, zero  = '0');\r
462             BOOST_STATIC_CONSTANT(char, minus = '-');\r
463         };\r
464 \r
465 #ifndef BOOST_LCAST_NO_WCHAR_T\r
466         template<>\r
467         struct lcast_char_constants<wchar_t>\r
468         {\r
469             BOOST_STATIC_CONSTANT(wchar_t, zero  = L'0');\r
470             BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');\r
471         };\r
472 #endif\r
473     }\r
474 \r
475     namespace detail // lexical_streambuf_fake\r
476     {\r
477         struct lexical_streambuf_fake\r
478         {\r
479         };\r
480     }\r
481 \r
482     namespace detail // lcast_to_unsigned\r
483     {\r
484 #if (defined _MSC_VER)\r
485 # pragma warning( push )\r
486 // C4146: unary minus operator applied to unsigned type, result still unsigned\r
487 # pragma warning( disable : 4146 )\r
488 #elif defined( __BORLANDC__ )\r
489 # pragma option push -w-8041\r
490 #endif\r
491         template<class T>\r
492         inline\r
493         BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value)\r
494         {\r
495             typedef BOOST_DEDUCED_TYPENAME make_unsigned<T>::type result_type;\r
496             result_type uvalue = static_cast<result_type>(value);\r
497             return value < 0 ? -uvalue : uvalue;\r
498         }\r
499 #if (defined _MSC_VER)\r
500 # pragma warning( pop )\r
501 #elif defined( __BORLANDC__ )\r
502 # pragma option pop\r
503 #endif\r
504     }\r
505 \r
506     namespace detail // lcast_put_unsigned\r
507     {\r
508         template<class Traits, class T, class CharT>\r
509         CharT* lcast_put_unsigned(T n, CharT* finish)\r
510         {\r
511 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS\r
512             BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);\r
513 #endif\r
514 \r
515 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE\r
516             // TODO: use BOOST_NO_STD_LOCALE\r
517             std::locale loc;\r
518             typedef std::numpunct<CharT> numpunct;\r
519             numpunct const& np = BOOST_USE_FACET(numpunct, loc);\r
520             std::string const& grouping = np.grouping();\r
521             std::string::size_type const grouping_size = grouping.size();\r
522             CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;\r
523             std::string::size_type group = 0; // current group number\r
524             char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];\r
525             // a) Since grouping is const, grouping[grouping.size()] returns 0.\r
526             // b) It's safe to assume here and below that CHAR_MAX\r
527             //    is equivalent to unlimited grouping:\r
528 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS\r
529             BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);\r
530 #endif\r
531 \r
532             char left = last_grp_size;\r
533 #endif\r
534 \r
535             typedef typename Traits::int_type int_type;\r
536             CharT const czero = lcast_char_constants<CharT>::zero;\r
537             int_type const zero = Traits::to_int_type(czero);\r
538 \r
539             do\r
540             {\r
541 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE\r
542                 if(left == 0)\r
543                 {\r
544                     ++group;\r
545                     if(group < grouping_size)\r
546                     {\r
547                         char const grp_size = grouping[group];\r
548                         last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;\r
549                     }\r
550 \r
551                     left = last_grp_size;\r
552                     --finish;\r
553                     Traits::assign(*finish, thousands_sep);\r
554                 }\r
555 \r
556                 --left;\r
557 #endif\r
558 \r
559                 --finish;\r
560                 int_type const digit = static_cast<int_type>(n % 10U);\r
561                 Traits::assign(*finish, Traits::to_char_type(zero + digit));\r
562                 n /= 10;\r
563             } while(n);\r
564 \r
565             return finish;\r
566         }\r
567     }\r
568 \r
569     namespace detail // stream wrapper for handling lexical conversions\r
570     {\r
571         template<typename Target, typename Source, typename Traits>\r
572         class lexical_stream\r
573         {\r
574         private:\r
575             typedef typename widest_char<\r
576                 typename stream_char<Target>::type,\r
577                 typename stream_char<Source>::type>::type char_type;\r
578 \r
579             typedef Traits traits_type;\r
580 \r
581         public:\r
582             lexical_stream(char_type* = 0, char_type* = 0)\r
583             {\r
584                 stream.unsetf(std::ios::skipws);\r
585                 lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );\r
586             }\r
587             ~lexical_stream()\r
588             {\r
589                 #if defined(BOOST_NO_STRINGSTREAM)\r
590                 stream.freeze(false);\r
591                 #endif\r
592             }\r
593             bool operator<<(const Source &input)\r
594             {\r
595                 return !(stream << input).fail();\r
596             }\r
597             template<typename InputStreamable>\r
598             bool operator>>(InputStreamable &output)\r
599             {\r
600                 return !is_pointer<InputStreamable>::value &&\r
601                        stream >> output &&\r
602                        stream.get() ==\r
603 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)\r
604 // GCC 2.9x lacks std::char_traits<>::eof().\r
605 // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3\r
606 // configurations, which do provide std::char_traits<>::eof().\r
607     \r
608                            EOF;\r
609 #else\r
610                            traits_type::eof();\r
611 #endif\r
612             }\r
613 \r
614 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
615 \r
616             bool operator>>(std::string &output)\r
617             {\r
618                 #if defined(BOOST_NO_STRINGSTREAM)\r
619                 stream << '\0';\r
620                 #endif\r
621                 stream.str().swap(output);\r
622                 return true;\r
623             }\r
624             #ifndef BOOST_LCAST_NO_WCHAR_T\r
625             bool operator>>(std::wstring &output)\r
626             {\r
627                 stream.str().swap(output);\r
628                 return true;\r
629             }\r
630             #endif\r
631 \r
632 #else\r
633             bool operator>>(std::basic_string<char_type,traits_type>& output)\r
634             {\r
635                 stream.str().swap(output);\r
636                 return true;\r
637             }\r
638 \r
639             template<class Alloc>\r
640             bool operator>>(std::basic_string<char_type,traits_type,Alloc>& out)\r
641             {\r
642                 std::basic_string<char_type,traits_type> str(stream.str());\r
643                 out.assign(str.begin(), str.end());\r
644                 return true;\r
645             }\r
646 #endif\r
647         private:\r
648             #if defined(BOOST_NO_STRINGSTREAM)\r
649             std::strstream stream;\r
650             #elif defined(BOOST_NO_STD_LOCALE)\r
651             std::stringstream stream;\r
652             #else\r
653             std::basic_stringstream<char_type,traits_type> stream;\r
654             #endif\r
655         };\r
656     }\r
657 \r
658     namespace detail // optimized stream wrapper\r
659     {\r
660         // String representation of Source has an upper limit.\r
661         template< class CharT // a result of widest_char transformation\r
662                 , class Base // lexical_streambuf_fake or basic_streambuf<CharT>\r
663                 , class Traits // usually char_traits<CharT>\r
664                 >\r
665         class lexical_stream_limited_src : public Base\r
666         {\r
667             // A string representation of Source is written to [start, finish).\r
668             // Currently, it is assumed that [start, finish) is big enough\r
669             // to hold a string representation of any Source value.\r
670             CharT* start;\r
671             CharT* finish;\r
672 \r
673         private:\r
674 \r
675             static void widen_and_assign(char*p, char ch)\r
676             {\r
677                 Traits::assign(*p, ch);\r
678             }\r
679 \r
680 #ifndef BOOST_LCAST_NO_WCHAR_T\r
681             static void widen_and_assign(wchar_t* p, char ch)\r
682             {\r
683                 // TODO: use BOOST_NO_STD_LOCALE\r
684                 std::locale loc;\r
685                 wchar_t w = BOOST_USE_FACET(std::ctype<wchar_t>, loc).widen(ch);\r
686                 Traits::assign(*p, w);\r
687             }\r
688 \r
689             static void widen_and_assign(wchar_t* p, wchar_t ch)\r
690             {\r
691                 Traits::assign(*p, ch);\r
692             }\r
693 \r
694             static void widen_and_assign(char*, wchar_t ch); // undefined\r
695 #endif\r
696 \r
697             template<class OutputStreamable>\r
698             bool lcast_put(const OutputStreamable& input)\r
699             {\r
700                 this->setp(start, finish);\r
701                 std::basic_ostream<CharT> stream(static_cast<Base*>(this));\r
702                 lcast_set_precision(stream, static_cast<OutputStreamable*>(0));\r
703                 bool const result = !(stream << input).fail();\r
704                 finish = this->pptr();\r
705                 return result;\r
706             }\r
707 \r
708             // Undefined:\r
709             lexical_stream_limited_src(lexical_stream_limited_src const&);\r
710             void operator=(lexical_stream_limited_src const&);\r
711 \r
712         public:\r
713 \r
714             lexical_stream_limited_src(CharT* sta, CharT* fin)\r
715               : start(sta)\r
716               , finish(fin)\r
717             {}\r
718 \r
719         public: // output\r
720 \r
721             template<class Alloc>\r
722             bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str)\r
723             {\r
724                 start = const_cast<CharT*>(str.data());\r
725                 finish = start + str.length();\r
726                 return true;\r
727             }\r
728 \r
729             bool operator<<(bool);\r
730             bool operator<<(char);\r
731 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\r
732             bool operator<<(wchar_t);\r
733 #endif\r
734             bool operator<<(CharT const*);\r
735             bool operator<<(short);\r
736             bool operator<<(int);\r
737             bool operator<<(long);\r
738             bool operator<<(unsigned short);\r
739             bool operator<<(unsigned int);\r
740             bool operator<<(unsigned long);\r
741 #if defined(BOOST_HAS_LONG_LONG)\r
742             bool operator<<(boost::ulong_long_type);\r
743             bool operator<<(boost::long_long_type );\r
744 #elif defined(BOOST_HAS_MS_INT64)\r
745             bool operator<<(unsigned __int64);\r
746             bool operator<<(         __int64);\r
747 #endif\r
748             // These three operators use ostream and streambuf.\r
749             // lcast_streambuf_for_source<T>::value is true.\r
750             bool operator<<(float);\r
751             bool operator<<(double);\r
752             bool operator<<(long double);\r
753 \r
754         public: // input\r
755 \r
756             // Generic istream-based algorithm.\r
757             // lcast_streambuf_for_target<InputStreamable>::value is true.\r
758             template<typename InputStreamable>\r
759             bool operator>>(InputStreamable& output)\r
760             {\r
761 #if (defined _MSC_VER)\r
762 # pragma warning( push )\r
763   // conditional expression is constant\r
764 # pragma warning( disable : 4127 )\r
765 #endif\r
766                 if(is_pointer<InputStreamable>::value)\r
767                     return false;\r
768 \r
769                 this->setg(start, start, finish);\r
770                 std::basic_istream<CharT> stream(static_cast<Base*>(this));\r
771                 stream.unsetf(std::ios::skipws);\r
772                 lcast_set_precision(stream, static_cast<InputStreamable*>(0));\r
773 #if (defined _MSC_VER)\r
774 # pragma warning( pop )\r
775 #endif\r
776                 return stream >> output &&\r
777                     stream.get() ==\r
778 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)\r
779         // GCC 2.9x lacks std::char_traits<>::eof().\r
780         // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3\r
781         // configurations, which do provide std::char_traits<>::eof().\r
782 \r
783                     EOF;\r
784 #else\r
785                 Traits::eof();\r
786 #endif\r
787             }\r
788 \r
789             bool operator>>(CharT&);\r
790 \r
791 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
792 // This #if is in sync with lcast_streambuf_for_target\r
793 \r
794             bool operator>>(std::string&);\r
795 \r
796 #ifndef BOOST_LCAST_NO_WCHAR_T\r
797             bool operator>>(std::wstring&);\r
798 #endif\r
799 \r
800 #else\r
801             template<class Alloc>\r
802             bool operator>>(std::basic_string<CharT,Traits,Alloc>& str)\r
803             {\r
804                 str.assign(start, finish);\r
805                 return true;\r
806             }\r
807 #endif\r
808         };\r
809 \r
810         template<typename CharT, class Base, class Traits>\r
811         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
812                 bool value)\r
813         {\r
814             typedef typename Traits::int_type int_type;\r
815             CharT const czero = lcast_char_constants<CharT>::zero;\r
816             int_type const zero = Traits::to_int_type(czero);\r
817             Traits::assign(*start, Traits::to_char_type(zero + value));\r
818             finish = start + 1;\r
819             return true;\r
820         }\r
821 \r
822         template<typename CharT, class Base, class Traits>\r
823         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
824                 char ch)\r
825         {\r
826             widen_and_assign(start, ch);\r
827             finish = start + 1;\r
828             return true;\r
829         }\r
830 \r
831 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\r
832         template<typename CharT, class Base, class Traits>\r
833         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
834                 wchar_t ch)\r
835         {\r
836             widen_and_assign(start, ch);\r
837             finish = start + 1;\r
838             return true;\r
839         }\r
840 #endif\r
841 \r
842         template<typename CharT, class Base, class Traits>\r
843         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
844                 short n)\r
845         {\r
846             start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);\r
847             if(n < 0)\r
848             {\r
849                 --start;\r
850                 CharT const minus = lcast_char_constants<CharT>::minus;\r
851                 Traits::assign(*start, minus);\r
852             }\r
853             return true;\r
854         }\r
855 \r
856         template<typename CharT, class Base, class Traits>\r
857         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
858                 int n)\r
859         {\r
860             start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);\r
861             if(n < 0)\r
862             {\r
863                 --start;\r
864                 CharT const minus = lcast_char_constants<CharT>::minus;\r
865                 Traits::assign(*start, minus);\r
866             }\r
867             return true;\r
868         }\r
869 \r
870         template<typename CharT, class Base, class Traits>\r
871         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
872                 long n)\r
873         {\r
874             start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);\r
875             if(n < 0)\r
876             {\r
877                 --start;\r
878                 CharT const minus = lcast_char_constants<CharT>::minus;\r
879                 Traits::assign(*start, minus);\r
880             }\r
881             return true;\r
882         }\r
883 \r
884 #if defined(BOOST_HAS_LONG_LONG)\r
885         template<typename CharT, class Base, class Traits>\r
886         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
887                 boost::long_long_type n)\r
888         {\r
889             start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);\r
890             if(n < 0)\r
891             {\r
892                 --start;\r
893                 CharT const minus = lcast_char_constants<CharT>::minus;\r
894                 Traits::assign(*start, minus);\r
895             }\r
896             return true;\r
897         }\r
898 #elif defined(BOOST_HAS_MS_INT64)\r
899         template<typename CharT, class Base, class Traits>\r
900         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
901                 __int64 n)\r
902         {\r
903             start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);\r
904             if(n < 0)\r
905             {\r
906                 --start;\r
907                 CharT const minus = lcast_char_constants<CharT>::minus;\r
908                 Traits::assign(*start, minus);\r
909             }\r
910             return true;\r
911         }\r
912 #endif\r
913 \r
914         template<typename CharT, class Base, class Traits>\r
915         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
916                 unsigned short n)\r
917         {\r
918             start = lcast_put_unsigned<Traits>(n, finish);\r
919             return true;\r
920         }\r
921 \r
922         template<typename CharT, class Base, class Traits>\r
923         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
924                 unsigned int n)\r
925         {\r
926             start = lcast_put_unsigned<Traits>(n, finish);\r
927             return true;\r
928         }\r
929 \r
930         template<typename CharT, class Base, class Traits>\r
931         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
932                 unsigned long n)\r
933         {\r
934             start = lcast_put_unsigned<Traits>(n, finish);\r
935             return true;\r
936         }\r
937 \r
938 #if defined(BOOST_HAS_LONG_LONG)\r
939         template<typename CharT, class Base, class Traits>\r
940         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
941                 boost::ulong_long_type n)\r
942         {\r
943             start = lcast_put_unsigned<Traits>(n, finish);\r
944             return true;\r
945         }\r
946 #elif defined(BOOST_HAS_MS_INT64)\r
947         template<typename CharT, class Base, class Traits>\r
948         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
949                 unsigned __int64 n)\r
950         {\r
951             start = lcast_put_unsigned<Traits>(n, finish);\r
952             return true;\r
953         }\r
954 #endif\r
955 \r
956         template<typename CharT, class Base, class Traits>\r
957         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
958                 float val)\r
959         {\r
960             return this->lcast_put(val);\r
961         }\r
962 \r
963         template<typename CharT, class Base, class Traits>\r
964         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
965                 double val)\r
966         {\r
967             return this->lcast_put(val);\r
968         }\r
969 \r
970         template<typename CharT, class Base, class Traits>\r
971         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
972                 long double val)\r
973         {\r
974             return this->lcast_put(val);\r
975         }\r
976 \r
977         template<typename CharT, class Base, class Traits>\r
978         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(\r
979                 CharT const* str)\r
980         {\r
981             start = const_cast<CharT*>(str);\r
982             finish = start + Traits::length(str);\r
983             return true;\r
984         }\r
985 \r
986         template<typename CharT, class Base, class Traits>\r
987         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(\r
988                 CharT& output)\r
989         {\r
990             bool const ok = (finish - start == 1);\r
991             if(ok)\r
992                 Traits::assign(output, *start);\r
993             return ok;\r
994         }\r
995 \r
996 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
997         template<typename CharT, class Base, class Traits>\r
998         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(\r
999                 std::string& str)\r
1000         {\r
1001             str.assign(start, finish);\r
1002             return true;\r
1003         }\r
1004 \r
1005 #ifndef BOOST_LCAST_NO_WCHAR_T\r
1006         template<typename CharT, class Base, class Traits>\r
1007         inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(\r
1008                 std::wstring& str)\r
1009         {\r
1010             str.assign(start, finish);\r
1011             return true;\r
1012         }\r
1013 #endif\r
1014 #endif\r
1015     }\r
1016 \r
1017     namespace detail // lcast_streambuf_for_source\r
1018     {\r
1019         // Returns true if optimized stream wrapper needs ostream for writing.\r
1020         template<class Source>\r
1021         struct lcast_streambuf_for_source\r
1022         {\r
1023             BOOST_STATIC_CONSTANT(bool, value = false);\r
1024         };\r
1025 \r
1026         template<>\r
1027         struct lcast_streambuf_for_source<float>\r
1028         {\r
1029             BOOST_STATIC_CONSTANT(bool, value = true);\r
1030         };\r
1031  \r
1032         template<>\r
1033         struct lcast_streambuf_for_source<double>\r
1034         {\r
1035             BOOST_STATIC_CONSTANT(bool, value = true);\r
1036         };\r
1037   \r
1038         template<>\r
1039         struct lcast_streambuf_for_source<long double>\r
1040         {\r
1041             BOOST_STATIC_CONSTANT(bool, value = true);\r
1042         };\r
1043     }\r
1044 \r
1045     namespace detail // lcast_streambuf_for_target\r
1046     {\r
1047         // Returns true if optimized stream wrapper needs istream for reading.\r
1048         template<class Target>\r
1049         struct lcast_streambuf_for_target\r
1050         {\r
1051             BOOST_STATIC_CONSTANT(bool, value = true);\r
1052         };\r
1053 \r
1054         template<>\r
1055         struct lcast_streambuf_for_target<char>\r
1056         {\r
1057             BOOST_STATIC_CONSTANT(bool, value = false);\r
1058         };\r
1059 \r
1060 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)\r
1061         template<>\r
1062         struct lcast_streambuf_for_target<wchar_t>\r
1063         {\r
1064             BOOST_STATIC_CONSTANT(bool, value = false);\r
1065         };\r
1066 #endif\r
1067 \r
1068 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
1069         template<class Traits, class Alloc>\r
1070         struct lcast_streambuf_for_target<\r
1071                     std::basic_string<char,Traits,Alloc> >\r
1072         {\r
1073             BOOST_STATIC_CONSTANT(bool, value = false);\r
1074         };\r
1075 \r
1076 #ifndef BOOST_LCAST_NO_WCHAR_T\r
1077         template<class Traits, class Alloc>\r
1078         struct lcast_streambuf_for_target<\r
1079                     std::basic_string<wchar_t,Traits,Alloc> >\r
1080         {\r
1081             BOOST_STATIC_CONSTANT(bool, value = false);\r
1082         };\r
1083 #endif\r
1084 #else\r
1085         template<>\r
1086         struct lcast_streambuf_for_target<std::string>\r
1087         {\r
1088             BOOST_STATIC_CONSTANT(bool, value = false);\r
1089         };\r
1090 \r
1091 #ifndef BOOST_LCAST_NO_WCHAR_T\r
1092         template<>\r
1093         struct lcast_streambuf_for_target<std::wstring>\r
1094         {\r
1095             BOOST_STATIC_CONSTANT(bool, value = false);\r
1096         };\r
1097 #endif\r
1098 #endif\r
1099     }\r
1100 \r
1101     #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
1102 \r
1103     // call-by-const reference version\r
1104 \r
1105     namespace detail\r
1106     {\r
1107         template<class T>\r
1108         struct array_to_pointer_decay\r
1109         {\r
1110             typedef T type;\r
1111         };\r
1112 \r
1113         template<class T, std::size_t N>\r
1114         struct array_to_pointer_decay<T[N]>\r
1115         {\r
1116             typedef const T * type;\r
1117         };\r
1118 \r
1119 #if (defined _MSC_VER)\r
1120 # pragma warning( push )\r
1121 # pragma warning( disable : 4701 ) // possible use of ... before initialization\r
1122 # pragma warning( disable : 4702 ) // unreachable code\r
1123 #endif\r
1124 \r
1125         template< typename Target\r
1126                 , typename Source\r
1127                 , bool Unlimited // string representation of Source is unlimited\r
1128                 , typename CharT\r
1129                 >\r
1130         Target lexical_cast(\r
1131             BOOST_DEDUCED_TYPENAME boost::call_traits<Source>::param_type arg,\r
1132             CharT* buf, std::size_t src_len)\r
1133         {\r
1134             typedef BOOST_DEDUCED_TYPENAME\r
1135                 deduce_char_traits<CharT,Target,Source>::type traits;\r
1136 \r
1137             typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<\r
1138                 lcast_streambuf_for_target<Target>::value ||\r
1139                 lcast_streambuf_for_source<Source>::value\r
1140               , std::basic_streambuf<CharT>\r
1141               , lexical_streambuf_fake\r
1142               >::type base;\r
1143 \r
1144             BOOST_DEDUCED_TYPENAME boost::mpl::if_c<\r
1145                 Unlimited\r
1146               , detail::lexical_stream<Target,Source,traits>\r
1147               , detail::lexical_stream_limited_src<CharT,base,traits>\r
1148               >::type interpreter(buf, buf + src_len);\r
1149 \r
1150             Target result;\r
1151             if(!(interpreter << arg && interpreter >> result))\r
1152                 BOOST_LCAST_THROW_BAD_CAST(Source, Target);\r
1153             return result;\r
1154         }\r
1155 #if (defined _MSC_VER)\r
1156 # pragma warning( pop )\r
1157 #endif\r
1158     }\r
1159 \r
1160     template<typename Target, typename Source>\r
1161     inline Target lexical_cast(const Source &arg)\r
1162     {\r
1163         typedef typename detail::array_to_pointer_decay<Source>::type src;\r
1164 \r
1165         typedef typename detail::widest_char<\r
1166             typename detail::stream_char<Target>::type\r
1167           , typename detail::stream_char<src>::type\r
1168           >::type char_type;\r
1169 \r
1170         typedef detail::lcast_src_length<char_type, src> lcast_src_length;\r
1171         std::size_t const src_len = lcast_src_length::value;\r
1172         char_type buf[src_len + 1];\r
1173         lcast_src_length::check_coverage();\r
1174         return detail::lexical_cast<Target, src, !src_len>(arg, buf, src_len);\r
1175     }\r
1176 \r
1177     #else\r
1178 \r
1179     // call-by-value fallback version (deprecated)\r
1180 \r
1181     template<typename Target, typename Source>\r
1182     Target lexical_cast(Source arg)\r
1183     {\r
1184         typedef typename detail::widest_char< \r
1185             BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type \r
1186           , BOOST_DEDUCED_TYPENAME detail::stream_char<Source>::type \r
1187         >::type char_type; \r
1188 \r
1189         typedef std::char_traits<char_type> traits;\r
1190         detail::lexical_stream<Target, Source, traits> interpreter;\r
1191         Target result;\r
1192 \r
1193         if(!(interpreter << arg && interpreter >> result))\r
1194 #ifndef BOOST_NO_TYPEID\r
1195             throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));\r
1196 #else\r
1197             throw_exception(bad_lexical_cast());\r
1198 #endif\r
1199         return result;\r
1200     }\r
1201 \r
1202     #endif\r
1203 }\r
1204 \r
1205 // Copyright Kevlin Henney, 2000-2005.\r
1206 // Copyright Alexander Nasonov, 2006-2007.\r
1207 //\r
1208 // Distributed under the Boost Software License, Version 1.0. (See\r
1209 // accompanying file LICENSE_1_0.txt or copy at\r
1210 // http://www.boost.org/LICENSE_1_0.txt)\r
1211 \r
1212 #undef BOOST_LCAST_NO_WCHAR_T\r
1213 #endif\r