1 #ifndef BOOST_LEXICAL_CAST_INCLUDED
2 #define BOOST_LEXICAL_CAST_INCLUDED
4 // Boost lexical_cast.hpp header -------------------------------------------//
6 // See http://www.boost.org for most recent version including documentation.
7 // See end of this header for rights and permissions.
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,
15 // when: November 2000, March 2003, June 2005
20 #include <boost/config.hpp>
21 #include <boost/limits.hpp>
22 #include <boost/throw_exception.hpp>
23 #include <boost/type_traits/is_pointer.hpp>
25 #ifdef BOOST_NO_STRINGSTREAM
31 #if defined(BOOST_NO_STRINGSTREAM) || \
32 defined(BOOST_NO_STD_WSTRING) || \
33 defined(BOOST_NO_STD_LOCALE)
34 #define DISABLE_WIDE_CHAR_SUPPORT
39 // exception used to indicate runtime lexical_cast failure
40 class bad_lexical_cast : public std::bad_cast
44 source(&typeid(void)), target(&typeid(void))
48 const std::type_info &source_type,
49 const std::type_info &target_type) :
50 source(&source_type), target(&target_type)
53 const std::type_info &source_type() const
57 const std::type_info &target_type() const
61 virtual const char *what() const throw()
63 return "bad lexical cast: "
64 "source type value could not be interpreted as target";
66 virtual ~bad_lexical_cast() throw()
70 const std::type_info *source;
71 const std::type_info *target;
74 namespace detail // selectors for choosing stream character type
76 template<typename Type>
82 #ifndef DISABLE_WIDE_CHAR_SUPPORT
83 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
85 struct stream_char<wchar_t>
92 struct stream_char<wchar_t *>
98 struct stream_char<const wchar_t *>
100 typedef wchar_t type;
104 struct stream_char<std::wstring>
106 typedef wchar_t type;
110 template<typename TargetChar, typename SourceChar>
113 typedef TargetChar type;
117 struct widest_char<char, wchar_t>
119 typedef wchar_t type;
123 namespace detail // stream wrapper for handling lexical conversions
125 template<typename Target, typename Source>
129 typedef typename widest_char<
130 typename stream_char<Target>::type,
131 typename stream_char<Source>::type>::type char_type;
136 stream.unsetf(std::ios::skipws);
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);
145 #if defined(BOOST_NO_STRINGSTREAM)
146 stream.freeze(false);
149 bool operator<<(const Source &input)
151 return !(stream << input).fail();
153 template<typename InputStreamable>
154 bool operator>>(InputStreamable &output)
156 return !is_pointer<InputStreamable>::value &&
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().
166 std::char_traits<char_type>::eof();
169 bool operator>>(std::string &output)
171 #if defined(BOOST_NO_STRINGSTREAM)
174 output = stream.str();
177 #ifndef DISABLE_WIDE_CHAR_SUPPORT
178 bool operator>>(std::wstring &output)
180 output = stream.str();
185 #if defined(BOOST_NO_STRINGSTREAM)
186 std::strstream stream;
187 #elif defined(BOOST_NO_STD_LOCALE)
188 std::stringstream stream;
190 std::basic_stringstream<char_type> stream;
195 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
197 // call-by-const reference version
202 struct array_to_pointer_decay
207 template<class T, std::size_t N>
208 struct array_to_pointer_decay<T[N]>
210 typedef const T * type;
214 template<typename Target, typename Source>
215 Target lexical_cast(const Source &arg)
217 typedef typename detail::array_to_pointer_decay<Source>::type NewSource;
219 detail::lexical_stream<Target, NewSource> interpreter;
222 if(!(interpreter << arg && interpreter >> result))
223 throw_exception(bad_lexical_cast(typeid(NewSource), typeid(Target)));
229 // call-by-value fallback version (deprecated)
231 template<typename Target, typename Source>
232 Target lexical_cast(Source arg)
234 detail::lexical_stream<Target, Source> interpreter;
237 if(!(interpreter << arg && interpreter >> result))
238 throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
245 // Copyright Kevlin Henney, 2000-2005. All rights reserved.
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)
251 #undef DISABLE_WIDE_CHAR_SUPPORT