Ticket #5796: lexical_cast.hpp

File lexical_cast.hpp, 7.1 KB (added by Mikko Partonen <mikkopartonen@…>, 11 years ago)

Working lexical_cast.hpp file.

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 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
37namespace 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