forked from boostorg/conversion
Merge from trunk:
1) #warning replaced with #error (refs #7228) 2) Pavel Korzh added to thanks list (refs #7157) 3) BOOST_NOEXCEPT modifiers added where possible 4) better support for c++11 Unicode characters 5) fixed compilation with MSVC+STLPort 6) more agressive usage of Traits template parameter 7) Added lexical_cast(const CharType* chars, std::size_t count) function overload (refs #6430 and refs #6663) 8) Fixed GCC warning in numeric_cast_test.cpp 9) Fix compilation of lexical cast with MSVC 2003 (refs #7255) [SVN r80409]
This commit is contained in:
@@ -79,6 +79,13 @@ Following example converts some number and puts it to file:
|
||||
buf_t buffer = boost::lexical_cast<buf_t>(i); // No dynamic memory allocation
|
||||
puts(buffer.begin(), file);
|
||||
``
|
||||
Following example takes part of the string and converts it to `int`:
|
||||
``
|
||||
int convert_strings_part(const std::string& s, std::size_t pos, std::size_t n)
|
||||
{
|
||||
return boost::lexical_cast<int>(s.data() + pos, n);
|
||||
}
|
||||
``
|
||||
[endsect]
|
||||
|
||||
[section Synopsis]
|
||||
@@ -99,7 +106,13 @@ Library features defined in [@boost:boost/lexical_cast.hpp boost/lexical_cast.hp
|
||||
``
|
||||
Returns the result of streaming arg into a standard library string-based stream and then out as a Target object. Where Target is either `std::string` or `std::wstring`, stream extraction takes the whole content of the string, including spaces, rather than relying on the default `operator>>` behavior. If the conversion is unsuccessful, a `bad_lexical_cast` exception is thrown.
|
||||
|
||||
The requirements on the argument and result types are:
|
||||
``
|
||||
template <typename Target, typename CharType>
|
||||
Target lexical_cast(const CharType* chars, std::size_t count);
|
||||
``
|
||||
Takes an array of `count` characters as input parameter and streams them out as a Target object. If the conversion is unsuccessful, a `bad_lexical_cast` exception is thrown. This call may be useful for processing nonzero terminated array of characters or processing just some part of character array.
|
||||
|
||||
The requirements on the argument and result types for both functions are:
|
||||
|
||||
* Source is OutputStreamable, meaning that an `operator<<` is defined that takes a `std::ostream` or `std::wostream` object on the left hand side and an instance of the argument type on the right.
|
||||
* Target is InputStreamable, meaning that an `operator>>` is defined that takes a `std::istream` or `std::wistream` object on the left hand side and an instance of the result type on the right.
|
||||
@@ -114,6 +127,7 @@ The character type of the underlying stream is assumed to be `char` unless eithe
|
||||
* `boost::iterator_range<WideCharPtr>`, where `WideCharPtr` is a pointer to wide-character or pointer to const wide-character
|
||||
* `boost::array<CharT, N>` and `std::array<CharT, N>`, `boost::array<const CharT, N>` and `std::array<const CharT, N>`
|
||||
|
||||
|
||||
[important Many compilers and runtime libraries fail to make conversions using new Unicode characters. Make sure that the following code compiles and outputs nonzero values, before using new types:
|
||||
``
|
||||
std::cout
|
||||
@@ -253,12 +267,17 @@ limitation of compiler options that you use.
|
||||
]
|
||||
|
||||
* [*Question:] What is the fastest way to convert a non zero terminated string or a substring using `boost::lexical_cast`?
|
||||
* [*Answer:] Use `boost::iterator_range` for conversion. For example, if you whant to convert to `int` two characters from a string `str`, you shall write `lexacal_cast<int>(make_iterator_range(str.c_str(), str.c_str() + 2));`.
|
||||
* [*Answer:] Use `boost::iterator_range` for conversion or `lexical_cast` overload with two parameters. For example, if you whant to convert to `int` two characters from a string `str`, you shall write `lexical_cast<int>(make_iterator_range(str.data(), str.data() + 2));` or `lexical_cast<int>(str.data(), 2);`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Changes]
|
||||
|
||||
* [*boost 1.52.0 :]
|
||||
|
||||
* Restored compilation on MSVC-2003 (was broken in 1.51.0).
|
||||
* Added `lexical_cast(const CharType* chars, std::size_t count)` function overload.
|
||||
|
||||
* [*boost 1.51.0 :]
|
||||
|
||||
* Better performance, less memory usage for `boost::array<character_type, N>` and `std::array<character_type, N>` conversions.
|
||||
|
@@ -18,7 +18,7 @@
|
||||
// with additional fixes and suggestions from Gennaro Prota,
|
||||
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
|
||||
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
|
||||
// Cheng Yang, Matthew Bradbury, David W. Birdsall and other Boosters
|
||||
// Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
|
||||
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012
|
||||
|
||||
#include <boost/config.hpp>
|
||||
@@ -47,8 +47,12 @@
|
||||
# include <locale>
|
||||
#else
|
||||
# ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||
# warning "Unable to use <locale> header. boost::lexical_cast will use the 'C' locale."
|
||||
# define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||
// Getting error at this point means, that your STL library is old/lame/misconfigured.
|
||||
// If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
|
||||
// but beware: lexical_cast will understand only 'C' locale delimeters and thousands
|
||||
// separators.
|
||||
# error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
|
||||
# error "boost::lexical_cast to use only 'C' locale during conversions."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -83,7 +87,7 @@ namespace boost
|
||||
|
||||
{
|
||||
public:
|
||||
bad_lexical_cast() :
|
||||
bad_lexical_cast() BOOST_NOEXCEPT :
|
||||
#ifndef BOOST_NO_TYPEID
|
||||
source(&typeid(void)), target(&typeid(void))
|
||||
#else
|
||||
@@ -94,7 +98,7 @@ namespace boost
|
||||
|
||||
bad_lexical_cast(
|
||||
const std::type_info &source_type_arg,
|
||||
const std::type_info &target_type_arg) :
|
||||
const std::type_info &target_type_arg) BOOST_NOEXCEPT :
|
||||
source(&source_type_arg), target(&target_type_arg)
|
||||
{
|
||||
}
|
||||
@@ -108,14 +112,22 @@ namespace boost
|
||||
return *target;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_NOEXCEPT
|
||||
virtual const char *what() const noexcept
|
||||
#else
|
||||
virtual const char *what() const throw()
|
||||
#endif
|
||||
{
|
||||
return "bad lexical cast: "
|
||||
"source type value could not be interpreted as target";
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_NOEXCEPT
|
||||
virtual ~bad_lexical_cast() BOOST_NOEXCEPT
|
||||
#else
|
||||
virtual ~bad_lexical_cast() throw()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
{}
|
||||
private:
|
||||
const std::type_info *source;
|
||||
const std::type_info *target;
|
||||
@@ -570,10 +582,10 @@ namespace boost {
|
||||
#endif
|
||||
template<class T>
|
||||
inline
|
||||
BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value)
|
||||
BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME make_unsigned<T>::type result_type;
|
||||
result_type uvalue = static_cast<result_type>(value);
|
||||
const result_type uvalue = static_cast<result_type>(value);
|
||||
return value < 0 ? -uvalue : uvalue;
|
||||
}
|
||||
#if (defined _MSC_VER)
|
||||
@@ -777,7 +789,7 @@ namespace boost {
|
||||
namespace detail
|
||||
{
|
||||
template <class CharT>
|
||||
bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) {
|
||||
bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) BOOST_NOEXCEPT {
|
||||
for( unsigned int i=0; i < len; ++i ) {
|
||||
if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false;
|
||||
}
|
||||
@@ -790,7 +802,7 @@ namespace boost {
|
||||
inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
|
||||
, const CharT* lc_NAN, const CharT* lc_nan
|
||||
, const CharT* lc_INFINITY, const CharT* lc_infinity
|
||||
, const CharT opening_brace, const CharT closing_brace)
|
||||
, const CharT opening_brace, const CharT closing_brace) BOOST_NOEXCEPT
|
||||
{
|
||||
using namespace std;
|
||||
if (begin == end) return false;
|
||||
@@ -846,7 +858,7 @@ namespace boost {
|
||||
template <class CharT, class T>
|
||||
bool put_inf_nan_impl(CharT* begin, CharT*& end, const T& value
|
||||
, const CharT* lc_nan
|
||||
, const CharT* lc_infinity)
|
||||
, const CharT* lc_infinity) BOOST_NOEXCEPT
|
||||
{
|
||||
using namespace std;
|
||||
const CharT minus = lcast_char_constants<CharT>::minus;
|
||||
@@ -880,7 +892,7 @@ namespace boost {
|
||||
|
||||
#ifndef BOOST_LCAST_NO_WCHAR_T
|
||||
template <class T>
|
||||
bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value)
|
||||
bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return parse_inf_nan_impl(begin, end, value
|
||||
, L"NAN", L"nan"
|
||||
@@ -889,7 +901,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value)
|
||||
bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return put_inf_nan_impl(begin, end, value, L"nan", L"infinity");
|
||||
}
|
||||
@@ -897,7 +909,7 @@ namespace boost {
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CHAR16_T) && !defined(BOOST_NO_UNICODE_LITERALS)
|
||||
template <class T>
|
||||
bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value)
|
||||
bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return parse_inf_nan_impl(begin, end, value
|
||||
, u"NAN", u"nan"
|
||||
@@ -906,14 +918,14 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value)
|
||||
bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return put_inf_nan_impl(begin, end, value, u"nan", u"infinity");
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CHAR32_T) && !defined(BOOST_NO_UNICODE_LITERALS)
|
||||
template <class T>
|
||||
bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value)
|
||||
bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return parse_inf_nan_impl(begin, end, value
|
||||
, U"NAN", U"nan"
|
||||
@@ -922,14 +934,14 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value)
|
||||
bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return put_inf_nan_impl(begin, end, value, U"nan", U"infinity");
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class CharT, class T>
|
||||
bool parse_inf_nan(const CharT* begin, const CharT* end, T& value)
|
||||
bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return parse_inf_nan_impl(begin, end, value
|
||||
, "NAN", "nan"
|
||||
@@ -938,7 +950,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <class CharT, class T>
|
||||
bool put_inf_nan(CharT* begin, CharT*& end, const T& value)
|
||||
bool put_inf_nan(CharT* begin, CharT*& end, const T& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return put_inf_nan_impl(begin, end, value, "nan", "infinity");
|
||||
}
|
||||
@@ -1008,11 +1020,11 @@ namespace boost {
|
||||
|
||||
/* Getting the plus/minus sign */
|
||||
bool has_minus = false;
|
||||
if ( *begin == minus ) {
|
||||
if (Traits::eq(*begin, minus) ) {
|
||||
++ begin;
|
||||
has_minus = true;
|
||||
if (begin == end) return false;
|
||||
} else if ( *begin == plus ) {
|
||||
} else if (Traits::eq(*begin, plus) ) {
|
||||
++begin;
|
||||
if (begin == end) return false;
|
||||
}
|
||||
@@ -1031,7 +1043,7 @@ namespace boost {
|
||||
/* We allow no thousand_separators after decimal point */
|
||||
|
||||
mantissa_type tmp_mantissa = mantissa * 10u;
|
||||
if ( *begin == lowercase_e || *begin == capital_e ) break;
|
||||
if (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) break;
|
||||
if ( *begin < czero || *begin >= czero + 10 ) return false;
|
||||
if ( is_mantissa_full
|
||||
|| tmp_mantissa / 10u != mantissa
|
||||
@@ -1070,7 +1082,7 @@ namespace boost {
|
||||
|
||||
found_number_before_exp = true;
|
||||
++ length_since_last_delim;
|
||||
} else if ( *begin == decimal_point || *begin == lowercase_e || *begin == capital_e) {
|
||||
} else if (Traits::eq(*begin, decimal_point) || Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) {
|
||||
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||
/* If ( we need to check grouping
|
||||
* and ( grouping missmatches
|
||||
@@ -1088,7 +1100,7 @@ namespace boost {
|
||||
) return false;
|
||||
#endif
|
||||
|
||||
if(*begin == decimal_point) {
|
||||
if(Traits::eq(*begin, decimal_point)) {
|
||||
++ begin;
|
||||
found_decimal = true;
|
||||
if (!found_number_before_exp && begin==end) return false;
|
||||
@@ -1099,7 +1111,7 @@ namespace boost {
|
||||
}
|
||||
}
|
||||
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||
else if (grouping_size && *begin == thousands_sep){
|
||||
else if (grouping_size && Traits::eq(*begin, thousands_sep)){
|
||||
if(found_grouping)
|
||||
{
|
||||
/* It is not he first time, when we find thousands separator,
|
||||
@@ -1141,16 +1153,16 @@ namespace boost {
|
||||
}
|
||||
|
||||
// Exponent found
|
||||
if ( begin != end && ( *begin == lowercase_e || *begin == capital_e ) ) {
|
||||
if ( begin != end && (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) ) {
|
||||
++ begin;
|
||||
if ( begin == end ) return false;
|
||||
|
||||
bool exp_has_minus = false;
|
||||
if( *begin == minus ) {
|
||||
if(Traits::eq(*begin, minus)) {
|
||||
exp_has_minus = true;
|
||||
++ begin;
|
||||
if ( begin == end ) return false;
|
||||
} else if (*begin == plus ) {
|
||||
} else if (Traits::eq(*begin, plus)) {
|
||||
++ begin;
|
||||
if ( begin == end ) return false;
|
||||
}
|
||||
@@ -1258,7 +1270,7 @@ namespace boost {
|
||||
void operator=(lexical_stream_limited_src const&);
|
||||
|
||||
/************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
|
||||
bool shl_char(CharT ch)
|
||||
bool shl_char(CharT ch) BOOST_NOEXCEPT
|
||||
{
|
||||
Traits::assign(*start, ch);
|
||||
finish = start + 1;
|
||||
@@ -1270,13 +1282,13 @@ namespace boost {
|
||||
bool shl_char(T ch)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
|
||||
"boost::lexical_cast does not support conversions from wide character to char types."
|
||||
"boost::lexical_cast does not support narrowing of char types."
|
||||
"Use boost::locale instead" );
|
||||
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||
std::locale loc;
|
||||
wchar_t w = BOOST_USE_FACET(std::ctype<wchar_t>, loc).widen(ch);
|
||||
CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
|
||||
#else
|
||||
wchar_t w = ch;
|
||||
CharT const w = ch;
|
||||
#endif
|
||||
Traits::assign(*start, w);
|
||||
finish = start + 1;
|
||||
@@ -1284,7 +1296,7 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool shl_char_array(CharT const* str)
|
||||
bool shl_char_array(CharT const* str) BOOST_NOEXCEPT
|
||||
{
|
||||
start = const_cast<CharT*>(str);
|
||||
finish = start + Traits::length(str);
|
||||
@@ -1295,15 +1307,15 @@ namespace boost {
|
||||
bool shl_char_array(T const* str)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
|
||||
"boost::lexical_cast does not support conversions from wide characters to char types."
|
||||
"boost::lexical_cast does not support narrowing of char types."
|
||||
"Use boost::locale instead" );
|
||||
return shl_input_streamable(str);
|
||||
}
|
||||
|
||||
bool shl_char_array_limited(CharT const* str, std::size_t max_size)
|
||||
bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT
|
||||
{
|
||||
start = const_cast<CharT*>(str);
|
||||
finish = std::find(start, start + max_size, static_cast<CharT>(0));
|
||||
finish = std::find(start, start + max_size, Traits::to_char_type(0));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1349,7 +1361,7 @@ namespace boost {
|
||||
if (put_inf_nan(begin, end, val)) return true;
|
||||
const double val_as_double = val;
|
||||
end = begin +
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
sprintf_s(begin, end-begin,
|
||||
#else
|
||||
sprintf(begin,
|
||||
@@ -1362,7 +1374,7 @@ namespace boost {
|
||||
{ using namespace std;
|
||||
if (put_inf_nan(begin, end, val)) return true;
|
||||
end = begin +
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
sprintf_s(begin, end-begin,
|
||||
#else
|
||||
sprintf(begin,
|
||||
@@ -1376,7 +1388,7 @@ namespace boost {
|
||||
{ using namespace std;
|
||||
if (put_inf_nan(begin, end, val)) return true;
|
||||
end = begin +
|
||||
#if (defined _MSC_VER)
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
sprintf_s(begin, end-begin,
|
||||
#else
|
||||
sprintf(begin,
|
||||
@@ -1419,7 +1431,7 @@ namespace boost {
|
||||
/************************************ OPERATORS << ( ... ) ********************************/
|
||||
public:
|
||||
template<class Alloc>
|
||||
bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str)
|
||||
bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
|
||||
{
|
||||
start = const_cast<CharT*>(str.data());
|
||||
finish = start + str.length();
|
||||
@@ -1427,14 +1439,14 @@ namespace boost {
|
||||
}
|
||||
|
||||
template<class Alloc>
|
||||
bool operator<<(::boost::container::basic_string<CharT,Traits,Alloc> const& str)
|
||||
bool operator<<(::boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
|
||||
{
|
||||
start = const_cast<CharT*>(str.data());
|
||||
finish = start + str.length();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<<(bool value)
|
||||
bool operator<<(bool value) BOOST_NOEXCEPT
|
||||
{
|
||||
CharT const czero = lcast_char_constants<CharT>::zero;
|
||||
Traits::assign(*start, Traits::to_char_type(czero + value));
|
||||
@@ -1442,21 +1454,21 @@ namespace boost {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<<(const iterator_range<CharT*>& rng)
|
||||
bool operator<<(const iterator_range<CharT*>& rng) BOOST_NOEXCEPT
|
||||
{
|
||||
start = rng.begin();
|
||||
finish = rng.end();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<<(const iterator_range<const CharT*>& rng)
|
||||
bool operator<<(const iterator_range<const CharT*>& rng) BOOST_NOEXCEPT
|
||||
{
|
||||
start = const_cast<CharT*>(rng.begin());
|
||||
finish = const_cast<CharT*>(rng.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<<(const iterator_range<const signed char*>& rng)
|
||||
bool operator<<(const iterator_range<const signed char*>& rng) BOOST_NOEXCEPT
|
||||
{
|
||||
return (*this) << iterator_range<char*>(
|
||||
const_cast<char*>(reinterpret_cast<const char*>(rng.begin())),
|
||||
@@ -1464,7 +1476,7 @@ namespace boost {
|
||||
);
|
||||
}
|
||||
|
||||
bool operator<<(const iterator_range<const unsigned char*>& rng)
|
||||
bool operator<<(const iterator_range<const unsigned char*>& rng) BOOST_NOEXCEPT
|
||||
{
|
||||
return (*this) << iterator_range<char*>(
|
||||
const_cast<char*>(reinterpret_cast<const char*>(rng.begin())),
|
||||
@@ -1472,7 +1484,7 @@ namespace boost {
|
||||
);
|
||||
}
|
||||
|
||||
bool operator<<(const iterator_range<signed char*>& rng)
|
||||
bool operator<<(const iterator_range<signed char*>& rng) BOOST_NOEXCEPT
|
||||
{
|
||||
return (*this) << iterator_range<char*>(
|
||||
reinterpret_cast<char*>(rng.begin()),
|
||||
@@ -1480,7 +1492,7 @@ namespace boost {
|
||||
);
|
||||
}
|
||||
|
||||
bool operator<<(const iterator_range<unsigned char*>& rng)
|
||||
bool operator<<(const iterator_range<unsigned char*>& rng) BOOST_NOEXCEPT
|
||||
{
|
||||
return (*this) << iterator_range<char*>(
|
||||
reinterpret_cast<char*>(rng.begin()),
|
||||
@@ -1539,52 +1551,52 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(boost::array<CharT, N> const& input)
|
||||
bool operator<<(boost::array<CharT, N> const& input) BOOST_NOEXCEPT
|
||||
{ return shl_char_array_limited(input.begin(), N); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(boost::array<unsigned char, N> const& input)
|
||||
bool operator<<(boost::array<unsigned char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(boost::array<signed char, N> const& input)
|
||||
bool operator<<(boost::array<signed char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(boost::array<const CharT, N> const& input)
|
||||
bool operator<<(boost::array<const CharT, N> const& input) BOOST_NOEXCEPT
|
||||
{ return shl_char_array_limited(input.begin(), N); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(boost::array<const unsigned char, N> const& input)
|
||||
bool operator<<(boost::array<const unsigned char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(boost::array<const signed char, N> const& input)
|
||||
bool operator<<(boost::array<const signed char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
|
||||
template <std::size_t N>
|
||||
bool operator<<(std::array<CharT, N> const& input)
|
||||
bool operator<<(std::array<CharT, N> const& input) BOOST_NOEXCEPT
|
||||
{ return shl_char_array_limited(input.begin(), N); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(std::array<unsigned char, N> const& input)
|
||||
bool operator<<(std::array<unsigned char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(std::array<signed char, N> const& input)
|
||||
bool operator<<(std::array<signed char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(std::array<const CharT, N> const& input)
|
||||
bool operator<<(std::array<const CharT, N> const& input) BOOST_NOEXCEPT
|
||||
{ return shl_char_array_limited(input.begin(), N); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(std::array<const unsigned char, N> const& input)
|
||||
bool operator<<(std::array<const unsigned char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator<<(std::array<const signed char, N> const& input)
|
||||
bool operator<<(std::array<const signed char, N> const& input) BOOST_NOEXCEPT
|
||||
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
|
||||
#endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
|
||||
|
||||
@@ -1723,10 +1735,10 @@ namespace boost {
|
||||
inline bool shr_xchar(T& output)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
|
||||
"boost::lexical_cast does not support conversions from wchar_t to char types."
|
||||
"boost::lexical_cast does not support narrowing of character types."
|
||||
"Use boost::locale instead" );
|
||||
bool const ok = (finish - start == 1);
|
||||
if(ok) {
|
||||
if (ok) {
|
||||
CharT out;
|
||||
Traits::assign(out, *start);
|
||||
output = static_cast<T>(out);
|
||||
@@ -1770,7 +1782,7 @@ namespace boost {
|
||||
|
||||
private:
|
||||
template <std::size_t N, class ArrayT>
|
||||
bool shr_std_array(ArrayT& output, boost::mpl::bool_<true> /*is_T_char_tag*/)
|
||||
bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT
|
||||
{
|
||||
using namespace std;
|
||||
const std::size_t size = finish - start;
|
||||
@@ -1779,22 +1791,16 @@ namespace boost {
|
||||
}
|
||||
|
||||
memcpy(output.begin(), start, size * sizeof(CharT));
|
||||
*(output.begin() + size) = static_cast<CharT>(0);
|
||||
*(output.begin() + size) = Traits::to_char_type(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <std::size_t N, class ArrayT>
|
||||
bool shr_std_array(ArrayT& output, boost::mpl::bool_<false> /*is_T_char_tag*/)
|
||||
{
|
||||
return shr_using_base_class(output); // Array consist of non character types or unmatching character type
|
||||
}
|
||||
public:
|
||||
|
||||
template <std::size_t N>
|
||||
bool operator>>(boost::array<CharT, N>& output)
|
||||
bool operator>>(boost::array<CharT, N>& output) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef boost::mpl::bool_<true> tag_type;
|
||||
return shr_std_array<N>(output, tag_type());
|
||||
return shr_std_array<N>(output);
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
@@ -1811,10 +1817,9 @@ namespace boost {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
|
||||
template <std::size_t N>
|
||||
bool operator>>(std::array<CharT, N>& output)
|
||||
bool operator>>(std::array<CharT, N>& output) BOOST_NOEXCEPT
|
||||
{
|
||||
typedef boost::mpl::bool_<true> tag_type;
|
||||
return shr_std_array<N>(output, tag_type());
|
||||
return shr_std_array<N>(output);
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
@@ -1836,7 +1841,7 @@ namespace boost {
|
||||
* case "1" || "+1": output = true; return true;
|
||||
* default: return false;
|
||||
*/
|
||||
bool operator>>(bool& output)
|
||||
bool operator>>(bool& output) BOOST_NOEXCEPT
|
||||
{
|
||||
CharT const zero = lcast_char_constants<CharT>::zero;
|
||||
CharT const plus = lcast_char_constants<CharT>::plus;
|
||||
@@ -1886,10 +1891,10 @@ namespace boost {
|
||||
CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
|
||||
if ( return_value &&
|
||||
(
|
||||
*(finish-1) == lowercase_e // 1.0e
|
||||
|| *(finish-1) == capital_e // 1.0E
|
||||
|| *(finish-1) == minus // 1.0e- or 1.0E-
|
||||
|| *(finish-1) == plus // 1.0e+ or 1.0E+
|
||||
Traits::eq(*(finish-1), lowercase_e) // 1.0e
|
||||
|| Traits::eq(*(finish-1), capital_e) // 1.0E
|
||||
|| Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E-
|
||||
|| Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+
|
||||
)
|
||||
) return false;
|
||||
|
||||
@@ -2145,7 +2150,7 @@ namespace boost {
|
||||
template <typename Source>
|
||||
struct lexical_cast_copy
|
||||
{
|
||||
static inline Source lexical_cast_impl(const Source &arg)
|
||||
static inline const Source& lexical_cast_impl(const Source &arg) BOOST_NOEXCEPT
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
@@ -2295,6 +2300,17 @@ namespace boost {
|
||||
return caster_type::lexical_cast_impl(arg);
|
||||
}
|
||||
|
||||
template <typename Target, typename CharType>
|
||||
inline Target lexical_cast(const CharType* chars, std::size_t count)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(::boost::detail::is_char_or_wchar<CharType>::value,
|
||||
"CharType must be a character or wide character type");
|
||||
|
||||
return ::boost::lexical_cast<Target>(
|
||||
::boost::iterator_range<const CharType*>(chars, chars + count)
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
@@ -73,6 +73,7 @@ void test_conversion_from_wstring();
|
||||
void test_conversion_to_wstring();
|
||||
void test_bad_lexical_cast();
|
||||
void test_no_whitespace_stripping();
|
||||
void test_volatile_types_conversions();
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
void test_traits();
|
||||
void test_wtraits();
|
||||
@@ -108,6 +109,7 @@ unit_test::test_suite *init_unit_test_suite(int, char *[])
|
||||
#endif
|
||||
suite->add(BOOST_TEST_CASE(test_bad_lexical_cast));
|
||||
suite->add(BOOST_TEST_CASE(test_no_whitespace_stripping));
|
||||
suite->add(BOOST_TEST_CASE(test_volatile_types_conversions));
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
suite->add(BOOST_TEST_CASE(&test_traits));
|
||||
suite->add(BOOST_TEST_CASE(&test_wtraits));
|
||||
@@ -435,6 +437,17 @@ void test_no_whitespace_stripping()
|
||||
BOOST_CHECK_THROW(lexical_cast<int>("123 "), bad_lexical_cast);
|
||||
}
|
||||
|
||||
void test_volatile_types_conversions()
|
||||
{
|
||||
volatile int i1 = 100000;
|
||||
BOOST_CHECK_EQUAL("100000", boost::lexical_cast<std::string>(i1));
|
||||
|
||||
volatile const int i2 = 100000;
|
||||
BOOST_CHECK_EQUAL("100000", boost::lexical_cast<std::string>(i2));
|
||||
|
||||
volatile const long int i3 = 1000000;
|
||||
BOOST_CHECK_EQUAL("1000000", boost::lexical_cast<std::string>(i3));
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
void test_traits()
|
||||
|
@@ -28,7 +28,7 @@ using namespace boost;
|
||||
using std::cout;
|
||||
|
||||
|
||||
int test_main( int argc, char * argv[] )
|
||||
int test_main( int , char * [] )
|
||||
{
|
||||
|
||||
# ifdef NDEBUG
|
||||
@@ -96,5 +96,6 @@ int test_main( int argc, char * argv[] )
|
||||
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
|
||||
(void)ul; // Supressing GCC warning about set but unused wariable
|
||||
return 0 ;
|
||||
}
|
||||
|
@@ -46,24 +46,37 @@ template <class RngT>
|
||||
void do_test_iterator_range_impl(const RngT& rng)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(lexical_cast<int>(rng), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<int>(rng.begin(), rng.size()), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(rng), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned int>(rng.begin(), rng.size()), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<short>(rng), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<short>(rng.begin(), rng.size()), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(rng), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned short>(rng.begin(), rng.size()), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long int>(rng), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long int>(rng.begin(), rng.size()), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng.begin(), rng.size()), 1u);
|
||||
|
||||
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
|
||||
BOOST_CHECK_EQUAL(lexical_cast<float>(rng), 1.0f);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<float>(rng.begin(), rng.size()), 1.0f);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<double>(rng), 1.0);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<double>(rng.begin(), rng.size()), 1.0);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long double>(rng), 1.0L);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<long double>(rng.begin(), rng.size()), 1.0L);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(rng), 1);
|
||||
#endif
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
BOOST_CHECK_EQUAL(lexical_cast<boost::ulong_long_type>(rng), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<boost::ulong_long_type>(rng.begin(), rng.size()), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng.begin(), rng.size()), 1);
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng.begin(), rng.size()), 1u);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng), 1);
|
||||
BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng.begin(), rng.size()), 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user