forked from boostorg/conversion
update from Kevlin and Terje
[SVN r17861]
This commit is contained in:
+147
-42
@@ -1,31 +1,29 @@
|
||||
// boost lexical_cast.hpp header -------------------------------------------//
|
||||
|
||||
// See http://www.boost.org/libs/conversion for documentation.
|
||||
|
||||
#ifndef BOOST_LEXICAL_CAST_INCLUDED
|
||||
#define BOOST_LEXICAL_CAST_INCLUDED
|
||||
|
||||
// boost lexical_cast.hpp header --------------------------------------------//
|
||||
|
||||
// See http://www.boost.org/libs/conversion for documentation.
|
||||
// See end of this header for rights and permissions.
|
||||
//
|
||||
// what: lexical_cast custom keyword cast
|
||||
// who: contributed by Kevlin Henney, with alternative naming, behaviors
|
||||
// and fixes contributed by Dave Abrahams, Daryle Walker and other
|
||||
// Boosters on the list
|
||||
// when: November 2000
|
||||
// where: tested with MSVC 6.0, BCC 5.5, and g++ 2.91
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Some sstream implementations are broken for the purposes of lexical cast.
|
||||
# if defined(BOOST_NO_STRINGSTREAM)
|
||||
# define BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
# endif
|
||||
|
||||
#ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
# include <strstream>
|
||||
#else
|
||||
# include <sstream>
|
||||
#endif
|
||||
// who: contributed by Kevlin Henney,
|
||||
// enhanced with contributions from Terje Slettebø,
|
||||
// with additional fixes and suggestions from Gennaro Prota,
|
||||
// Dave Abrahams, Daryle Walker, and other Boosters on the list
|
||||
// when: November 2000, March 2003
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#ifdef BOOST_NO_STRINGSTREAM
|
||||
#include <strstream>
|
||||
#else
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -33,35 +31,146 @@ namespace boost
|
||||
class bad_lexical_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
// constructors, destructors, and assignment operator defaulted
|
||||
|
||||
// function inlined for brevity and consistency with rest of library
|
||||
virtual const char * what() const throw()
|
||||
virtual ~bad_lexical_cast() throw()
|
||||
{
|
||||
return "bad lexical cast: "
|
||||
"source type value could not be interpreted as target";
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail // actual underlying concrete exception type
|
||||
{
|
||||
template<typename Target, typename Source>
|
||||
class no_lexical_conversion : public bad_lexical_cast
|
||||
{
|
||||
public:
|
||||
no_lexical_conversion()
|
||||
: description(
|
||||
std::string() + "bad lexical cast: " +
|
||||
"source type value could not be interpreted as target, Target=" +
|
||||
typeid(Target).name() + ", Source=" + typeid(Source).name())
|
||||
{
|
||||
}
|
||||
virtual ~no_lexical_conversion() throw()
|
||||
{
|
||||
}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return description.c_str();
|
||||
}
|
||||
private:
|
||||
const std::string description; // static initialization fails on MSVC6
|
||||
};
|
||||
}
|
||||
|
||||
namespace detail // selectors for choosing stream character type
|
||||
{
|
||||
template<typename Type>
|
||||
struct stream_char
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_STRINGSTREAM
|
||||
template<>
|
||||
struct stream_char<wchar_t>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<wchar_t *>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<const wchar_t *>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<std::wstring>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename TargetChar, typename SourceChar>
|
||||
struct widest_char
|
||||
{
|
||||
typedef TargetChar type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct widest_char<char, wchar_t>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace detail // stream wrapper for handling lexical conversions
|
||||
{
|
||||
template<typename Target, typename Source>
|
||||
class lexical_stream
|
||||
{
|
||||
public:
|
||||
lexical_stream()
|
||||
{
|
||||
stream.unsetf(std::ios::skipws);
|
||||
|
||||
if(std::numeric_limits<Target>::is_specialized)
|
||||
stream.precision(std::numeric_limits<Target>::digits10 + 1);
|
||||
else if(std::numeric_limits<Source>::is_specialized)
|
||||
stream.precision(std::numeric_limits<Source>::digits10 + 1);
|
||||
}
|
||||
~lexical_stream()
|
||||
{
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
stream.freeze(false);
|
||||
#endif
|
||||
}
|
||||
bool operator<<(const Source &input)
|
||||
{
|
||||
return stream << input;
|
||||
}
|
||||
template<typename InputStreamable>
|
||||
bool operator>>(InputStreamable &output)
|
||||
{
|
||||
return !is_pointer<InputStreamable>::value &&
|
||||
stream >> output &&
|
||||
(stream >> std::ws).eof();
|
||||
}
|
||||
template<typename Char, typename Traits, typename Allocator>
|
||||
bool operator>>(std::basic_string<Char, Traits, Allocator> &output)
|
||||
{
|
||||
return std::getline(stream, output, char_type()).eof();
|
||||
}
|
||||
private:
|
||||
typedef typename widest_char<
|
||||
typename stream_char<Target>::type,
|
||||
typename stream_char<Source>::type>::type char_type;
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
std::strstream stream;
|
||||
#else
|
||||
std::basic_stringstream<char_type> stream;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Target, typename Source>
|
||||
Target lexical_cast(Source arg)
|
||||
{
|
||||
# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
std::strstream interpreter; // for out-of-the-box g++ 2.95.2
|
||||
# else
|
||||
std::stringstream interpreter;
|
||||
# endif
|
||||
detail::lexical_stream<Target, Source> interpreter;
|
||||
Target result;
|
||||
|
||||
if(!(interpreter << arg) || !(interpreter >> result) ||
|
||||
!(interpreter >> std::ws).eof())
|
||||
throw bad_lexical_cast();
|
||||
|
||||
if(!(interpreter << arg && interpreter >> result))
|
||||
throw detail::no_lexical_conversion<Target, Source>();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
|
||||
// Copyright Kevlin Henney, 2000-2003. All rights reserved.
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose is hereby granted without fee, provided that this copyright and
|
||||
@@ -69,8 +178,4 @@ namespace boost
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty.
|
||||
|
||||
#ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
# undef BOOST_LEXICAL_CAST_USE_STRSTREAM
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user