#ifndef BOOST_LEXICAL_CAST_INCLUDED #define BOOST_LEXICAL_CAST_INCLUDED // Boost lexical_cast.hpp header -------------------------------------------// // // See http://www.boost.org/ for most recent version including documentation. // See end of this header for rights and permissions. // // what: lexical_cast custom keyword cast // who: contributed by Kevlin Henney, // enhanced with contributions from Terje Slettebo, // with additional fixes and suggestions from Gennaro Prota, // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov, // and other Boosters // when: November 2000, March 2003, June 2005 #include #include #include #include #include #include #include #include #ifdef BOOST_NO_STRINGSTREAM #include #else #include #endif #if defined(BOOST_NO_STRINGSTREAM) || \ defined(BOOST_NO_STD_WSTRING) || \ defined(BOOST_NO_STD_LOCALE) #define DISABLE_WIDE_CHAR_SUPPORT #endif namespace boost { // exception used to indicate runtime lexical_cast failure class bad_lexical_cast : public std::bad_cast { public: bad_lexical_cast() : source(&typeid(void)), target(&typeid(void)) { } bad_lexical_cast( const std::type_info &source_type, const std::type_info &target_type) : source(&source_type), target(&target_type) { } const std::type_info &source_type() const { return *source; } const std::type_info &target_type() const { return *target; } virtual const char *what() const throw() { return "bad lexical cast: " "source type value could not be interpreted as target"; } virtual ~bad_lexical_cast() throw() { } private: const std::type_info *source; const std::type_info *target; }; namespace detail // selectors for choosing stream character type { template struct stream_char { typedef char type; }; #ifndef DISABLE_WIDE_CHAR_SUPPORT #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) template<> struct stream_char { typedef wchar_t type; }; #endif template<> struct stream_char { typedef wchar_t type; }; template<> struct stream_char { typedef wchar_t type; }; template<> struct stream_char { typedef wchar_t type; }; #endif template struct widest_char { typedef TargetChar type; }; template<> struct widest_char { typedef wchar_t type; }; } namespace detail // stream wrapper for handling lexical conversions { template class lexical_stream { private: typedef typename widest_char< typename stream_char::type, typename stream_char::type>::type char_type; public: lexical_stream() { stream.unsetf(std::ios::skipws); #if (defined _MSC_VER) # pragma warning( push ) // conditional expression is constant # pragma warning( disable : 4127 ) #endif typedef std::numeric_limits t; typedef std::numeric_limits s; if(t::is_specialized) stream.precision(1 + t::digits10); else if(s::is_specialized) stream.precision(1 + s::digits10); #if (defined _MSC_VER) # pragma warning( pop ) #endif } ~lexical_stream() { #if defined(BOOST_NO_STRINGSTREAM) stream.freeze(false); #endif } bool operator<<(const Source &input) { return !(stream << input).fail(); } template bool operator>>(InputStreamable &output) { return !is_pointer::value && stream >> output && stream.get() == #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING) // GCC 2.9x lacks std::char_traits<>::eof(). // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3 // configurations, which do provide std::char_traits<>::eof(). EOF; #else std::char_traits::eof(); #endif } bool operator>>(std::string &output) { #if defined(BOOST_NO_STRINGSTREAM) stream << '\0'; #endif output = stream.str(); return true; } #ifndef DISABLE_WIDE_CHAR_SUPPORT bool operator>>(std::wstring &output) { output = stream.str(); return true; } #endif private: #if defined(BOOST_NO_STRINGSTREAM) std::strstream stream; #elif defined(BOOST_NO_STD_LOCALE) std::stringstream stream; #else std::basic_stringstream stream; #endif }; } #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // call-by-const reference version namespace detail { template struct array_to_pointer_decay { typedef T type; }; template struct array_to_pointer_decay { typedef const T * type; }; template Target lexical_cast( BOOST_DEDUCED_TYPENAME boost::call_traits::value_type arg) { detail::lexical_stream interpreter; // The original form, reproduced below, is more elegant // but yields a spurious C4701 warning ("possible use of // "result" before initialization") with VC7.1 (/W4). // // Target result; // // if(!(interpreter << arg && interpreter >> result)) // throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))); // return result; if(interpreter << arg) { Target result; if (interpreter >> result) return result; } throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))); return Target(); // normally never reached (throw_exception) } } template inline Target lexical_cast(const Source &arg) { typedef typename detail::array_to_pointer_decay::type NewSource; return detail::lexical_cast(arg); } #else // call-by-value fallback version (deprecated) template Target lexical_cast(Source arg) { detail::lexical_stream interpreter; Target result; if(!(interpreter << arg && interpreter >> result)) throw_exception(bad_lexical_cast(typeid(Source), typeid(Target))); return result; } #endif } // Copyright Kevlin Henney, 2000-2005. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #undef DISABLE_WIDE_CHAR_SUPPORT #endif