Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / lexical_cast.hpp
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 for most recent version including 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 Slettebø,
12 //        with additional fixes and suggestions from Gennaro Prota,
13 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
14 //        and other Boosters
15 // when:  November 2000, March 2003, June 2005
16
17 #include <cstddef>
18 #include <string>
19 #include <typeinfo>
20 #include <boost/config.hpp>
21 #include <boost/limits.hpp>
22 #include <boost/throw_exception.hpp>
23 #include <boost/type_traits/is_pointer.hpp>
24
25 #ifdef BOOST_NO_STRINGSTREAM
26 #include <strstream>
27 #else
28 #include <sstream>
29 #endif
30
31 #if defined(BOOST_NO_STRINGSTREAM) || \
32     defined(BOOST_NO_STD_WSTRING) || \
33     defined(BOOST_NO_STD_LOCALE) 
34 #define DISABLE_WIDE_CHAR_SUPPORT
35 #endif
36
37 namespace boost
38 {
39     // exception used to indicate runtime lexical_cast failure
40     class bad_lexical_cast : public std::bad_cast
41     {
42     public:
43         bad_lexical_cast() :
44         source(&typeid(void)), target(&typeid(void))
45         {
46         }
47         bad_lexical_cast(
48             const std::type_info &source_type,
49             const std::type_info &target_type) :
50             source(&source_type), target(&target_type)
51         {
52         }
53         const std::type_info &source_type() const
54         {
55             return *source;
56         }
57         const std::type_info &target_type() const
58         {
59             return *target;
60         }
61         virtual const char *what() const throw()
62         {
63             return "bad lexical cast: "
64                    "source type value could not be interpreted as target";
65         }
66         virtual ~bad_lexical_cast() throw()
67         {
68         }
69     private:
70         const std::type_info *source;
71         const std::type_info *target;
72     };
73
74     namespace detail // selectors for choosing stream character type
75     {
76         template<typename Type>
77         struct stream_char
78         {
79             typedef char type;
80         };
81
82         #ifndef DISABLE_WIDE_CHAR_SUPPORT
83 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
84         template<>
85         struct stream_char<wchar_t>
86         {
87             typedef wchar_t type;
88         };
89 #endif
90
91         template<>
92         struct stream_char<wchar_t *>
93         {
94             typedef wchar_t type;
95         };
96
97         template<>
98         struct stream_char<const wchar_t *>
99         {
100             typedef wchar_t type;
101         };
102
103         template<>
104         struct stream_char<std::wstring>
105         {
106             typedef wchar_t type;
107         };
108         #endif
109
110         template<typename TargetChar, typename SourceChar>
111         struct widest_char
112         {
113             typedef TargetChar type;
114         };
115
116         template<>
117         struct widest_char<char, wchar_t>
118         {
119             typedef wchar_t type;
120         };
121     }
122     
123     namespace detail // stream wrapper for handling lexical conversions
124     {
125         template<typename Target, typename Source>
126         class lexical_stream
127         {
128         private:
129             typedef typename widest_char<
130                 typename stream_char<Target>::type,
131                 typename stream_char<Source>::type>::type char_type;
132
133         public:
134             lexical_stream()
135             {
136                 stream.unsetf(std::ios::skipws);
137
138                 if(std::numeric_limits<Target>::is_specialized)
139                     stream.precision(std::numeric_limits<Target>::digits10 + 1);
140                 else if(std::numeric_limits<Source>::is_specialized)
141                     stream.precision(std::numeric_limits<Source>::digits10 + 1);
142             }
143             ~lexical_stream()
144             {
145                 #if defined(BOOST_NO_STRINGSTREAM)
146                 stream.freeze(false);
147                 #endif
148             }
149             bool operator<<(const Source &input)
150             {
151                 return !(stream << input).fail();
152             }
153             template<typename InputStreamable>
154             bool operator>>(InputStreamable &output)
155             {
156                 return !is_pointer<InputStreamable>::value &&
157                        stream >> output &&
158                        stream.get() ==
159 #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
160 // GCC 2.9x lacks std::char_traits<>::eof().
161 // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
162 // configurations, which do provide std::char_traits<>::eof().
163     
164                            EOF;
165 #else
166                            std::char_traits<char_type>::eof();
167 #endif
168             }
169             bool operator>>(std::string &output)
170             {
171                 #if defined(BOOST_NO_STRINGSTREAM)
172                 stream << '\0';
173                 #endif
174                 output = stream.str();
175                 return true;
176             }
177             #ifndef DISABLE_WIDE_CHAR_SUPPORT
178             bool operator>>(std::wstring &output)
179             {
180                 output = stream.str();
181                 return true;
182             }
183             #endif
184         private:
185             #if defined(BOOST_NO_STRINGSTREAM)
186             std::strstream stream;
187             #elif defined(BOOST_NO_STD_LOCALE)
188             std::stringstream stream;
189             #else
190             std::basic_stringstream<char_type> stream;
191             #endif
192         };
193     }
194
195     #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
196
197     // call-by-const reference version
198
199     namespace detail
200     {
201         template<class T>
202         struct array_to_pointer_decay
203         {
204             typedef T type;
205         };
206
207         template<class T, std::size_t N>
208         struct array_to_pointer_decay<T[N]>
209         {
210             typedef const T * type;
211         };
212     }
213
214     template<typename Target, typename Source>
215     Target lexical_cast(const Source &arg)
216     {
217         typedef typename detail::array_to_pointer_decay<Source>::type NewSource;
218
219         detail::lexical_stream<Target, NewSource> interpreter;
220         Target result;
221
222         if(!(interpreter << arg && interpreter >> result))
223             throw_exception(bad_lexical_cast(typeid(NewSource), typeid(Target)));
224         return result;
225     }
226
227     #else
228
229     // call-by-value fallback version (deprecated)
230
231     template<typename Target, typename Source>
232     Target lexical_cast(Source arg)
233     {
234         detail::lexical_stream<Target, Source> interpreter;
235         Target result;
236
237         if(!(interpreter << arg && interpreter >> result))
238             throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
239         return result;
240     }
241
242     #endif
243 }
244
245 // Copyright Kevlin Henney, 2000-2005. All rights reserved.
246 //
247 // Distributed under the Boost Software License, Version 1.0. (See
248 // accompanying file LICENSE_1_0.txt or copy at
249 // http://www.boost.org/LICENSE_1_0.txt)
250
251 #undef DISABLE_WIDE_CHAR_SUPPORT
252 #endif