Added lexical_cast(const CharType* chars, std::size_t count) function overload (refs #6430 and refs #6663)

Fixed GCC warning in numeric_cast_test.cpp

[SVN r80291]
This commit is contained in:
Antony Polukhin
2012-08-28 20:31:16 +00:00
parent 63acf4f174
commit d08477900d
4 changed files with 46 additions and 2 deletions

View File

@@ -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 buf_t buffer = boost::lexical_cast<buf_t>(i); // No dynamic memory allocation
puts(buffer.begin(), file); 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.c_str() + pos, n);
}
``
[endsect] [endsect]
[section Synopsis] [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. 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. * 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. * 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::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>` * `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: [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 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`? * [*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.c_str(), str.c_str() + 2));` or `lexical_cast<int>(str.c_str(), 2);`.
[endsect] [endsect]
[section Changes] [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 :] * [*boost 1.51.0 :]
* Better performance, less memory usage for `boost::array<character_type, N>` and `std::array<character_type, N>` conversions. * Better performance, less memory usage for `boost::array<character_type, N>` and `std::array<character_type, N>` conversions.

View File

@@ -2300,6 +2300,17 @@ namespace boost {
return caster_type::lexical_cast_impl(arg); 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 } // namespace boost
#else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

View File

@@ -96,5 +96,6 @@ int test_main( int , char * [] )
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; } { cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
BOOST_CHECK ( caught_exception ); BOOST_CHECK ( caught_exception );
(void)ul; // Supressing GCC warning about set but unused wariable
return 0 ; return 0 ;
} }

View File

@@ -46,24 +46,37 @@ template <class RngT>
void do_test_iterator_range_impl(const RngT& rng) void do_test_iterator_range_impl(const RngT& rng)
{ {
BOOST_CHECK_EQUAL(lexical_cast<int>(rng), 1); 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), 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), 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), 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), 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), 1u);
BOOST_CHECK_EQUAL(lexical_cast<unsigned long int>(rng.begin(), rng.size()), 1u);
#ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES
BOOST_CHECK_EQUAL(lexical_cast<float>(rng), 1.0f); 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), 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), 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); BOOST_CHECK_EQUAL(lexical_cast<class_with_user_defined_sream_operators>(rng), 1);
#endif #endif
#if defined(BOOST_HAS_LONG_LONG) #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), 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), 1);
BOOST_CHECK_EQUAL(lexical_cast<boost::long_long_type>(rng.begin(), rng.size()), 1);
#elif defined(BOOST_HAS_MS_INT64) #elif defined(BOOST_HAS_MS_INT64)
BOOST_CHECK_EQUAL(lexical_cast<unsigned __int64>(rng), 1u); 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), 1);
BOOST_CHECK_EQUAL(lexical_cast<__int64>(rng.begin(), rng.size()), 1);
#endif #endif
} }