From d08477900d78bff3b95726268249e8194e422cef Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Tue, 28 Aug 2012 20:31:16 +0000 Subject: [PATCH] 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] --- doc/lexical_cast.qbk | 23 +++++++++++++++++++++-- include/boost/lexical_cast.hpp | 11 +++++++++++ numeric_cast_test.cpp | 1 + test/lexical_cast_iterator_range_test.cpp | 13 +++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/doc/lexical_cast.qbk b/doc/lexical_cast.qbk index eb7ba21..65516e1 100644 --- a/doc/lexical_cast.qbk +++ b/doc/lexical_cast.qbk @@ -79,6 +79,13 @@ Following example converts some number and puts it to file: buf_t buffer = boost::lexical_cast(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(s.c_str() + 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 + 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`, where `WideCharPtr` is a pointer to wide-character or pointer to const wide-character * `boost::array` and `std::array`, `boost::array` and `std::array` + [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(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(make_iterator_range(str.c_str(), str.c_str() + 2));` or `lexical_cast(str.c_str(), 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` and `std::array` conversions. diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index b164068..9fb5626 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -2300,6 +2300,17 @@ namespace boost { return caster_type::lexical_cast_impl(arg); } + template + inline Target lexical_cast(const CharType* chars, std::size_t count) + { + BOOST_STATIC_ASSERT_MSG(::boost::detail::is_char_or_wchar::value, + "CharType must be a character or wide character type"); + + return ::boost::lexical_cast( + ::boost::iterator_range(chars, chars + count) + ); + } + } // namespace boost #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/numeric_cast_test.cpp b/numeric_cast_test.cpp index 51393b9..7d569a4 100644 --- a/numeric_cast_test.cpp +++ b/numeric_cast_test.cpp @@ -96,5 +96,6 @@ int test_main( int , char * [] ) { 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 ; } diff --git a/test/lexical_cast_iterator_range_test.cpp b/test/lexical_cast_iterator_range_test.cpp index 50b86ff..59e8eae 100644 --- a/test/lexical_cast_iterator_range_test.cpp +++ b/test/lexical_cast_iterator_range_test.cpp @@ -46,24 +46,37 @@ template void do_test_iterator_range_impl(const RngT& rng) { BOOST_CHECK_EQUAL(lexical_cast(rng), 1); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1); BOOST_CHECK_EQUAL(lexical_cast(rng), 1u); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1u); BOOST_CHECK_EQUAL(lexical_cast(rng), 1); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1); BOOST_CHECK_EQUAL(lexical_cast(rng), 1u); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1u); BOOST_CHECK_EQUAL(lexical_cast(rng), 1); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1); BOOST_CHECK_EQUAL(lexical_cast(rng), 1u); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1u); #ifdef BOOST_STL_SUPPORTS_NEW_UNICODE_LOCALES BOOST_CHECK_EQUAL(lexical_cast(rng), 1.0f); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1.0f); BOOST_CHECK_EQUAL(lexical_cast(rng), 1.0); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1.0); BOOST_CHECK_EQUAL(lexical_cast(rng), 1.0L); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1.0L); BOOST_CHECK_EQUAL(lexical_cast(rng), 1); #endif #if defined(BOOST_HAS_LONG_LONG) BOOST_CHECK_EQUAL(lexical_cast(rng), 1u); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1u); BOOST_CHECK_EQUAL(lexical_cast(rng), 1); + BOOST_CHECK_EQUAL(lexical_cast(rng.begin(), rng.size()), 1); #elif defined(BOOST_HAS_MS_INT64) BOOST_CHECK_EQUAL(lexical_cast(rng), 1u); + BOOST_CHECK_EQUAL(lexical_cast(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 }