[857] | 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
|
---|