SCM Repositories - boost


Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.24, Sun Aug 6 12:31:44 2006 UTC revision 1.26, Sat Aug 26 17:22:33 2006 UTC
# Line 11  Line 11 
11  //        enhanced with contributions from Terje Slettebo,  //        enhanced with contributions from Terje Slettebo,
12  //        with additional fixes and suggestions from Gennaro Prota,  //        with additional fixes and suggestions from Gennaro Prota,
13  //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,  //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
14  //        and other Boosters  //        Alexander Nasonov and other Boosters
15  // when:  November 2000, March 2003, June 2005  // when:  November 2000, March 2003, June 2005, June 2006
16    
17    #include <climits>
18  #include <cstddef>  #include <cstddef>
19    #include <istream>
20    #include <locale>
21  #include <string>  #include <string>
22  #include <typeinfo>  #include <typeinfo>
23  #include <boost/config.hpp>  #include <boost/config.hpp>
24  #include <boost/limits.hpp>  #include <boost/limits.hpp>
25    #include <boost/mpl/if.hpp>
26  #include <boost/throw_exception.hpp>  #include <boost/throw_exception.hpp>
27  #include <boost/type_traits/is_pointer.hpp>  #include <boost/type_traits/is_pointer.hpp>
28  #include <boost/call_traits.hpp>  #include <boost/call_traits.hpp>
29    #include <boost/static_assert.hpp>
30    
31  #ifdef BOOST_NO_STRINGSTREAM  #ifdef BOOST_NO_STRINGSTREAM
32  #include <strstream>  #include <strstream>
# Line 81  Line 86 
86          };          };
87    
88          #ifndef DISABLE_WIDE_CHAR_SUPPORT          #ifndef DISABLE_WIDE_CHAR_SUPPORT
89  #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)  #ifndef BOOST_NO_INTRINSIC_WCHAR_T
90          template<>          template<>
91          struct stream_char<wchar_t>          struct stream_char<wchar_t>
92          {          {
# Line 121  Line 126 
126          };          };
127      }      }
128    
129        namespace detail // lcast_src_length
130        {
131            // Return max. length of string representation of Source;
132            // 0 if unlimited (with exceptions for some types, see below).
133            // Values with limited string representation are placed to
134            // the buffer locally defined in lexical_cast function.
135            // 1 is returned for few types such as CharT const* or
136            // std::basic_string<CharT> that already have an internal
137            // buffer ready to be reused by lexical_stream_limited_src.
138            // Each specialization should have a correspondent operator<<
139            // defined in lexical_stream_limited_src.
140            template< class CharT  // A result of widest_char transformation.
141                    , class Source // Source type of lexical_cast.
142                    >
143            struct lcast_src_length
144            {
145                BOOST_STATIC_CONSTANT(std::size_t, value = 0);
146                // To check coverage, build the test with
147                // bjam --v2 profile optimization=off
148                static void check_coverage() {}
149            };
150    
151            template<>
152            struct lcast_src_length<char, bool>
153            {
154                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
155                static void check_coverage() {}
156            };
157    
158            template<>
159            struct lcast_src_length<char, char>
160            {
161                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
162                static void check_coverage() {}
163            };
164    
165            // No specializations for:
166            // lcast_src_length<char, signed char>
167            // lcast_src_length<char, unsigned char>
168            // lcast_src_length<char, signed char*>
169            // lcast_src_length<char, unsigned char*>
170            // lcast_src_length<char, signed char const*>
171            // lcast_src_length<char, unsigned char const*>
172    
173    #ifndef DISABLE_WIDE_CHAR_SUPPORT
174            template<>
175            struct lcast_src_length<wchar_t, bool>
176            {
177                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
178                static void check_coverage() {}
179            };
180    
181            template<>
182            struct lcast_src_length<wchar_t, char>
183            {
184                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
185                static void check_coverage() {}
186            };
187    
188    #ifndef BOOST_NO_INTRINSIC_WCHAR_T
189            template<>
190            struct lcast_src_length<wchar_t, wchar_t>
191            {
192                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
193                static void check_coverage() {}
194            };
195    #endif
196    #endif
197    
198            template<>
199            struct lcast_src_length<char, char const*>
200            {
201                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
202                static void check_coverage() {}
203            };
204    
205            template<>
206            struct lcast_src_length<char, char*>
207            {
208                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
209                static void check_coverage() {}
210            };
211    
212    #ifndef DISABLE_WIDE_CHAR_SUPPORT
213            template<>
214            struct lcast_src_length<wchar_t, wchar_t const*>
215            {
216                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
217                static void check_coverage() {}
218            };
219    
220            template<>
221            struct lcast_src_length<wchar_t, wchar_t*>
222            {
223                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
224                static void check_coverage() {}
225            };
226    #endif
227    
228    #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
229            template<class CharT, class Traits, class Alloc>
230            struct lcast_src_length< CharT, std::basic_string<CharT,Traits,Alloc> >
231            {
232                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
233                static void check_coverage() {}
234            };
235    #else
236            template<>
237            struct lcast_src_length< char, std::basic_string<char> >
238            {
239                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
240                static void check_coverage() {}
241            };
242    
243    #ifndef DISABLE_WIDE_CHAR_SUPPORT
244            template<>
245            struct lcast_src_length< wchar_t, std::basic_string<wchar_t> >
246            {
247                BOOST_STATIC_CONSTANT(std::size_t, value = 1);
248                static void check_coverage() {}
249            };
250    #endif
251    #endif
252    
253            // Helper for integral types.
254            // Notes on length calculation:
255            // Max length for 32bit int with grouping "\1" and thousands_sep ',':
256            // "-2,1,4,7,4,8,3,6,4,7"
257            //  ^                    - is_signed
258            //   ^                   - 1 digit not counted by digits10
259            //    ^^^^^^^^^^^^^^^^^^ - digits10 * 2
260            //
261            // Constant is_specialized is used instead of constant 1
262            // to prevent buffer overflow in a rare case when
263            // <boost/limits.hpp> doesn't add missing specialization for
264            // numeric_limits<T> for some integral type T.
265            // When is_specialized is false, the whole expression is 0.
266            template<class Source>
267            struct lcast_src_length_integral
268            {
269    #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x581
270                BOOST_STATIC_CONSTANT(std::size_t, value =
271                      std::numeric_limits<Source>::is_signed +
272                      std::numeric_limits<Source>::is_specialized + // == 1
273                      std::numeric_limits<Source>::digits10 * 2
274                  );
275    #else
276                BOOST_STATIC_CONSTANT(std::size_t, value = 156); // 256bit integers
277    #endif
278            };
279    
280    #define BOOST_AUX_LEXICAL_CAST_DEF1(CharT, T) template<>             \
281        struct lcast_src_length<CharT, T> : lcast_src_length_integral<T> \
282        { static void check_coverage() {} };
283    
284    #ifdef DISABLE_WIDE_CHAR_SUPPORT
285    #define BOOST_AUX_LEXICAL_CAST_DEF(T) BOOST_AUX_LEXICAL_CAST_DEF1(char, T)
286    #else
287    #define BOOST_AUX_LEXICAL_CAST_DEF(T)          \
288            BOOST_AUX_LEXICAL_CAST_DEF1(char, T)   \
289            BOOST_AUX_LEXICAL_CAST_DEF1(wchar_t, T)
290    #endif
291    
292            BOOST_AUX_LEXICAL_CAST_DEF(short)
293            BOOST_AUX_LEXICAL_CAST_DEF(unsigned short)
294            BOOST_AUX_LEXICAL_CAST_DEF(int)
295            BOOST_AUX_LEXICAL_CAST_DEF(unsigned int)
296            BOOST_AUX_LEXICAL_CAST_DEF(long)
297            BOOST_AUX_LEXICAL_CAST_DEF(unsigned long)
298    #if defined(BOOST_HAS_LONG_LONG)
299            BOOST_AUX_LEXICAL_CAST_DEF(boost::ulong_long_type)
300            BOOST_AUX_LEXICAL_CAST_DEF(boost::long_long_type )
301    #elif defined(BOOST_HAS_MS_INT64)
302            BOOST_AUX_LEXICAL_CAST_DEF(unsigned __int64)
303            BOOST_AUX_LEXICAL_CAST_DEF(         __int64)
304    #endif
305    
306    #undef BOOST_AUX_LEXICAL_CAST_DEF
307    #undef BOOST_AUX_LEXICAL_CAST_DEF1
308    
309        }
310    
311        namespace detail // '0' and '-' constants
312        {
313            template<typename CharT> struct lcast_char_constants;
314    
315            template<>
316            struct lcast_char_constants<char>
317            {
318                BOOST_STATIC_CONSTANT(char, zero  = '0');
319                BOOST_STATIC_CONSTANT(char, minus = '-');
320            };
321    
322    #ifndef DISABLE_WIDE_CHAR_SUPPORT
323            template<>
324            struct lcast_char_constants<wchar_t>
325            {
326                BOOST_STATIC_CONSTANT(wchar_t, zero  = L'0');
327                BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
328            };
329    #endif
330        }
331    
332        namespace detail // public access to basic_streambuf<CharT>::setg
333        {
334            template<typename CharT>
335            class lexical_streambuf : public std::basic_streambuf<CharT>
336            {
337            public:
338                void setbuf(CharT* start, CharT* finish)
339                {
340                    this->setg(start, start, finish);
341                }
342            };
343        }
344    
345        namespace detail // lcast_to_unsigned
346        {
347    #if (defined _MSC_VER)
348    # pragma warning( push )
349    // C4146: unary minus operator applied to unsigned type, result still unsigned
350    # pragma warning( disable : 4146 )
351    #endif
352    
353            inline unsigned int lcast_to_unsigned(int value)
354            {
355                unsigned int uval = value;
356                return value < 0 ? -uval : uval;
357            }
358    
359            inline unsigned long lcast_to_unsigned(long value)
360            {
361                unsigned long uval = value;
362                return value < 0 ? -uval : uval;
363            }
364    
365    #if defined(BOOST_HAS_LONG_LONG)
366            inline boost::ulong_long_type lcast_to_unsigned(boost::long_long_type v)
367            {
368                boost::ulong_long_type uval = v;
369                return v < 0 ? -uval : uval;
370            }
371    #elif defined(BOOST_HAS_MS_INT64)
372            inline unsigned __int64 lcast_to_unsigned(__int64 value)
373            {
374                unsigned __int64 uval = value;
375                return value < 0 ? -uval : uval;
376            }
377    #endif
378    
379    #if (defined _MSC_VER)
380    # pragma warning( pop ) // C4146: unary minus operator applied to unsigned type, result still unsigned
381    #endif
382        }
383    
384        namespace detail // lcast_put_unsigned
385        {
386            // I'd personally put lcast_put_unsigned in .cpp file if not
387            // boost practice for header-only libraries (Alexander Nasonov).
388            template<typename T, typename CharT>
389            CharT* lcast_put_unsigned(T n, CharT* finish)
390            {
391                typedef std::numpunct<CharT> numpunct;
392    
393                CharT thousands_sep = 0;
394    
395    #if !defined(MEASURE_LEXICAL_CAST_PERFORMANCE_WITHOUT_LOCALE_OVERHEAD)
396                std::locale loc;
397                numpunct const& np = BOOST_USE_FACET(numpunct, loc);
398                std::string const& grouping = np.grouping();
399                std::string::size_type const grouping_size = grouping.size();
400    
401                if(grouping_size)
402                    thousands_sep = np.thousands_sep();
403    #else // dead branch in production code
404                char const* grouping = "";
405                std::size_t grouping_size = 0;
406    #endif
407    
408                std::string::size_type group = 0; // current group number
409                char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];
410                // a) Since grouping is const, grouping[grouping.size()] returns 0.
411                // b) It's safe to assume here and below that CHAR_MAX
412                //    is equivalent to unlimited grouping:
413    #if !defined(__BORLANDC__) || __BORLANDC__ >= 0x581
414                BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
415    #endif
416    
417                char left = last_grp_size;
418    
419                do
420                {
421                    if(left == 0)
422                    {
423                        ++group;
424                        if(group < grouping_size)
425                        {
426                            char const grp_size = grouping[group];
427                            last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
428                        }
429    
430                        left = last_grp_size;
431                        --finish;
432                        *finish = thousands_sep;
433                    }
434    
435                    --left;
436                    --finish;
437                    int const digit = n % 10;
438                    int const cdigit = digit + lcast_char_constants<CharT>::zero;
439                    *finish = static_cast<char>(cdigit);
440                    n /= 10;
441                } while(n);
442    
443                return finish;
444            }
445        }
446    
447      namespace detail // stream wrapper for handling lexical conversions      namespace detail // stream wrapper for handling lexical conversions
448      {      {
449          template<typename Target, typename Source>          template<typename Target, typename Source>
# Line 132  Line 455 
455                  typename stream_char<Source>::type>::type char_type;                  typename stream_char<Source>::type>::type char_type;
456    
457          public:          public:
458              lexical_stream()              lexical_stream(char_type* = 0, char_type* = 0)
459              {              {
460                  stream.unsetf(std::ios::skipws);                  stream.unsetf(std::ios::skipws);
461    
# Line 186  Line 509 
509                  #if defined(BOOST_NO_STRINGSTREAM)                  #if defined(BOOST_NO_STRINGSTREAM)
510                  stream << '\0';                  stream << '\0';
511                  #endif                  #endif
512                  output = stream.str();                  stream.str().swap(output);
513                  return true;                  return true;
514              }              }
515              #ifndef DISABLE_WIDE_CHAR_SUPPORT              #ifndef DISABLE_WIDE_CHAR_SUPPORT
516              bool operator>>(std::wstring &output)              bool operator>>(std::wstring &output)
517              {              {
518                  output = stream.str();                  stream.str().swap(output);
519                  return true;                  return true;
520              }              }
521              #endif              #endif
# Line 207  Line 530 
530          };          };
531      }      }
532    
533        namespace detail // optimized stream wrapper
534        {
535            // String representation of Source has an upper limit.
536            template<typename CharT>
537            class lexical_stream_limited_src
538            {
539                // A string representation of Source is written to [start, finish).
540                // Currently, it is assumed that [start, finish) is big enough
541                // to hold a string representation of any Source value.
542                CharT* start;
543                CharT* finish;
544    
545            private:
546    
547                static void widen_and_assign(char*p, char ch)
548                {
549                    *p = ch;
550                }
551    
552    #ifndef DISABLE_WIDE_CHAR_SUPPORT
553                static void widen_and_assign(wchar_t* p, char ch)
554                {
555                    std::locale loc;
556                    *p = BOOST_USE_FACET(std::ctype<wchar_t>, loc).widen(ch);
557                }
558    
559                static void widen_and_assign(wchar_t* p, wchar_t ch)
560                {
561                    *p = ch;
562                }
563    
564                static void widen_and_assign(char*, wchar_t ch); // undefined
565    #endif
566    
567                // Undefined:
568                lexical_stream_limited_src(lexical_stream_limited_src const&);
569                void operator=(lexical_stream_limited_src const&);
570    
571            public:
572    
573                lexical_stream_limited_src(CharT* start, CharT* finish)
574                  : start(start)
575                  , finish(finish)
576                {}
577    
578            public: // output
579    
580                template<class Traits, class Alloc>
581                bool operator<<(std::basic_string<CharT, Traits, Alloc> const& str)
582                {
583                    start = const_cast<CharT*>(str.data());
584                    finish = start + str.length();
585                    return true;
586                }
587    
588                bool operator<<(bool);
589                bool operator<<(char);
590    #if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
591                bool operator<<(wchar_t);
592    #endif
593                bool operator<<(CharT const*);
594                bool operator<<(short);
595                bool operator<<(int);
596                bool operator<<(long);
597                bool operator<<(unsigned short);
598                bool operator<<(unsigned int);
599                bool operator<<(unsigned long);
600    #if defined(BOOST_HAS_LONG_LONG)
601                bool operator<<(boost::ulong_long_type);
602                bool operator<<(boost::long_long_type );
603    #elif defined(BOOST_HAS_MS_INT64)
604                bool operator<<(unsigned __int64);
605                bool operator<<(         __int64);
606    #endif
607    
608            public: // input
609    
610                template<typename InputStreamable>
611                bool operator>>(InputStreamable& output)
612                {
613    #if (defined _MSC_VER)
614    # pragma warning( push )
615      // conditional expression is constant
616    # pragma warning( disable : 4127 )
617    #endif
618                    if(is_pointer<InputStreamable>::value)
619                        return false;
620    
621                    lexical_streambuf<CharT> sb;
622                    sb.setbuf(start, finish);
623    
624                    std::basic_istream<CharT> stream(&sb);
625                    stream.unsetf(std::ios::skipws);
626    
627                    typedef std::numeric_limits<InputStreamable> limits;
628    
629                    if(limits::is_specialized)
630                        stream.precision(limits::digits10 + 1);
631    #if (defined _MSC_VER)
632    # pragma warning( pop )
633    #endif
634                    return stream >> output &&
635                        stream.get() ==
636    #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
637            // GCC 2.9x lacks std::char_traits<>::eof().
638            // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
639            // configurations, which do provide std::char_traits<>::eof().
640    
641                        EOF;
642    #else
643                    std::char_traits<CharT>::eof();
644    #endif
645                }
646    
647                bool operator>>(CharT&);
648                bool operator>>(std::string&);
649    
650                #ifndef DISABLE_WIDE_CHAR_SUPPORT
651                bool operator>>(std::wstring&);
652                #endif
653            };
654    
655            template<typename CharT>
656            inline bool lexical_stream_limited_src<CharT>::operator<<(bool value)
657            {
658                *start = value + lcast_char_constants<CharT>::zero;
659                finish = start + 1;
660                return true;
661            }
662    
663            template<typename CharT>
664            inline bool lexical_stream_limited_src<CharT>::operator<<(char ch)
665            {
666                widen_and_assign(start, ch);
667                finish = start + 1;
668                return true;
669            }
670    
671    #if !defined(DISABLE_WIDE_CHAR_SUPPORT) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
672            template<typename CharT>
673            inline bool lexical_stream_limited_src<CharT>::operator<<(wchar_t ch)
674            {
675                widen_and_assign(start, ch);
676                finish = start + 1;
677                return true;
678            }
679    #endif
680    
681            template<typename CharT>
682            inline bool lexical_stream_limited_src<CharT>::operator<<(short n)
683            {
684                start = lcast_put_unsigned(lcast_to_unsigned(n), finish);
685                if(n < 0)
686                    *--start = lcast_char_constants<CharT>::minus;
687                return true;
688            }
689    
690            template<typename CharT>
691            inline bool lexical_stream_limited_src<CharT>::operator<<(int n)
692            {
693                start = lcast_put_unsigned(lcast_to_unsigned(n), finish);
694                if(n < 0)
695                    *--start = lcast_char_constants<CharT>::minus;
696                return true;
697            }
698    
699            template<typename CharT>
700            inline bool lexical_stream_limited_src<CharT>::operator<<(long n)
701            {
702                start = lcast_put_unsigned(lcast_to_unsigned(n), finish);
703                if(n < 0)
704                    *--start = lcast_char_constants<CharT>::minus;
705                return true;
706            }
707    
708    #if defined(BOOST_HAS_LONG_LONG)
709            template<typename CharT>
710            inline bool lexical_stream_limited_src<CharT>::operator<<(
711                    boost::long_long_type n)
712            {
713                start = lcast_put_unsigned(lcast_to_unsigned(n), finish);
714                if(n < 0)
715                    *--start = lcast_char_constants<CharT>::minus;
716                return true;
717            }
718    #elif defined(BOOST_HAS_MS_INT64)
719            template<typename CharT>
720            inline bool lexical_stream_limited_src<CharT>::operator<<(__int64 n)
721            {
722                start = lcast_put_unsigned(lcast_to_unsigned(n), finish);
723                if(n < 0)
724                    *--start = lcast_char_constants<CharT>::minus;
725                return true;
726            }
727    #endif
728    
729            template<typename CharT>
730            inline bool lexical_stream_limited_src<CharT>::operator<<(
731                    unsigned short n)
732            {
733                start = lcast_put_unsigned(+n, finish);
734                return true;
735            }
736    
737            template<typename CharT>
738            inline bool lexical_stream_limited_src<CharT>::operator<<(
739                    unsigned int n)
740            {
741                start = lcast_put_unsigned(n, finish);
742                return true;
743            }
744    
745            template<typename CharT>
746            inline bool lexical_stream_limited_src<CharT>::operator<<(
747                    unsigned long n)
748            {
749                start = lcast_put_unsigned(n, finish);
750                return true;
751            }
752    
753    #if defined(BOOST_HAS_LONG_LONG)
754            template<typename CharT>
755            inline bool lexical_stream_limited_src<CharT>::operator<<(
756                    boost::ulong_long_type n)
757            {
758                start = lcast_put_unsigned(n, finish);
759                return true;
760            }
761    #elif defined(BOOST_HAS_MS_INT64)
762            template<typename CharT>
763            inline bool lexical_stream_limited_src<CharT>::operator<<(
764                    unsigned __int64 n)
765            {
766                start = lcast_put_unsigned(n, finish);
767                return true;
768            }
769    #endif
770    
771            template<typename CharT>
772            inline bool lexical_stream_limited_src<CharT>::operator<<(
773                    CharT const* str)
774            {
775                start = const_cast<CharT*>(str);
776                finish = start + std::char_traits<CharT>::length(str);
777                return true;
778            }
779    
780            template<typename CharT>
781            inline bool lexical_stream_limited_src<CharT>::operator>>(CharT& output)
782            {
783                bool const ok = (finish - start == 1);
784                if(ok)
785                    output = *start;
786                return ok;
787            }
788    
789            template<typename CharT>
790            inline bool lexical_stream_limited_src<CharT>::operator>>(
791                    std::string& str)
792            {
793                str.assign(start, finish);
794                return true;
795            }
796    
797            #ifndef DISABLE_WIDE_CHAR_SUPPORT
798            template<typename CharT>
799            inline bool lexical_stream_limited_src<CharT>::operator>>(
800                    std::wstring& str)
801            {
802                str.assign(start, finish);
803                return true;
804            }
805            #endif
806        }
807    
808      #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION      #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
809    
810      // call-by-const reference version      // call-by-const reference version
# Line 225  Line 823 
823              typedef const T * type;              typedef const T * type;
824          };          };
825    
826          template<typename Target, typename Source>          template< typename Target
827                    , typename Source
828                    , bool Unlimited // string representation of Source is unlimited
829                    , typename CharT
830                    >
831          Target lexical_cast(          Target lexical_cast(
832              BOOST_DEDUCED_TYPENAME boost::call_traits<Source>::value_type arg)              BOOST_DEDUCED_TYPENAME boost::call_traits<Source>::value_type arg,
833                CharT* buf, std::size_t src_len)
834          {          {
835                BOOST_DEDUCED_TYPENAME mpl::if_c<
836              detail::lexical_stream<Target, Source> interpreter;                  Unlimited
837                  , detail::lexical_stream<Target, Source>
838                  , detail::lexical_stream_limited_src<CharT>
839                  >::type interpreter(buf, buf + src_len);
840    
841              // The original form, reproduced below, is more elegant              // The original form, reproduced below, is more elegant
842              // but yields a spurious C4701 warning ("possible use of              // but yields a spurious C4701 warning ("possible use of
# Line 255  Line 861 
861      template<typename Target, typename Source>      template<typename Target, typename Source>
862      inline Target lexical_cast(const Source &arg)      inline Target lexical_cast(const Source &arg)
863      {      {
864          typedef typename detail::array_to_pointer_decay<Source>::type NewSource;          typedef typename detail::array_to_pointer_decay<Source>::type src;
865          return detail::lexical_cast<Target, NewSource>(arg);  
866            typedef typename detail::widest_char<
867                typename detail::stream_char<Target>::type
868              , typename detail::stream_char<src>::type
869              >::type char_type;
870    
871            typedef detail::lcast_src_length<char_type, src> lcast_src_length;
872            std::size_t const src_len = lcast_src_length::value;
873            char_type buf[src_len + 1];
874            lcast_src_length::check_coverage();
875            return detail::lexical_cast<Target, src, !src_len>(arg, buf, src_len);
876      }      }
877    
878      #else      #else

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.26