diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a46e67..7cf1e04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,6 @@ target_link_libraries(boost_lexical_cast Boost::core Boost::integer Boost::numeric_conversion - Boost::range Boost::throw_exception Boost::type_traits ) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index f8adc4f..d0b4d72 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -27,7 +27,8 @@ #define BOOST_LCAST_NO_WCHAR_T #endif -#include +#include + #include #include @@ -49,7 +50,7 @@ namespace boost inline Target lexical_cast(const char* chars, std::size_t count) { return ::boost::lexical_cast( - ::boost::iterator_range(chars, chars + count) + ::boost::conversion::detail::make_buffer_view(chars, chars + count) ); } @@ -57,7 +58,7 @@ namespace boost inline Target lexical_cast(const unsigned char* chars, std::size_t count) { return ::boost::lexical_cast( - ::boost::iterator_range(chars, chars + count) + ::boost::conversion::detail::make_buffer_view(chars, chars + count) ); } @@ -65,7 +66,7 @@ namespace boost inline Target lexical_cast(const signed char* chars, std::size_t count) { return ::boost::lexical_cast( - ::boost::iterator_range(chars, chars + count) + ::boost::conversion::detail::make_buffer_view(chars, chars + count) ); } @@ -74,7 +75,7 @@ namespace boost inline Target lexical_cast(const wchar_t* chars, std::size_t count) { return ::boost::lexical_cast( - ::boost::iterator_range(chars, chars + count) + ::boost::conversion::detail::make_buffer_view(chars, chars + count) ); } #endif @@ -82,14 +83,14 @@ namespace boost inline Target lexical_cast(const char16_t* chars, std::size_t count) { return ::boost::lexical_cast( - ::boost::iterator_range(chars, chars + count) + ::boost::conversion::detail::make_buffer_view(chars, chars + count) ); } template inline Target lexical_cast(const char32_t* chars, std::size_t count) { return ::boost::lexical_cast( - ::boost::iterator_range(chars, chars + count) + ::boost::conversion::detail::make_buffer_view(chars, chars + count) ); } diff --git a/include/boost/lexical_cast/detail/buffer_view.hpp b/include/boost/lexical_cast/detail/buffer_view.hpp new file mode 100644 index 0000000..888dd7e --- /dev/null +++ b/include/boost/lexical_cast/detail/buffer_view.hpp @@ -0,0 +1,59 @@ +// Copyright Antony Polukhin, 2011-2023. +// +// 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) + +#ifndef BOOST_LEXICAL_CAST_DETAIL_BUFFER_VIEW_HPP +#define BOOST_LEXICAL_CAST_DETAIL_BUFFER_VIEW_HPP + +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include + +namespace boost { namespace conversion { namespace detail { + + template < typename CharT > + struct buffer_view { + const CharT* begin; + const CharT* end; + }; + + template < typename CharT > + buffer_view make_buffer_view(const CharT* begin, const CharT* end) { + return buffer_view{begin, end}; + } + + inline buffer_view make_buffer_view(const signed char* begin, const signed char* end) { + return buffer_view{ + reinterpret_cast(begin), + reinterpret_cast(end) + }; + } + + inline buffer_view make_buffer_view(const unsigned char* begin, const unsigned char* end) { + return buffer_view{ + reinterpret_cast(begin), + reinterpret_cast(end) + }; + } + + template< typename CharT, typename Elem, typename Traits > + std::basic_ostream& operator<<( + std::basic_ostream& os, + buffer_view r) + { + while (r.begin != r.end) { + os << r.begin[0]; + ++r.begin; + } + return os; + } + +}}} // namespace boost::conversion::detail + +#endif // BOOST_LEXICAL_CAST_DETAIL_BUFFER_VIEW_HPP + diff --git a/include/boost/lexical_cast/detail/converter_lexical.hpp b/include/boost/lexical_cast/detail/converter_lexical.hpp index 7ba548d..fdc8f1f 100644 --- a/include/boost/lexical_cast/detail/converter_lexical.hpp +++ b/include/boost/lexical_cast/detail/converter_lexical.hpp @@ -44,7 +44,7 @@ #include -#include +#include #include #include @@ -54,6 +54,8 @@ namespace boost { // Forward declaration template class array; + template + class iterator_range; namespace detail // normalize_single_byte_char { @@ -110,6 +112,12 @@ namespace boost { boost::detail::deduce_character_type_later< const Char* > > {}; + template < typename Char > + struct stream_char_common< boost::conversion::detail::buffer_view< Char > > + { + typedef Char type; + }; + template < typename Char > struct stream_char_common< boost::iterator_range< Char* > >: public boost::conditional< boost::detail::is_character< Char >::value, diff --git a/include/boost/lexical_cast/detail/converter_lexical_streams.hpp b/include/boost/lexical_cast/detail/converter_lexical_streams.hpp index 430e373..ad778ef 100644 --- a/include/boost/lexical_cast/detail/converter_lexical_streams.hpp +++ b/include/boost/lexical_cast/detail/converter_lexical_streams.hpp @@ -69,11 +69,12 @@ #include #include #include -#include +#include #include #include #include #include +#include #ifndef BOOST_NO_CWCHAR # include #endif @@ -83,6 +84,8 @@ namespace boost { // Forward declaration template class array; + template + class iterator_range; namespace detail // basic_unlockedbuf { @@ -217,7 +220,11 @@ namespace boost { bool shl_char_array_limited(CharT const* str, std::size_t max_size) noexcept { start = str; - finish = std::find(start, start + max_size, Traits::to_char_type(0)); + finish = start; + const auto zero = Traits::to_char_type(0); + while (finish < start + max_size && zero != *finish) { + ++ finish; + } return true; } @@ -363,30 +370,15 @@ namespace boost { return true; } - template - typename boost::disable_if, bool>::type - operator<<(const iterator_range& rng) noexcept { - return (*this) << iterator_range(rng.begin(), rng.end()); - } - - bool operator<<(const iterator_range& rng) noexcept { - start = rng.begin(); - finish = rng.end(); + bool operator<<(boost::conversion::detail::buffer_view rng) noexcept { + start = rng.begin; + finish = rng.end; return true; } - bool operator<<(const iterator_range& rng) noexcept { - return (*this) << iterator_range( - reinterpret_cast(rng.begin()), - reinterpret_cast(rng.end()) - ); - } - - bool operator<<(const iterator_range& rng) noexcept { - return (*this) << iterator_range( - reinterpret_cast(rng.begin()), - reinterpret_cast(rng.end()) - ); + template + bool operator<<(const iterator_range& rng) noexcept { + return (*this) << boost::conversion::detail::make_buffer_view(rng.begin(), rng.end()); } bool operator<<(char ch) { return shl_char(ch); } diff --git a/include/boost/lexical_cast/try_lexical_convert.hpp b/include/boost/lexical_cast/try_lexical_convert.hpp index 3c0d36d..962d950 100644 --- a/include/boost/lexical_cast/try_lexical_convert.hpp +++ b/include/boost/lexical_cast/try_lexical_convert.hpp @@ -39,11 +39,11 @@ #include #include +#include #include #include #include -#include #include namespace boost { @@ -209,7 +209,8 @@ namespace boost { "This overload of try_lexical_convert is meant to be used only with arrays of characters." ); return ::boost::conversion::detail::try_lexical_convert( - ::boost::iterator_range(chars, chars + count), result + ::boost::conversion::detail::make_buffer_view(chars, chars + count), + result ); }