2002-05-21 23:39:58 +00:00
|
|
|
|
#ifndef BOOST_LEXICAL_CAST_INCLUDED
|
|
|
|
|
#define BOOST_LEXICAL_CAST_INCLUDED
|
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
// 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.
|
|
|
|
|
//
|
2002-05-21 23:39:58 +00:00
|
|
|
|
// what: lexical_cast custom keyword cast
|
2003-03-20 23:09:18 +00:00
|
|
|
|
// who: contributed by Kevlin Henney,
|
|
|
|
|
// enhanced with contributions from Terje Sletteb<65>,
|
|
|
|
|
// with additional fixes and suggestions from Gennaro Prota,
|
|
|
|
|
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
|
|
|
|
|
// and other Boosters
|
2006-03-05 18:22:35 +00:00
|
|
|
|
// when: November 2000, March 2003, June 2005
|
2002-05-21 23:39:58 +00:00
|
|
|
|
|
2006-03-05 18:22:35 +00:00
|
|
|
|
#include <cstddef>
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#include <string>
|
|
|
|
|
#include <typeinfo>
|
2002-05-21 23:39:58 +00:00
|
|
|
|
#include <boost/config.hpp>
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#include <boost/limits.hpp>
|
2003-08-07 12:09:24 +00:00
|
|
|
|
#include <boost/throw_exception.hpp>
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#include <boost/type_traits/is_pointer.hpp>
|
2002-05-21 23:39:58 +00:00
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#ifdef BOOST_NO_STRINGSTREAM
|
|
|
|
|
#include <strstream>
|
2002-05-21 23:39:58 +00:00
|
|
|
|
#else
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#include <sstream>
|
2002-05-21 23:39:58 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#if defined(BOOST_NO_STRINGSTREAM) || \
|
|
|
|
|
defined(BOOST_NO_STD_WSTRING) || \
|
2006-03-05 18:22:35 +00:00
|
|
|
|
defined(BOOST_NO_STD_LOCALE)
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#define DISABLE_WIDE_CHAR_SUPPORT
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-05-21 23:39:58 +00:00
|
|
|
|
namespace boost
|
|
|
|
|
{
|
|
|
|
|
// exception used to indicate runtime lexical_cast failure
|
|
|
|
|
class bad_lexical_cast : public std::bad_cast
|
|
|
|
|
{
|
|
|
|
|
public:
|
2003-08-07 12:09:24 +00:00
|
|
|
|
bad_lexical_cast() :
|
|
|
|
|
source(&typeid(void)), target(&typeid(void))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
bad_lexical_cast(
|
2006-03-05 18:22:35 +00:00
|
|
|
|
const std::type_info &source_type,
|
|
|
|
|
const std::type_info &target_type) :
|
|
|
|
|
source(&source_type), target(&target_type)
|
2003-08-07 12:09:24 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
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";
|
|
|
|
|
}
|
2003-03-20 23:09:18 +00:00
|
|
|
|
virtual ~bad_lexical_cast() throw()
|
2002-05-21 23:39:58 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2003-08-07 12:09:24 +00:00
|
|
|
|
private:
|
|
|
|
|
const std::type_info *source;
|
|
|
|
|
const std::type_info *target;
|
2002-05-21 23:39:58 +00:00
|
|
|
|
};
|
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
namespace detail // selectors for choosing stream character type
|
|
|
|
|
{
|
|
|
|
|
template<typename Type>
|
|
|
|
|
struct stream_char
|
|
|
|
|
{
|
|
|
|
|
typedef char type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
2006-03-05 18:22:35 +00:00
|
|
|
|
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
2003-03-20 23:09:18 +00:00
|
|
|
|
template<>
|
|
|
|
|
struct stream_char<wchar_t>
|
|
|
|
|
{
|
|
|
|
|
typedef wchar_t type;
|
|
|
|
|
};
|
2006-03-05 18:22:35 +00:00
|
|
|
|
#endif
|
2003-03-20 23:09:18 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2006-03-05 18:22:35 +00:00
|
|
|
|
private:
|
|
|
|
|
typedef typename widest_char<
|
|
|
|
|
typename stream_char<Target>::type,
|
|
|
|
|
typename stream_char<Source>::type>::type char_type;
|
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
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)
|
|
|
|
|
{
|
2003-08-07 12:09:24 +00:00
|
|
|
|
return !(stream << input).fail();
|
2003-03-20 23:09:18 +00:00
|
|
|
|
}
|
|
|
|
|
template<typename InputStreamable>
|
|
|
|
|
bool operator>>(InputStreamable &output)
|
|
|
|
|
{
|
|
|
|
|
return !is_pointer<InputStreamable>::value &&
|
|
|
|
|
stream >> output &&
|
2006-03-05 18:22:35 +00:00
|
|
|
|
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<char_type>::eof();
|
|
|
|
|
#endif
|
2003-03-20 23:09:18 +00:00
|
|
|
|
}
|
|
|
|
|
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<char_type> stream;
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-05 18:22:35 +00:00
|
|
|
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
|
|
|
|
|
|
|
|
// call-by-const reference version
|
|
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
|
{
|
|
|
|
|
template<class T>
|
|
|
|
|
struct array_to_pointer_decay
|
|
|
|
|
{
|
|
|
|
|
typedef T type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class T, std::size_t N>
|
|
|
|
|
struct array_to_pointer_decay<T[N]>
|
|
|
|
|
{
|
|
|
|
|
typedef const T * type;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Target, typename Source>
|
|
|
|
|
Target lexical_cast(const Source &arg)
|
|
|
|
|
{
|
|
|
|
|
typedef typename detail::array_to_pointer_decay<Source>::type NewSource;
|
|
|
|
|
|
|
|
|
|
detail::lexical_stream<Target, NewSource> interpreter;
|
|
|
|
|
Target result;
|
|
|
|
|
|
|
|
|
|
if(!(interpreter << arg && interpreter >> result))
|
|
|
|
|
throw_exception(bad_lexical_cast(typeid(NewSource), typeid(Target)));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// call-by-value fallback version (deprecated)
|
|
|
|
|
|
2002-05-21 23:39:58 +00:00
|
|
|
|
template<typename Target, typename Source>
|
|
|
|
|
Target lexical_cast(Source arg)
|
|
|
|
|
{
|
2003-03-20 23:09:18 +00:00
|
|
|
|
detail::lexical_stream<Target, Source> interpreter;
|
2002-05-21 23:39:58 +00:00
|
|
|
|
Target result;
|
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
if(!(interpreter << arg && interpreter >> result))
|
2006-03-05 18:22:35 +00:00
|
|
|
|
throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
|
2002-05-21 23:39:58 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
2006-03-05 18:22:35 +00:00
|
|
|
|
|
|
|
|
|
#endif
|
2002-05-21 23:39:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-05 18:22:35 +00:00
|
|
|
|
// Copyright Kevlin Henney, 2000-2005. All rights reserved.
|
2002-05-21 23:39:58 +00:00
|
|
|
|
//
|
2004-11-20 09:08:45 +00:00
|
|
|
|
// 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)
|
2002-05-21 23:39:58 +00:00
|
|
|
|
|
2003-03-20 23:09:18 +00:00
|
|
|
|
#undef DISABLE_WIDE_CHAR_SUPPORT
|
2002-05-21 23:39:58 +00:00
|
|
|
|
#endif
|