diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) |
commit | f53a1ef582494458301b97bf6e546be52d7ff7e8 (patch) | |
tree | 7571b5cbcbd8a8f1dd1c966c9045b6cb69f0e295 /3rdParty/Boost/src/boost/lexical_cast.hpp | |
parent | 638345680d72ca6acaf123f2c8c1c391f696e371 (diff) | |
download | swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.zip swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.tar.bz2 |
Moving submodule contents back.
Diffstat (limited to '3rdParty/Boost/src/boost/lexical_cast.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/lexical_cast.hpp | 1216 |
1 files changed, 1216 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/lexical_cast.hpp b/3rdParty/Boost/src/boost/lexical_cast.hpp new file mode 100644 index 0000000..0da0d3d --- /dev/null +++ b/3rdParty/Boost/src/boost/lexical_cast.hpp @@ -0,0 +1,1216 @@ +#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 |