PageRenderTime 90ms CodeModel.GetById 19ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 1ms

/src/contrib/boost/lexical_cast.hpp

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