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