1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216 |
- #ifndef BOOST_LEXICAL_CAST_INCLUDED
- #define BOOST_LEXICAL_CAST_INCLUDED
- // Boost lexical_cast.hpp header -------------------------------------------//
- //
- // See http://www.boost.org/libs/conversion for documentation.
- // See end of this header for rights and permissions.
- //
- // what: lexical_cast custom keyword cast
- // who: contributed by Kevlin Henney,
- // enhanced with contributions from Terje Slettebo,
- // with additional fixes and suggestions from Gennaro Prota,
- // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
- // Alexander Nasonov and other Boosters
- // when: November 2000, March 2003, June 2005, June 2006
- #include <climits>
- #include <cstddef>
- #include <istream>
- #include <string>
- #include <typeinfo>
- #include <exception>
- #include <boost/config.hpp>
- #include <boost/limits.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/throw_exception.hpp>
- #include <boost/type_traits/is_pointer.hpp>
- #include <boost/type_traits/make_unsigned.hpp>
- #include <boost/call_traits.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/detail/lcast_precision.hpp>
- #include <boost/detail/workaround.hpp>
- #ifndef BOOST_NO_STD_LOCALE
- #include <locale>
- #endif
- #ifdef BOOST_NO_STRINGSTREAM
- #include <strstream>
- #else
- #include <sstream>
- #endif
- #if defined(BOOST_NO_STRINGSTREAM) || \
- defined(BOOST_NO_STD_WSTRING) || \
- defined(BOOST_NO_STD_LOCALE)
- #define BOOST_LCAST_NO_WCHAR_T
- #endif
- namespace boost
- {
- // exception used to indicate runtime lexical_cast failure
- class bad_lexical_cast : public std::bad_cast
- #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
- // under bcc32 5.5.1 bad_cast doesn't derive from exception
- , public std::exception
- #endif
- {
- public:
- bad_lexical_cast() :
- #ifndef BOOST_NO_TYPEID
- source(&typeid(void)), target(&typeid(void))
- #else
- source(0), target(0) // this breaks getters
- #endif
- {
- }
- bad_lexical_cast(
- const std::type_info &source_type_arg,
- const std::type_info &target_type_arg) :
- source(&source_type_arg), target(&target_type_arg)
- {
- }
- const std::type_info &source_type() const
- {
- return *source;
- }
- const std::type_info &target_type() const
- {
- return *target;
- }
- virtual const char *what() const throw()
- {
- return "bad lexical cast: "
- "source type value could not be interpreted as target";
- }
- virtual ~bad_lexical_cast() throw()
- {
- }
- private:
- const std::type_info *source;
- const std::type_info *target;
- };
- namespace detail // selectors for choosing stream character type
- {
- template<typename Type>
- struct stream_char
- {
- typedef char type;
- };
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template<class CharT, class Traits, class Alloc>
- struct stream_char< std::basic_string<CharT,Traits,Alloc> >
- {
- typedef CharT type;
- };
- #endif
- #ifndef BOOST_LCAST_NO_WCHAR_T
- #ifndef BOOST_NO_INTRINSIC_WCHAR_T
- template<>
- struct stream_char<wchar_t>
- {
- typedef wchar_t type;
- };
- #endif
- template<>
- struct stream_char<wchar_t *>
- {
- typedef wchar_t type;
- };
- template<>
- struct stream_char<const wchar_t *>
- {
- typedef wchar_t type;
- };
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template<>
- struct stream_char<std::wstring>
- {
- typedef wchar_t type;
- };
- #endif
- #endif
- template<typename TargetChar, typename SourceChar>
- struct widest_char
- {
- typedef TargetChar type;
- };
- template<>
- struct widest_char<char, wchar_t>
- {
- typedef wchar_t type;
- };
- }
- namespace detail // deduce_char_traits template
- {
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template<class CharT, class Target, class Source>
- struct deduce_char_traits
- {
- typedef std::char_traits<CharT> type;
- };
- template<class CharT, class Traits, class Alloc, class Source>
- struct deduce_char_traits< CharT
- , std::basic_string<CharT,Traits,Alloc>
- , Source
- >
- {
- typedef Traits type;
- };
- template<class CharT, class Target, class Traits, class Alloc>
- struct deduce_char_traits< CharT
- , Target
- , std::basic_string<CharT,Traits,Alloc>
- >
- {
- typedef Traits type;
- };
- template<class CharT, class Traits, class Alloc1, class Alloc2>
- struct deduce_char_traits< CharT
- , std::basic_string<CharT,Traits,Alloc1>
- , std::basic_string<CharT,Traits,Alloc2>
- >
- {
- typedef Traits type;
- };
- #endif
- }
- namespace detail // lcast_src_length
- {
- // Return max. length of string representation of Source;
- // 0 if unlimited (with exceptions for some types, see below).
- // Values with limited string representation are placed to
- // the buffer locally defined in lexical_cast function.
- // 1 is returned for few types such as CharT const* or
- // std::basic_string<CharT> that already have an internal
- // buffer ready to be reused by lexical_stream_limited_src.
- // Each specialization should have a correspondent operator<<
- // defined in lexical_stream_limited_src.
- template< class CharT // A result of widest_char transformation.
- , class Source // Source type of lexical_cast.
- >
- struct lcast_src_length
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 0);
- // To check coverage, build the test with
- // bjam --v2 profile optimization=off
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<char, bool>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<char, char>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- // No specializations for:
- // lcast_src_length<char, signed char>
- // lcast_src_length<char, unsigned char>
- // lcast_src_length<char, signed char*>
- // lcast_src_length<char, unsigned char*>
- // lcast_src_length<char, signed char const*>
- // lcast_src_length<char, unsigned char const*>
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<>
- struct lcast_src_length<wchar_t, bool>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<wchar_t, char>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #ifndef BOOST_NO_INTRINSIC_WCHAR_T
- template<>
- struct lcast_src_length<wchar_t, wchar_t>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #endif
- #endif
- template<>
- struct lcast_src_length<char, char const*>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<char, char*>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<>
- struct lcast_src_length<wchar_t, wchar_t const*>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<wchar_t, wchar_t*>
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #endif
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template<class CharT, class Traits, class Alloc>
- struct lcast_src_length< CharT, std::basic_string<CharT,Traits,Alloc> >
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #else
- template<>
- struct lcast_src_length< char, std::basic_string<char> >
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<>
- struct lcast_src_length< wchar_t, std::basic_string<wchar_t> >
- {
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
- static void check_coverage() {}
- };
- #endif
- #endif
- // Helper for integral types.
- // Notes on length calculation:
- // Max length for 32bit int with grouping "\1" and thousands_sep ',':
- // "-2,1,4,7,4,8,3,6,4,7"
- // ^ - is_signed
- // ^ - 1 digit not counted by digits10
- // ^^^^^^^^^^^^^^^^^^ - digits10 * 2
- //
- // Constant is_specialized is used instead of constant 1
- // to prevent buffer overflow in a rare case when
- // <boost/limits.hpp> doesn't add missing specialization for
- // numeric_limits<T> for some integral type T.
- // When is_specialized is false, the whole expression is 0.
- template<class Source>
- struct lcast_src_length_integral
- {
- #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_CONSTANT(std::size_t, value =
- std::numeric_limits<Source>::is_signed +
- std::numeric_limits<Source>::is_specialized + // == 1
- std::numeric_limits<Source>::digits10 * 2
- );
- #else
- BOOST_STATIC_CONSTANT(std::size_t, value = 156);
- BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
- #endif
- };
- #define BOOST_LCAST_DEF1(CharT, T) \
- template<> struct lcast_src_length<CharT, T> \
- : lcast_src_length_integral<T> \
- { static void check_coverage() {} };
- #ifdef BOOST_LCAST_NO_WCHAR_T
- #define BOOST_LCAST_DEF(T) BOOST_LCAST_DEF1(char, T)
- #else
- #define BOOST_LCAST_DEF(T) \
- BOOST_LCAST_DEF1(char, T) \
- BOOST_LCAST_DEF1(wchar_t, T)
- #endif
- BOOST_LCAST_DEF(short)
- BOOST_LCAST_DEF(unsigned short)
- BOOST_LCAST_DEF(int)
- BOOST_LCAST_DEF(unsigned int)
- BOOST_LCAST_DEF(long)
- BOOST_LCAST_DEF(unsigned long)
- #if defined(BOOST_HAS_LONG_LONG)
- BOOST_LCAST_DEF(boost::ulong_long_type)
- BOOST_LCAST_DEF(boost::long_long_type )
- #elif defined(BOOST_HAS_MS_INT64)
- BOOST_LCAST_DEF(unsigned __int64)
- BOOST_LCAST_DEF( __int64)
- #endif
- #undef BOOST_LCAST_DEF
- #undef BOOST_LCAST_DEF1
- #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
- // Helper for floating point types.
- // -1.23456789e-123456
- // ^ sign
- // ^ leading digit
- // ^ decimal point
- // ^^^^^^^^ lcast_precision<Source>::value
- // ^ "e"
- // ^ exponent sign
- // ^^^^^^ exponent (assumed 6 or less digits)
- // sign + leading digit + decimal point + "e" + exponent sign == 5
- template<class Source>
- struct lcast_src_length_floating
- {
- BOOST_STATIC_ASSERT(
- std::numeric_limits<Source>::max_exponent10 <= 999999L &&
- std::numeric_limits<Source>::min_exponent10 >= -999999L
- );
- BOOST_STATIC_CONSTANT(std::size_t, value =
- 5 + lcast_precision<Source>::value + 6
- );
- };
- template<>
- struct lcast_src_length<char,float>
- : lcast_src_length_floating<float>
- {
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<char,double>
- : lcast_src_length_floating<double>
- {
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<char,long double>
- : lcast_src_length_floating<long double>
- {
- static void check_coverage() {}
- };
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<>
- struct lcast_src_length<wchar_t,float>
- : lcast_src_length_floating<float>
- {
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<wchar_t,double>
- : lcast_src_length_floating<double>
- {
- static void check_coverage() {}
- };
- template<>
- struct lcast_src_length<wchar_t,long double>
- : lcast_src_length_floating<long double>
- {
- static void check_coverage() {}
- };
- #endif // #ifndef BOOST_LCAST_NO_WCHAR_T
- #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
- }
- namespace detail // '0' and '-' constants
- {
- template<typename CharT> struct lcast_char_constants;
- template<>
- struct lcast_char_constants<char>
- {
- BOOST_STATIC_CONSTANT(char, zero = '0');
- BOOST_STATIC_CONSTANT(char, minus = '-');
- };
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<>
- struct lcast_char_constants<wchar_t>
- {
- BOOST_STATIC_CONSTANT(wchar_t, zero = L'0');
- BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
- };
- #endif
- }
- namespace detail // lexical_streambuf_fake
- {
- struct lexical_streambuf_fake
- {
- };
- }
- namespace detail // lcast_to_unsigned
- {
- #if (defined _MSC_VER)
- # pragma warning( push )
- // C4146: unary minus operator applied to unsigned type, result still unsigned
- # pragma warning( disable : 4146 )
- #elif defined( __BORLANDC__ )
- # pragma option push -w-8041
- #endif
- template<class T>
- inline
- BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value)
- {
- typedef BOOST_DEDUCED_TYPENAME make_unsigned<T>::type result_type;
- result_type uvalue = static_cast<result_type>(value);
- return value < 0 ? -uvalue : uvalue;
- }
- #if (defined _MSC_VER)
- # pragma warning( pop )
- #elif defined( __BORLANDC__ )
- # pragma option pop
- #endif
- }
- namespace detail // lcast_put_unsigned
- {
- template<class Traits, class T, class CharT>
- CharT* lcast_put_unsigned(T n, CharT* finish)
- {
- #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
- #endif
- #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
- // TODO: use BOOST_NO_STD_LOCALE
- std::locale loc;
- typedef std::numpunct<CharT> numpunct;
- numpunct const& np = BOOST_USE_FACET(numpunct, loc);
- std::string const& grouping = np.grouping();
- std::string::size_type const grouping_size = grouping.size();
- CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;
- std::string::size_type group = 0; // current group number
- char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];
- // a) Since grouping is const, grouping[grouping.size()] returns 0.
- // b) It's safe to assume here and below that CHAR_MAX
- // is equivalent to unlimited grouping:
- #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
- #endif
- char left = last_grp_size;
- #endif
- typedef typename Traits::int_type int_type;
- CharT const czero = lcast_char_constants<CharT>::zero;
- int_type const zero = Traits::to_int_type(czero);
- do
- {
- #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
- if(left == 0)
- {
- ++group;
- if(group < grouping_size)
- {
- char const grp_size = grouping[group];
- last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
- }
- left = last_grp_size;
- --finish;
- Traits::assign(*finish, thousands_sep);
- }
- --left;
- #endif
- --finish;
- int_type const digit = static_cast<int_type>(n % 10U);
- Traits::assign(*finish, Traits::to_char_type(zero + digit));
- n /= 10;
- } while(n);
- return finish;
- }
- }
- namespace detail // stream wrapper for handling lexical conversions
- {
- template<typename Target, typename Source, typename Traits>
- class lexical_stream
- {
- private:
- typedef typename widest_char<
- typename stream_char<Target>::type,
- typename stream_char<Source>::type>::type char_type;
- typedef Traits traits_type;
- public:
- lexical_stream(char_type* = 0, char_type* = 0)
- {
- stream.unsetf(std::ios::skipws);
- lcast_set_precision(stream, (Source*)0, (Target*)0);
- }
- ~lexical_stream()
- {
- #if defined(BOOST_NO_STRINGSTREAM)
- stream.freeze(false);
- #endif
- }
- bool operator<<(const Source &input)
- {
- return !(stream << input).fail();
- }
- template<typename InputStreamable>
- bool operator>>(InputStreamable &output)
- {
- return !is_pointer<InputStreamable>::value &&
- stream >> output &&
- stream.get() ==
- #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
- // GCC 2.9x lacks std::char_traits<>::eof().
- // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
- // configurations, which do provide std::char_traits<>::eof().
-
- EOF;
- #else
- traits_type::eof();
- #endif
- }
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- bool operator>>(std::string &output)
- {
- #if defined(BOOST_NO_STRINGSTREAM)
- stream << '\0';
- #endif
- stream.str().swap(output);
- return true;
- }
- #ifndef BOOST_LCAST_NO_WCHAR_T
- bool operator>>(std::wstring &output)
- {
- stream.str().swap(output);
- return true;
- }
- #endif
- #else
- bool operator>>(std::basic_string<char_type,traits_type>& output)
- {
- stream.str().swap(output);
- return true;
- }
- template<class Alloc>
- bool operator>>(std::basic_string<char_type,traits_type,Alloc>& out)
- {
- std::basic_string<char_type,traits_type> str(stream.str());
- out.assign(str.begin(), str.end());
- return true;
- }
- #endif
- private:
- #if defined(BOOST_NO_STRINGSTREAM)
- std::strstream stream;
- #elif defined(BOOST_NO_STD_LOCALE)
- std::stringstream stream;
- #else
- std::basic_stringstream<char_type,traits_type> stream;
- #endif
- };
- }
- namespace detail // optimized stream wrapper
- {
- // String representation of Source has an upper limit.
- template< class CharT // a result of widest_char transformation
- , class Base // lexical_streambuf_fake or basic_streambuf<CharT>
- , class Traits // usually char_traits<CharT>
- >
- class lexical_stream_limited_src : public Base
- {
- // A string representation of Source is written to [start, finish).
- // Currently, it is assumed that [start, finish) is big enough
- // to hold a string representation of any Source value.
- CharT* start;
- CharT* finish;
- private:
- static void widen_and_assign(char*p, char ch)
- {
- Traits::assign(*p, ch);
- }
- #ifndef BOOST_LCAST_NO_WCHAR_T
- static void widen_and_assign(wchar_t* p, char ch)
- {
- // TODO: use BOOST_NO_STD_LOCALE
- std::locale loc;
- wchar_t w = BOOST_USE_FACET(std::ctype<wchar_t>, loc).widen(ch);
- Traits::assign(*p, w);
- }
- static void widen_and_assign(wchar_t* p, wchar_t ch)
- {
- Traits::assign(*p, ch);
- }
- static void widen_and_assign(char*, wchar_t ch); // undefined
- #endif
- template<class OutputStreamable>
- bool lcast_put(const OutputStreamable& input)
- {
- this->setp(start, finish);
- std::basic_ostream<CharT> stream(static_cast<Base*>(this));
- lcast_set_precision(stream, (OutputStreamable*)0);
- bool const result = !(stream << input).fail();
- finish = this->pptr();
- return result;
- }
- // Undefined:
- lexical_stream_limited_src(lexical_stream_limited_src const&);
- void operator=(lexical_stream_limited_src const&);
- public:
- lexical_stream_limited_src(CharT* sta, CharT* fin)
- : start(sta)
- , finish(fin)
- {}
- public: // output
- template<class Alloc>
- bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str)
- {
- start = const_cast<CharT*>(str.data());
- finish = start + str.length();
- return true;
- }
- bool operator<<(bool);
- bool operator<<(char);
- #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- bool operator<<(wchar_t);
- #endif
- bool operator<<(CharT const*);
- bool operator<<(short);
- bool operator<<(int);
- bool operator<<(long);
- bool operator<<(unsigned short);
- bool operator<<(unsigned int);
- bool operator<<(unsigned long);
- #if defined(BOOST_HAS_LONG_LONG)
- bool operator<<(boost::ulong_long_type);
- bool operator<<(boost::long_long_type );
- #elif defined(BOOST_HAS_MS_INT64)
- bool operator<<(unsigned __int64);
- bool operator<<( __int64);
- #endif
- // These three operators use ostream and streambuf.
- // lcast_streambuf_for_source<T>::value is true.
- bool operator<<(float);
- bool operator<<(double);
- bool operator<<(long double);
- public: // input
- // Generic istream-based algorithm.
- // lcast_streambuf_for_target<InputStreamable>::value is true.
- template<typename InputStreamable>
- bool operator>>(InputStreamable& output)
- {
- #if (defined _MSC_VER)
- # pragma warning( push )
- // conditional expression is constant
- # pragma warning( disable : 4127 )
- #endif
- if(is_pointer<InputStreamable>::value)
- return false;
- this->setg(start, start, finish);
- std::basic_istream<CharT> stream(static_cast<Base*>(this));
- stream.unsetf(std::ios::skipws);
- lcast_set_precision(stream, (InputStreamable*)0);
- #if (defined _MSC_VER)
- # pragma warning( pop )
- #endif
- return stream >> output &&
- stream.get() ==
- #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
- // GCC 2.9x lacks std::char_traits<>::eof().
- // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
- // configurations, which do provide std::char_traits<>::eof().
- EOF;
- #else
- Traits::eof();
- #endif
- }
- bool operator>>(CharT&);
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- // This #if is in sync with lcast_streambuf_for_target
- bool operator>>(std::string&);
- #ifndef BOOST_LCAST_NO_WCHAR_T
- bool operator>>(std::wstring&);
- #endif
- #else
- template<class Alloc>
- bool operator>>(std::basic_string<CharT,Traits,Alloc>& str)
- {
- str.assign(start, finish);
- return true;
- }
- #endif
- };
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- bool value)
- {
- typedef typename Traits::int_type int_type;
- CharT const czero = lcast_char_constants<CharT>::zero;
- int_type const zero = Traits::to_int_type(czero);
- Traits::assign(*start, Traits::to_char_type(zero + value));
- finish = start + 1;
- return true;
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- char ch)
- {
- widen_and_assign(start, ch);
- finish = start + 1;
- return true;
- }
- #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- wchar_t ch)
- {
- widen_and_assign(start, ch);
- finish = start + 1;
- return true;
- }
- #endif
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- short n)
- {
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
- if(n < 0)
- {
- --start;
- CharT const minus = lcast_char_constants<CharT>::minus;
- Traits::assign(*start, minus);
- }
- return true;
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- int n)
- {
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
- if(n < 0)
- {
- --start;
- CharT const minus = lcast_char_constants<CharT>::minus;
- Traits::assign(*start, minus);
- }
- return true;
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- long n)
- {
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
- if(n < 0)
- {
- --start;
- CharT const minus = lcast_char_constants<CharT>::minus;
- Traits::assign(*start, minus);
- }
- return true;
- }
- #if defined(BOOST_HAS_LONG_LONG)
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- boost::long_long_type n)
- {
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
- if(n < 0)
- {
- --start;
- CharT const minus = lcast_char_constants<CharT>::minus;
- Traits::assign(*start, minus);
- }
- return true;
- }
- #elif defined(BOOST_HAS_MS_INT64)
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- __int64 n)
- {
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
- if(n < 0)
- {
- --start;
- CharT const minus = lcast_char_constants<CharT>::minus;
- Traits::assign(*start, minus);
- }
- return true;
- }
- #endif
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- unsigned short n)
- {
- start = lcast_put_unsigned<Traits>(n, finish);
- return true;
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- unsigned int n)
- {
- start = lcast_put_unsigned<Traits>(n, finish);
- return true;
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- unsigned long n)
- {
- start = lcast_put_unsigned<Traits>(n, finish);
- return true;
- }
- #if defined(BOOST_HAS_LONG_LONG)
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- boost::ulong_long_type n)
- {
- start = lcast_put_unsigned<Traits>(n, finish);
- return true;
- }
- #elif defined(BOOST_HAS_MS_INT64)
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- unsigned __int64 n)
- {
- start = lcast_put_unsigned<Traits>(n, finish);
- return true;
- }
- #endif
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- float val)
- {
- return this->lcast_put(val);
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- double val)
- {
- return this->lcast_put(val);
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- long double val)
- {
- return this->lcast_put(val);
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
- CharT const* str)
- {
- start = const_cast<CharT*>(str);
- finish = start + Traits::length(str);
- return true;
- }
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
- CharT& output)
- {
- bool const ok = (finish - start == 1);
- if(ok)
- Traits::assign(output, *start);
- return ok;
- }
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
- std::string& str)
- {
- str.assign(start, finish);
- return true;
- }
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<typename CharT, class Base, class Traits>
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
- std::wstring& str)
- {
- str.assign(start, finish);
- return true;
- }
- #endif
- #endif
- }
- namespace detail // lcast_streambuf_for_source
- {
- // Returns true if optimized stream wrapper needs ostream for writing.
- template<class Source>
- struct lcast_streambuf_for_source
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- template<>
- struct lcast_streambuf_for_source<float>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
- template<>
- struct lcast_streambuf_for_source<double>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-
- template<>
- struct lcast_streambuf_for_source<long double>
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- }
- namespace detail // lcast_streambuf_for_target
- {
- // Returns true if optimized stream wrapper needs istream for reading.
- template<class Target>
- struct lcast_streambuf_for_target
- {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- template<>
- struct lcast_streambuf_for_target<char>
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- template<>
- struct lcast_streambuf_for_target<wchar_t>
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- #endif
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- template<class Traits, class Alloc>
- struct lcast_streambuf_for_target<
- std::basic_string<char,Traits,Alloc> >
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<class Traits, class Alloc>
- struct lcast_streambuf_for_target<
- std::basic_string<wchar_t,Traits,Alloc> >
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- #endif
- #else
- template<>
- struct lcast_streambuf_for_target<std::string>
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- #ifndef BOOST_LCAST_NO_WCHAR_T
- template<>
- struct lcast_streambuf_for_target<std::wstring>
- {
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- #endif
- #endif
- }
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- // call-by-const reference version
- namespace detail
- {
- template<class T>
- struct array_to_pointer_decay
- {
- typedef T type;
- };
- template<class T, std::size_t N>
- struct array_to_pointer_decay<T[N]>
- {
- typedef const T * type;
- };
- template< typename Target
- , typename Source
- , bool Unlimited // string representation of Source is unlimited
- , typename CharT
- >
- Target lexical_cast(
- BOOST_DEDUCED_TYPENAME boost::call_traits<Source>::param_type arg,
- CharT* buf, std::size_t src_len)
- {
- typedef BOOST_DEDUCED_TYPENAME
- deduce_char_traits<CharT,Target,Source>::type traits;
- typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
- lcast_streambuf_for_target<Target>::value ||
- lcast_streambuf_for_source<Source>::value
- , std::basic_streambuf<CharT>
- , lexical_streambuf_fake
- >::type base;
- BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
- Unlimited
- , detail::lexical_stream<Target,Source,traits>
- , detail::lexical_stream_limited_src<CharT,base,traits>
- >::type interpreter(buf, buf + src_len);
- // The original form, reproduced below, is more elegant
- // but yields a spurious C4701 warning ("possible use of
- // "result" before initialization") with VC7.1 (/W4).
- //
- // Target result;
- //
- // if(!(interpreter << arg && interpreter >> result))
- // throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
- // return result;
- if(interpreter << arg) {
- Target result;
- if (interpreter >> result)
- return result;
- }
- #ifndef BOOST_NO_TYPEID
- throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
- #else
- throw_exception(bad_lexical_cast());
- #endif
- return Target(); // normally never reached (throw_exception)
- }
- }
- template<typename Target, typename Source>
- inline Target lexical_cast(const Source &arg)
- {
- typedef typename detail::array_to_pointer_decay<Source>::type src;
- typedef typename detail::widest_char<
- typename detail::stream_char<Target>::type
- , typename detail::stream_char<src>::type
- >::type char_type;
- typedef detail::lcast_src_length<char_type, src> lcast_src_length;
- std::size_t const src_len = lcast_src_length::value;
- char_type buf[src_len + 1];
- lcast_src_length::check_coverage();
- return detail::lexical_cast<Target, src, !src_len>(arg, buf, src_len);
- }
- #else
- // call-by-value fallback version (deprecated)
- template<typename Target, typename Source>
- Target lexical_cast(Source arg)
- {
- typedef typename detail::widest_char<
- BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type
- , BOOST_DEDUCED_TYPENAME detail::stream_char<Source>::type
- >::type char_type;
- typedef std::char_traits<char_type> traits;
- detail::lexical_stream<Target, Source, traits> interpreter;
- Target result;
- if(!(interpreter << arg && interpreter >> result))
- #ifndef BOOST_NO_TYPEID
- throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
- #else
- throw_exception(bad_lexical_cast());
- #endif
- return result;
- }
- #endif
- }
- // Copyright Kevlin Henney, 2000-2005.
- // Copyright Alexander Nasonov, 2006-2007.
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #undef BOOST_LCAST_NO_WCHAR_T
- #endif
|