New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
lexical_cast.hpp in vendors/XIOS/current/extern/boost/include/boost – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/lexical_cast.hpp @ 3408

Last change on this file since 3408 was 3408, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

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