1 #ifndef BOOST_LEXICAL_CAST_INCLUDED
\r
2 #define BOOST_LEXICAL_CAST_INCLUDED
\r
4 // Boost lexical_cast.hpp header -------------------------------------------//
\r
6 // See http://www.boost.org/libs/conversion for documentation.
\r
7 // See end of this header for rights and permissions.
\r
9 // what: lexical_cast custom keyword cast
\r
10 // who: contributed by Kevlin Henney,
\r
11 // enhanced with contributions from Terje Slettebo,
\r
12 // with additional fixes and suggestions from Gennaro Prota,
\r
13 // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
\r
14 // Alexander Nasonov and other Boosters
\r
15 // when: November 2000, March 2003, June 2005, June 2006
\r
22 #include <exception>
\r
23 #include <boost/config.hpp>
\r
24 #include <boost/limits.hpp>
\r
25 #include <boost/mpl/if.hpp>
\r
26 #include <boost/throw_exception.hpp>
\r
27 #include <boost/type_traits/is_pointer.hpp>
\r
28 #include <boost/type_traits/make_unsigned.hpp>
\r
29 #include <boost/call_traits.hpp>
\r
30 #include <boost/static_assert.hpp>
\r
31 #include <boost/detail/lcast_precision.hpp>
\r
32 #include <boost/detail/workaround.hpp>
\r
34 #ifndef BOOST_NO_STD_LOCALE
\r
38 #ifdef BOOST_NO_STRINGSTREAM
\r
39 #include <strstream>
\r
44 #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
\r
45 #define BOOST_LCAST_NO_WCHAR_T
\r
48 #ifdef BOOST_NO_TYPEID
\r
49 #define BOOST_LCAST_THROW_BAD_CAST(S, T) throw_exception(bad_lexical_cast())
\r
51 #define BOOST_LCAST_THROW_BAD_CAST(Source, Target) \
\r
52 throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)))
\r
57 // exception used to indicate runtime lexical_cast failure
\r
58 class bad_lexical_cast : public std::bad_cast
\r
60 #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
\r
61 // under bcc32 5.5.1 bad_cast doesn't derive from exception
\r
62 , public std::exception
\r
67 bad_lexical_cast() :
\r
68 #ifndef BOOST_NO_TYPEID
\r
69 source(&typeid(void)), target(&typeid(void))
\r
71 source(0), target(0) // this breaks getters
\r
77 const std::type_info &source_type_arg,
\r
78 const std::type_info &target_type_arg) :
\r
79 source(&source_type_arg), target(&target_type_arg)
\r
83 const std::type_info &source_type() const
\r
87 const std::type_info &target_type() const
\r
92 virtual const char *what() const throw()
\r
94 return "bad lexical cast: "
\r
95 "source type value could not be interpreted as target";
\r
97 virtual ~bad_lexical_cast() throw()
\r
101 const std::type_info *source;
\r
102 const std::type_info *target;
\r
105 namespace detail // selectors for choosing stream character type
\r
107 template<typename Type>
\r
113 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
114 template<class CharT, class Traits, class Alloc>
\r
115 struct stream_char< std::basic_string<CharT,Traits,Alloc> >
\r
117 typedef CharT type;
\r
121 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
122 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
\r
124 struct stream_char<wchar_t>
\r
126 typedef wchar_t type;
\r
131 struct stream_char<wchar_t *>
\r
133 typedef wchar_t type;
\r
137 struct stream_char<const wchar_t *>
\r
139 typedef wchar_t type;
\r
142 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
144 struct stream_char<std::wstring>
\r
146 typedef wchar_t type;
\r
151 template<typename TargetChar, typename SourceChar>
\r
154 typedef TargetChar type;
\r
158 struct widest_char<char, wchar_t>
\r
160 typedef wchar_t type;
\r
164 namespace detail // deduce_char_traits template
\r
166 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
167 template<class CharT, class Target, class Source>
\r
168 struct deduce_char_traits
\r
170 typedef std::char_traits<CharT> type;
\r
173 template<class CharT, class Traits, class Alloc, class Source>
\r
174 struct deduce_char_traits< CharT
\r
175 , std::basic_string<CharT,Traits,Alloc>
\r
179 typedef Traits type;
\r
182 template<class CharT, class Target, class Traits, class Alloc>
\r
183 struct deduce_char_traits< CharT
\r
185 , std::basic_string<CharT,Traits,Alloc>
\r
188 typedef Traits type;
\r
191 template<class CharT, class Traits, class Alloc1, class Alloc2>
\r
192 struct deduce_char_traits< CharT
\r
193 , std::basic_string<CharT,Traits,Alloc1>
\r
194 , std::basic_string<CharT,Traits,Alloc2>
\r
197 typedef Traits type;
\r
202 namespace detail // lcast_src_length
\r
204 // Return max. length of string representation of Source;
\r
205 // 0 if unlimited (with exceptions for some types, see below).
\r
206 // Values with limited string representation are placed to
\r
207 // the buffer locally defined in lexical_cast function.
\r
208 // 1 is returned for few types such as CharT const* or
\r
209 // std::basic_string<CharT> that already have an internal
\r
210 // buffer ready to be reused by lexical_stream_limited_src.
\r
211 // Each specialization should have a correspondent operator<<
\r
212 // defined in lexical_stream_limited_src.
\r
213 template< class CharT // A result of widest_char transformation.
\r
214 , class Source // Source type of lexical_cast.
\r
216 struct lcast_src_length
\r
218 BOOST_STATIC_CONSTANT(std::size_t, value = 0);
\r
219 // To check coverage, build the test with
\r
220 // bjam --v2 profile optimization=off
\r
221 static void check_coverage() {}
\r
225 struct lcast_src_length<char, bool>
\r
227 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
228 static void check_coverage() {}
\r
232 struct lcast_src_length<char, char>
\r
234 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
235 static void check_coverage() {}
\r
238 // No specializations for:
\r
239 // lcast_src_length<char, signed char>
\r
240 // lcast_src_length<char, unsigned char>
\r
241 // lcast_src_length<char, signed char*>
\r
242 // lcast_src_length<char, unsigned char*>
\r
243 // lcast_src_length<char, signed char const*>
\r
244 // lcast_src_length<char, unsigned char const*>
\r
246 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
248 struct lcast_src_length<wchar_t, bool>
\r
250 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
251 static void check_coverage() {}
\r
255 struct lcast_src_length<wchar_t, char>
\r
257 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
258 static void check_coverage() {}
\r
261 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
\r
263 struct lcast_src_length<wchar_t, wchar_t>
\r
265 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
266 static void check_coverage() {}
\r
272 struct lcast_src_length<char, char const*>
\r
274 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
275 static void check_coverage() {}
\r
279 struct lcast_src_length<char, char*>
\r
281 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
282 static void check_coverage() {}
\r
285 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
287 struct lcast_src_length<wchar_t, wchar_t const*>
\r
289 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
290 static void check_coverage() {}
\r
294 struct lcast_src_length<wchar_t, wchar_t*>
\r
296 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
297 static void check_coverage() {}
\r
301 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
302 template<class CharT, class Traits, class Alloc>
\r
303 struct lcast_src_length< CharT, std::basic_string<CharT,Traits,Alloc> >
\r
305 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
306 static void check_coverage() {}
\r
310 struct lcast_src_length< char, std::basic_string<char> >
\r
312 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
313 static void check_coverage() {}
\r
316 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
318 struct lcast_src_length< wchar_t, std::basic_string<wchar_t> >
\r
320 BOOST_STATIC_CONSTANT(std::size_t, value = 1);
\r
321 static void check_coverage() {}
\r
326 // Helper for integral types.
\r
327 // Notes on length calculation:
\r
328 // Max length for 32bit int with grouping "\1" and thousands_sep ',':
\r
329 // "-2,1,4,7,4,8,3,6,4,7"
\r
331 // ^ - 1 digit not counted by digits10
\r
332 // ^^^^^^^^^^^^^^^^^^ - digits10 * 2
\r
334 // Constant is_specialized is used instead of constant 1
\r
335 // to prevent buffer overflow in a rare case when
\r
336 // <boost/limits.hpp> doesn't add missing specialization for
\r
337 // numeric_limits<T> for some integral type T.
\r
338 // When is_specialized is false, the whole expression is 0.
\r
339 template<class Source>
\r
340 struct lcast_src_length_integral
\r
342 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
\r
343 BOOST_STATIC_CONSTANT(std::size_t, value =
\r
344 std::numeric_limits<Source>::is_signed +
\r
345 std::numeric_limits<Source>::is_specialized + // == 1
\r
346 std::numeric_limits<Source>::digits10 * 2
\r
349 BOOST_STATIC_CONSTANT(std::size_t, value = 156);
\r
350 BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
\r
354 #define BOOST_LCAST_DEF1(CharT, T) \
\r
355 template<> struct lcast_src_length<CharT, T> \
\r
356 : lcast_src_length_integral<T> \
\r
357 { static void check_coverage() {} };
\r
359 #ifdef BOOST_LCAST_NO_WCHAR_T
\r
360 #define BOOST_LCAST_DEF(T) BOOST_LCAST_DEF1(char, T)
\r
362 #define BOOST_LCAST_DEF(T) \
\r
363 BOOST_LCAST_DEF1(char, T) \
\r
364 BOOST_LCAST_DEF1(wchar_t, T)
\r
367 BOOST_LCAST_DEF(short)
\r
368 BOOST_LCAST_DEF(unsigned short)
\r
369 BOOST_LCAST_DEF(int)
\r
370 BOOST_LCAST_DEF(unsigned int)
\r
371 BOOST_LCAST_DEF(long)
\r
372 BOOST_LCAST_DEF(unsigned long)
\r
373 #if defined(BOOST_HAS_LONG_LONG)
\r
374 BOOST_LCAST_DEF(boost::ulong_long_type)
\r
375 BOOST_LCAST_DEF(boost::long_long_type )
\r
376 #elif defined(BOOST_HAS_MS_INT64)
\r
377 BOOST_LCAST_DEF(unsigned __int64)
\r
378 BOOST_LCAST_DEF( __int64)
\r
381 #undef BOOST_LCAST_DEF
\r
382 #undef BOOST_LCAST_DEF1
\r
384 #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
\r
385 // Helper for floating point types.
\r
386 // -1.23456789e-123456
\r
389 // ^ decimal point
\r
390 // ^^^^^^^^ lcast_precision<Source>::value
\r
393 // ^^^^^^ exponent (assumed 6 or less digits)
\r
394 // sign + leading digit + decimal point + "e" + exponent sign == 5
\r
395 template<class Source>
\r
396 struct lcast_src_length_floating
\r
398 BOOST_STATIC_ASSERT(
\r
399 std::numeric_limits<Source>::max_exponent10 <= 999999L &&
\r
400 std::numeric_limits<Source>::min_exponent10 >= -999999L
\r
402 BOOST_STATIC_CONSTANT(std::size_t, value =
\r
403 5 + lcast_precision<Source>::value + 6
\r
408 struct lcast_src_length<char,float>
\r
409 : lcast_src_length_floating<float>
\r
411 static void check_coverage() {}
\r
415 struct lcast_src_length<char,double>
\r
416 : lcast_src_length_floating<double>
\r
418 static void check_coverage() {}
\r
422 struct lcast_src_length<char,long double>
\r
423 : lcast_src_length_floating<long double>
\r
425 static void check_coverage() {}
\r
428 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
430 struct lcast_src_length<wchar_t,float>
\r
431 : lcast_src_length_floating<float>
\r
433 static void check_coverage() {}
\r
437 struct lcast_src_length<wchar_t,double>
\r
438 : lcast_src_length_floating<double>
\r
440 static void check_coverage() {}
\r
444 struct lcast_src_length<wchar_t,long double>
\r
445 : lcast_src_length_floating<long double>
\r
447 static void check_coverage() {}
\r
450 #endif // #ifndef BOOST_LCAST_NO_WCHAR_T
\r
451 #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
\r
454 namespace detail // '0' and '-' constants
\r
456 template<typename CharT> struct lcast_char_constants;
\r
459 struct lcast_char_constants<char>
\r
461 BOOST_STATIC_CONSTANT(char, zero = '0');
\r
462 BOOST_STATIC_CONSTANT(char, minus = '-');
\r
465 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
467 struct lcast_char_constants<wchar_t>
\r
469 BOOST_STATIC_CONSTANT(wchar_t, zero = L'0');
\r
470 BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
\r
475 namespace detail // lexical_streambuf_fake
\r
477 struct lexical_streambuf_fake
\r
482 namespace detail // lcast_to_unsigned
\r
484 #if (defined _MSC_VER)
\r
485 # pragma warning( push )
\r
486 // C4146: unary minus operator applied to unsigned type, result still unsigned
\r
487 # pragma warning( disable : 4146 )
\r
488 #elif defined( __BORLANDC__ )
\r
489 # pragma option push -w-8041
\r
493 BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value)
\r
495 typedef BOOST_DEDUCED_TYPENAME make_unsigned<T>::type result_type;
\r
496 result_type uvalue = static_cast<result_type>(value);
\r
497 return value < 0 ? -uvalue : uvalue;
\r
499 #if (defined _MSC_VER)
\r
500 # pragma warning( pop )
\r
501 #elif defined( __BORLANDC__ )
\r
502 # pragma option pop
\r
506 namespace detail // lcast_put_unsigned
\r
508 template<class Traits, class T, class CharT>
\r
509 CharT* lcast_put_unsigned(T n, CharT* finish)
\r
511 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
\r
512 BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
\r
515 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
\r
516 // TODO: use BOOST_NO_STD_LOCALE
\r
518 typedef std::numpunct<CharT> numpunct;
\r
519 numpunct const& np = BOOST_USE_FACET(numpunct, loc);
\r
520 std::string const& grouping = np.grouping();
\r
521 std::string::size_type const grouping_size = grouping.size();
\r
522 CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;
\r
523 std::string::size_type group = 0; // current group number
\r
524 char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];
\r
525 // a) Since grouping is const, grouping[grouping.size()] returns 0.
\r
526 // b) It's safe to assume here and below that CHAR_MAX
\r
527 // is equivalent to unlimited grouping:
\r
528 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
\r
529 BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
\r
532 char left = last_grp_size;
\r
535 typedef typename Traits::int_type int_type;
\r
536 CharT const czero = lcast_char_constants<CharT>::zero;
\r
537 int_type const zero = Traits::to_int_type(czero);
\r
541 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
\r
545 if(group < grouping_size)
\r
547 char const grp_size = grouping[group];
\r
548 last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
\r
551 left = last_grp_size;
\r
553 Traits::assign(*finish, thousands_sep);
\r
560 int_type const digit = static_cast<int_type>(n % 10U);
\r
561 Traits::assign(*finish, Traits::to_char_type(zero + digit));
\r
569 namespace detail // stream wrapper for handling lexical conversions
\r
571 template<typename Target, typename Source, typename Traits>
\r
572 class lexical_stream
\r
575 typedef typename widest_char<
\r
576 typename stream_char<Target>::type,
\r
577 typename stream_char<Source>::type>::type char_type;
\r
579 typedef Traits traits_type;
\r
582 lexical_stream(char_type* = 0, char_type* = 0)
\r
584 stream.unsetf(std::ios::skipws);
\r
585 lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
\r
589 #if defined(BOOST_NO_STRINGSTREAM)
\r
590 stream.freeze(false);
\r
593 bool operator<<(const Source &input)
\r
595 return !(stream << input).fail();
\r
597 template<typename InputStreamable>
\r
598 bool operator>>(InputStreamable &output)
\r
600 return !is_pointer<InputStreamable>::value &&
\r
601 stream >> output &&
\r
603 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
\r
604 // GCC 2.9x lacks std::char_traits<>::eof().
\r
605 // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
\r
606 // configurations, which do provide std::char_traits<>::eof().
\r
610 traits_type::eof();
\r
614 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
616 bool operator>>(std::string &output)
\r
618 #if defined(BOOST_NO_STRINGSTREAM)
\r
621 stream.str().swap(output);
\r
624 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
625 bool operator>>(std::wstring &output)
\r
627 stream.str().swap(output);
\r
633 bool operator>>(std::basic_string<char_type,traits_type>& output)
\r
635 stream.str().swap(output);
\r
639 template<class Alloc>
\r
640 bool operator>>(std::basic_string<char_type,traits_type,Alloc>& out)
\r
642 std::basic_string<char_type,traits_type> str(stream.str());
\r
643 out.assign(str.begin(), str.end());
\r
648 #if defined(BOOST_NO_STRINGSTREAM)
\r
649 std::strstream stream;
\r
650 #elif defined(BOOST_NO_STD_LOCALE)
\r
651 std::stringstream stream;
\r
653 std::basic_stringstream<char_type,traits_type> stream;
\r
658 namespace detail // optimized stream wrapper
\r
660 // String representation of Source has an upper limit.
\r
661 template< class CharT // a result of widest_char transformation
\r
662 , class Base // lexical_streambuf_fake or basic_streambuf<CharT>
\r
663 , class Traits // usually char_traits<CharT>
\r
665 class lexical_stream_limited_src : public Base
\r
667 // A string representation of Source is written to [start, finish).
\r
668 // Currently, it is assumed that [start, finish) is big enough
\r
669 // to hold a string representation of any Source value.
\r
675 static void widen_and_assign(char*p, char ch)
\r
677 Traits::assign(*p, ch);
\r
680 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
681 static void widen_and_assign(wchar_t* p, char ch)
\r
683 // TODO: use BOOST_NO_STD_LOCALE
\r
685 wchar_t w = BOOST_USE_FACET(std::ctype<wchar_t>, loc).widen(ch);
\r
686 Traits::assign(*p, w);
\r
689 static void widen_and_assign(wchar_t* p, wchar_t ch)
\r
691 Traits::assign(*p, ch);
\r
694 static void widen_and_assign(char*, wchar_t ch); // undefined
\r
697 template<class OutputStreamable>
\r
698 bool lcast_put(const OutputStreamable& input)
\r
700 this->setp(start, finish);
\r
701 std::basic_ostream<CharT> stream(static_cast<Base*>(this));
\r
702 lcast_set_precision(stream, static_cast<OutputStreamable*>(0));
\r
703 bool const result = !(stream << input).fail();
\r
704 finish = this->pptr();
\r
709 lexical_stream_limited_src(lexical_stream_limited_src const&);
\r
710 void operator=(lexical_stream_limited_src const&);
\r
714 lexical_stream_limited_src(CharT* sta, CharT* fin)
\r
721 template<class Alloc>
\r
722 bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str)
\r
724 start = const_cast<CharT*>(str.data());
\r
725 finish = start + str.length();
\r
729 bool operator<<(bool);
\r
730 bool operator<<(char);
\r
731 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
\r
732 bool operator<<(wchar_t);
\r
734 bool operator<<(CharT const*);
\r
735 bool operator<<(short);
\r
736 bool operator<<(int);
\r
737 bool operator<<(long);
\r
738 bool operator<<(unsigned short);
\r
739 bool operator<<(unsigned int);
\r
740 bool operator<<(unsigned long);
\r
741 #if defined(BOOST_HAS_LONG_LONG)
\r
742 bool operator<<(boost::ulong_long_type);
\r
743 bool operator<<(boost::long_long_type );
\r
744 #elif defined(BOOST_HAS_MS_INT64)
\r
745 bool operator<<(unsigned __int64);
\r
746 bool operator<<( __int64);
\r
748 // These three operators use ostream and streambuf.
\r
749 // lcast_streambuf_for_source<T>::value is true.
\r
750 bool operator<<(float);
\r
751 bool operator<<(double);
\r
752 bool operator<<(long double);
\r
756 // Generic istream-based algorithm.
\r
757 // lcast_streambuf_for_target<InputStreamable>::value is true.
\r
758 template<typename InputStreamable>
\r
759 bool operator>>(InputStreamable& output)
\r
761 #if (defined _MSC_VER)
\r
762 # pragma warning( push )
\r
763 // conditional expression is constant
\r
764 # pragma warning( disable : 4127 )
\r
766 if(is_pointer<InputStreamable>::value)
\r
769 this->setg(start, start, finish);
\r
770 std::basic_istream<CharT> stream(static_cast<Base*>(this));
\r
771 stream.unsetf(std::ios::skipws);
\r
772 lcast_set_precision(stream, static_cast<InputStreamable*>(0));
\r
773 #if (defined _MSC_VER)
\r
774 # pragma warning( pop )
\r
776 return stream >> output &&
\r
778 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
\r
779 // GCC 2.9x lacks std::char_traits<>::eof().
\r
780 // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
\r
781 // configurations, which do provide std::char_traits<>::eof().
\r
789 bool operator>>(CharT&);
\r
791 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
792 // This #if is in sync with lcast_streambuf_for_target
\r
794 bool operator>>(std::string&);
\r
796 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
797 bool operator>>(std::wstring&);
\r
801 template<class Alloc>
\r
802 bool operator>>(std::basic_string<CharT,Traits,Alloc>& str)
\r
804 str.assign(start, finish);
\r
810 template<typename CharT, class Base, class Traits>
\r
811 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
814 typedef typename Traits::int_type int_type;
\r
815 CharT const czero = lcast_char_constants<CharT>::zero;
\r
816 int_type const zero = Traits::to_int_type(czero);
\r
817 Traits::assign(*start, Traits::to_char_type(zero + value));
\r
818 finish = start + 1;
\r
822 template<typename CharT, class Base, class Traits>
\r
823 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
826 widen_and_assign(start, ch);
\r
827 finish = start + 1;
\r
831 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
\r
832 template<typename CharT, class Base, class Traits>
\r
833 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
836 widen_and_assign(start, ch);
\r
837 finish = start + 1;
\r
842 template<typename CharT, class Base, class Traits>
\r
843 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
846 start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
\r
850 CharT const minus = lcast_char_constants<CharT>::minus;
\r
851 Traits::assign(*start, minus);
\r
856 template<typename CharT, class Base, class Traits>
\r
857 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
860 start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
\r
864 CharT const minus = lcast_char_constants<CharT>::minus;
\r
865 Traits::assign(*start, minus);
\r
870 template<typename CharT, class Base, class Traits>
\r
871 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
874 start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
\r
878 CharT const minus = lcast_char_constants<CharT>::minus;
\r
879 Traits::assign(*start, minus);
\r
884 #if defined(BOOST_HAS_LONG_LONG)
\r
885 template<typename CharT, class Base, class Traits>
\r
886 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
887 boost::long_long_type n)
\r
889 start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
\r
893 CharT const minus = lcast_char_constants<CharT>::minus;
\r
894 Traits::assign(*start, minus);
\r
898 #elif defined(BOOST_HAS_MS_INT64)
\r
899 template<typename CharT, class Base, class Traits>
\r
900 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
903 start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
\r
907 CharT const minus = lcast_char_constants<CharT>::minus;
\r
908 Traits::assign(*start, minus);
\r
914 template<typename CharT, class Base, class Traits>
\r
915 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
918 start = lcast_put_unsigned<Traits>(n, finish);
\r
922 template<typename CharT, class Base, class Traits>
\r
923 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
926 start = lcast_put_unsigned<Traits>(n, finish);
\r
930 template<typename CharT, class Base, class Traits>
\r
931 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
934 start = lcast_put_unsigned<Traits>(n, finish);
\r
938 #if defined(BOOST_HAS_LONG_LONG)
\r
939 template<typename CharT, class Base, class Traits>
\r
940 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
941 boost::ulong_long_type n)
\r
943 start = lcast_put_unsigned<Traits>(n, finish);
\r
946 #elif defined(BOOST_HAS_MS_INT64)
\r
947 template<typename CharT, class Base, class Traits>
\r
948 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
949 unsigned __int64 n)
\r
951 start = lcast_put_unsigned<Traits>(n, finish);
\r
956 template<typename CharT, class Base, class Traits>
\r
957 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
960 return this->lcast_put(val);
\r
963 template<typename CharT, class Base, class Traits>
\r
964 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
967 return this->lcast_put(val);
\r
970 template<typename CharT, class Base, class Traits>
\r
971 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
974 return this->lcast_put(val);
\r
977 template<typename CharT, class Base, class Traits>
\r
978 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
\r
981 start = const_cast<CharT*>(str);
\r
982 finish = start + Traits::length(str);
\r
986 template<typename CharT, class Base, class Traits>
\r
987 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
\r
990 bool const ok = (finish - start == 1);
\r
992 Traits::assign(output, *start);
\r
996 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
997 template<typename CharT, class Base, class Traits>
\r
998 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
\r
1001 str.assign(start, finish);
\r
1005 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
1006 template<typename CharT, class Base, class Traits>
\r
1007 inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
\r
1008 std::wstring& str)
\r
1010 str.assign(start, finish);
\r
1017 namespace detail // lcast_streambuf_for_source
\r
1019 // Returns true if optimized stream wrapper needs ostream for writing.
\r
1020 template<class Source>
\r
1021 struct lcast_streambuf_for_source
\r
1023 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1027 struct lcast_streambuf_for_source<float>
\r
1029 BOOST_STATIC_CONSTANT(bool, value = true);
\r
1033 struct lcast_streambuf_for_source<double>
\r
1035 BOOST_STATIC_CONSTANT(bool, value = true);
\r
1039 struct lcast_streambuf_for_source<long double>
\r
1041 BOOST_STATIC_CONSTANT(bool, value = true);
\r
1045 namespace detail // lcast_streambuf_for_target
\r
1047 // Returns true if optimized stream wrapper needs istream for reading.
\r
1048 template<class Target>
\r
1049 struct lcast_streambuf_for_target
\r
1051 BOOST_STATIC_CONSTANT(bool, value = true);
\r
1055 struct lcast_streambuf_for_target<char>
\r
1057 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1060 #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
\r
1062 struct lcast_streambuf_for_target<wchar_t>
\r
1064 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1068 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
1069 template<class Traits, class Alloc>
\r
1070 struct lcast_streambuf_for_target<
\r
1071 std::basic_string<char,Traits,Alloc> >
\r
1073 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1076 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
1077 template<class Traits, class Alloc>
\r
1078 struct lcast_streambuf_for_target<
\r
1079 std::basic_string<wchar_t,Traits,Alloc> >
\r
1081 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1086 struct lcast_streambuf_for_target<std::string>
\r
1088 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1091 #ifndef BOOST_LCAST_NO_WCHAR_T
\r
1093 struct lcast_streambuf_for_target<std::wstring>
\r
1095 BOOST_STATIC_CONSTANT(bool, value = false);
\r
1101 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
1103 // call-by-const reference version
\r
1108 struct array_to_pointer_decay
\r
1113 template<class T, std::size_t N>
\r
1114 struct array_to_pointer_decay<T[N]>
\r
1116 typedef const T * type;
\r
1119 #if (defined _MSC_VER)
\r
1120 # pragma warning( push )
\r
1121 # pragma warning( disable : 4701 ) // possible use of ... before initialization
\r
1122 # pragma warning( disable : 4702 ) // unreachable code
\r
1125 template< typename Target
\r
1127 , bool Unlimited // string representation of Source is unlimited
\r
1130 Target lexical_cast(
\r
1131 BOOST_DEDUCED_TYPENAME boost::call_traits<Source>::param_type arg,
\r
1132 CharT* buf, std::size_t src_len)
\r
1134 typedef BOOST_DEDUCED_TYPENAME
\r
1135 deduce_char_traits<CharT,Target,Source>::type traits;
\r
1137 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
\r
1138 lcast_streambuf_for_target<Target>::value ||
\r
1139 lcast_streambuf_for_source<Source>::value
\r
1140 , std::basic_streambuf<CharT>
\r
1141 , lexical_streambuf_fake
\r
1144 BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
\r
1146 , detail::lexical_stream<Target,Source,traits>
\r
1147 , detail::lexical_stream_limited_src<CharT,base,traits>
\r
1148 >::type interpreter(buf, buf + src_len);
\r
1151 if(!(interpreter << arg && interpreter >> result))
\r
1152 BOOST_LCAST_THROW_BAD_CAST(Source, Target);
\r
1155 #if (defined _MSC_VER)
\r
1156 # pragma warning( pop )
\r
1160 template<typename Target, typename Source>
\r
1161 inline Target lexical_cast(const Source &arg)
\r
1163 typedef typename detail::array_to_pointer_decay<Source>::type src;
\r
1165 typedef typename detail::widest_char<
\r
1166 typename detail::stream_char<Target>::type
\r
1167 , typename detail::stream_char<src>::type
\r
1168 >::type char_type;
\r
1170 typedef detail::lcast_src_length<char_type, src> lcast_src_length;
\r
1171 std::size_t const src_len = lcast_src_length::value;
\r
1172 char_type buf[src_len + 1];
\r
1173 lcast_src_length::check_coverage();
\r
1174 return detail::lexical_cast<Target, src, !src_len>(arg, buf, src_len);
\r
1179 // call-by-value fallback version (deprecated)
\r
1181 template<typename Target, typename Source>
\r
1182 Target lexical_cast(Source arg)
\r
1184 typedef typename detail::widest_char<
\r
1185 BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type
\r
1186 , BOOST_DEDUCED_TYPENAME detail::stream_char<Source>::type
\r
1187 >::type char_type;
\r
1189 typedef std::char_traits<char_type> traits;
\r
1190 detail::lexical_stream<Target, Source, traits> interpreter;
\r
1193 if(!(interpreter << arg && interpreter >> result))
\r
1194 #ifndef BOOST_NO_TYPEID
\r
1195 throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
\r
1197 throw_exception(bad_lexical_cast());
\r
1205 // Copyright Kevlin Henney, 2000-2005.
\r
1206 // Copyright Alexander Nasonov, 2006-2007.
\r
1208 // Distributed under the Boost Software License, Version 1.0. (See
\r
1209 // accompanying file LICENSE_1_0.txt or copy at
\r
1210 // http://www.boost.org/LICENSE_1_0.txt)
\r
1212 #undef BOOST_LCAST_NO_WCHAR_T
\r