|
@@ -77,7 +77,6 @@
|
|
|
#include <boost/type_traits/is_const.hpp>
|
|
|
#include <boost/type_traits/is_reference.hpp>
|
|
|
#include <boost/container/container_fwd.hpp>
|
|
|
-#include <boost/core/noncopyable.hpp>
|
|
|
#include <boost/core/enable_if.hpp>
|
|
|
#ifndef BOOST_NO_CWCHAR
|
|
|
# include <cwchar>
|
|
@@ -89,6 +88,9 @@ namespace boost {
|
|
|
class array;
|
|
|
template<class IteratorT>
|
|
|
class iterator_range;
|
|
|
+
|
|
|
+ // forward declaration of boost::basic_string_view from Utility
|
|
|
+ template<class Ch, class Tr> class basic_string_view;
|
|
|
}
|
|
|
|
|
|
namespace boost { namespace detail { namespace lcast {
|
|
@@ -105,7 +107,7 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
, class Traits
|
|
|
, std::size_t CharacterBufferSize
|
|
|
>
|
|
|
- class optimized_src_stream: boost::noncopyable {
|
|
|
+ class optimized_src_stream {
|
|
|
CharT buffer[CharacterBufferSize];
|
|
|
|
|
|
// After the `stream_in(` finishes, `[start, finish)` is
|
|
@@ -113,6 +115,11 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
const CharT* start;
|
|
|
const CharT* finish;
|
|
|
public:
|
|
|
+ optimized_src_stream(optimized_src_stream&&) = delete;
|
|
|
+ optimized_src_stream(const optimized_src_stream&) = delete;
|
|
|
+ optimized_src_stream& operator=(optimized_src_stream&&) = delete;
|
|
|
+ optimized_src_stream& operator=(const optimized_src_stream&) = delete;
|
|
|
+
|
|
|
optimized_src_stream() noexcept
|
|
|
: start(buffer)
|
|
|
, finish(buffer + CharacterBufferSize)
|
|
@@ -191,7 +198,6 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
}
|
|
|
|
|
|
bool shl_real_type(float val, char* begin) {
|
|
|
- using namespace std;
|
|
|
const double val_as_double = val;
|
|
|
finish = start +
|
|
|
boost::core::snprintf(begin, CharacterBufferSize,
|
|
@@ -200,7 +206,6 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
}
|
|
|
|
|
|
bool shl_real_type(double val, char* begin) {
|
|
|
- using namespace std;
|
|
|
finish = start +
|
|
|
boost::core::snprintf(begin, CharacterBufferSize,
|
|
|
"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val);
|
|
@@ -209,7 +214,6 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
|
|
|
#ifndef __MINGW32__
|
|
|
bool shl_real_type(long double val, char* begin) {
|
|
|
- using namespace std;
|
|
|
finish = start +
|
|
|
boost::core::snprintf(begin, CharacterBufferSize,
|
|
|
"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double>()), val );
|
|
@@ -221,41 +225,55 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
|
|
|
+#if !defined(BOOST_LCAST_NO_WCHAR_T)
|
|
|
bool shl_real_type(float val, wchar_t* begin) {
|
|
|
- using namespace std;
|
|
|
const double val_as_double = val;
|
|
|
- finish = start + swprintf(begin, CharacterBufferSize,
|
|
|
- L"%.*g",
|
|
|
- static_cast<int>(boost::detail::lcast_get_precision<float >()),
|
|
|
- val_as_double );
|
|
|
+ finish = start + boost::core::swprintf(
|
|
|
+ begin, CharacterBufferSize, L"%.*g",
|
|
|
+ static_cast<int>(boost::detail::lcast_get_precision<float >()),
|
|
|
+ val_as_double
|
|
|
+ );
|
|
|
return finish > start;
|
|
|
}
|
|
|
|
|
|
bool shl_real_type(double val, wchar_t* begin) {
|
|
|
- using namespace std;
|
|
|
- finish = start + swprintf(begin, CharacterBufferSize,
|
|
|
- L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
|
|
|
+ finish = start + boost::core::swprintf(
|
|
|
+ begin, CharacterBufferSize, L"%.*g",
|
|
|
+ static_cast<int>(boost::detail::lcast_get_precision<double>()),
|
|
|
+ val
|
|
|
+ );
|
|
|
return finish > start;
|
|
|
}
|
|
|
|
|
|
bool shl_real_type(long double val, wchar_t* begin) {
|
|
|
- using namespace std;
|
|
|
- finish = start + swprintf(begin, CharacterBufferSize,
|
|
|
- L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
|
|
|
+ finish = start + boost::core::swprintf(
|
|
|
+ begin, CharacterBufferSize, L"%.*Lg",
|
|
|
+ static_cast<int>(boost::detail::lcast_get_precision<long double>()),
|
|
|
+ val
|
|
|
+ );
|
|
|
return finish > start;
|
|
|
}
|
|
|
#endif
|
|
|
public:
|
|
|
- template<class Alloc>
|
|
|
- bool stream_in(lcast::exact<std::basic_string<CharT,Traits,Alloc>> x) noexcept {
|
|
|
+ template <class C>
|
|
|
+ using enable_if_compatible_char_t = typename boost::enable_if_c<
|
|
|
+ boost::is_same<const C, const CharT>::value || (
|
|
|
+ boost::is_same<const char, const CharT>::value && (
|
|
|
+ boost::is_same<const C, const unsigned char>::value ||
|
|
|
+ boost::is_same<const C, const signed char>::value
|
|
|
+ )
|
|
|
+ ), bool
|
|
|
+ >::type;
|
|
|
+
|
|
|
+ template<class CharTraits, class Alloc>
|
|
|
+ bool stream_in(lcast::exact<std::basic_string<CharT,CharTraits,Alloc>> x) noexcept {
|
|
|
start = x.payload.data();
|
|
|
finish = start + x.payload.length();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- template<class Alloc>
|
|
|
- bool stream_in(lcast::exact<boost::container::basic_string<CharT,Traits,Alloc>> x) noexcept {
|
|
|
+ template<class CharTraits, class Alloc>
|
|
|
+ bool stream_in(lcast::exact<boost::container::basic_string<CharT,CharTraits,Alloc>> x) noexcept {
|
|
|
start = x.payload.data();
|
|
|
finish = start + x.payload.length();
|
|
|
return true;
|
|
@@ -275,19 +293,12 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
}
|
|
|
|
|
|
template <class C>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<C>::value && sizeof(CharT) == sizeof(C), bool>::type
|
|
|
+ enable_if_compatible_char_t<C>
|
|
|
stream_in(lcast::exact<boost::iterator_range<C*>> x) noexcept {
|
|
|
auto buf = boost::conversion::detail::make_buffer_view(x.payload.begin(), x.payload.end());
|
|
|
return stream_in(lcast::exact<decltype(buf)>{buf});
|
|
|
}
|
|
|
|
|
|
- template <class C>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<C>::value && sizeof(CharT) == sizeof(C), bool>::type
|
|
|
- stream_in(lcast::exact<boost::iterator_range<const C*>> x) noexcept {
|
|
|
- auto buf = boost::conversion::detail::make_buffer_view(x.payload.begin(), x.payload.end());
|
|
|
- return stream_in(lcast::exact<decltype(buf)>{buf});
|
|
|
- }
|
|
|
-
|
|
|
bool stream_in(lcast::exact<char> x) { return shl_char(x.payload); }
|
|
|
bool stream_in(lcast::exact<unsigned char> x) { return shl_char(static_cast<char>(x.payload)); }
|
|
|
bool stream_in(lcast::exact<signed char> x) { return shl_char(static_cast<char>(x.payload)); }
|
|
@@ -297,12 +308,8 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
stream_in(lcast::exact<C> x) { return shl_char(x.payload); }
|
|
|
|
|
|
template <class Type>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<Type>::value && sizeof(CharT) == sizeof(Type), bool>::type
|
|
|
- stream_in(lcast::exact<const Type*> x) { return shl_char_array(reinterpret_cast<CharT const*>(x.payload)); }
|
|
|
-
|
|
|
- template <class Type>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<Type>::value && sizeof(CharT) == sizeof(Type), bool>::type
|
|
|
- stream_in(lcast::exact<Type*> x) { return shl_char_array(reinterpret_cast<CharT*>(x.payload)); }
|
|
|
+ enable_if_compatible_char_t<Type>
|
|
|
+ stream_in(lcast::exact<Type*> x) { return shl_char_array(reinterpret_cast<CharT const*>(x.payload)); }
|
|
|
|
|
|
template <class Type>
|
|
|
typename boost::enable_if_c<boost::is_signed<Type>::value && !boost::is_enum<Type>::value, bool>::type
|
|
@@ -324,27 +331,32 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
}
|
|
|
|
|
|
template <class C, std::size_t N>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<C>::value && sizeof(CharT) == sizeof(C), bool>::type
|
|
|
+ enable_if_compatible_char_t<C>
|
|
|
stream_in(lcast::exact<boost::array<C, N>> x) noexcept {
|
|
|
return shl_char_array_limited(reinterpret_cast<const CharT*>(x.payload.data()), N);
|
|
|
}
|
|
|
|
|
|
template <class C, std::size_t N>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<C>::value && sizeof(CharT) == sizeof(C), bool>::type
|
|
|
- stream_in(lcast::exact<boost::array<const C, N>> x) noexcept {
|
|
|
- return shl_char_array_limited(reinterpret_cast<const CharT*>(x.payload.data()), N);
|
|
|
- }
|
|
|
-
|
|
|
- template <class C, std::size_t N>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<C>::value && sizeof(CharT) == sizeof(C), bool>::type
|
|
|
+ enable_if_compatible_char_t<C>
|
|
|
stream_in(lcast::exact<std::array<C, N>> x) noexcept {
|
|
|
return shl_char_array_limited(reinterpret_cast<const CharT*>(x.payload.data()), N);
|
|
|
}
|
|
|
|
|
|
- template <class C, std::size_t N>
|
|
|
- typename boost::enable_if_c<boost::detail::is_character<C>::value && sizeof(CharT) == sizeof(C), bool>::type
|
|
|
- stream_in(lcast::exact<std::array<const C, N>> x) noexcept {
|
|
|
- return shl_char_array_limited(reinterpret_cast<const CharT*>(x.payload.data()), N);
|
|
|
+#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
|
|
|
+ template <class C, class CharTraits>
|
|
|
+ enable_if_compatible_char_t<C>
|
|
|
+ stream_in(lcast::exact<std::basic_string_view<C, CharTraits>> x) noexcept {
|
|
|
+ start = reinterpret_cast<const CharT*>(x.payload.data());
|
|
|
+ finish = start + x.payload.size();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ template <class C, class CharTraits>
|
|
|
+ enable_if_compatible_char_t<C>
|
|
|
+ stream_in(lcast::exact<boost::basic_string_view<C, CharTraits>> x) noexcept {
|
|
|
+ start = reinterpret_cast<const CharT*>(x.payload.data());
|
|
|
+ finish = start + x.payload.size();
|
|
|
+ return true;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -360,6 +372,11 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
const CharT* start = nullptr;
|
|
|
const CharT* finish = nullptr;
|
|
|
public:
|
|
|
+ ios_src_stream(ios_src_stream&&) = delete;
|
|
|
+ ios_src_stream(const ios_src_stream&) = delete;
|
|
|
+ ios_src_stream& operator=(ios_src_stream&&) = delete;
|
|
|
+ ios_src_stream& operator=(const ios_src_stream&) = delete;
|
|
|
+
|
|
|
ios_src_stream(): out_buffer(), out_stream(&out_buffer) {}
|
|
|
|
|
|
const CharT* cbegin() const noexcept {
|
|
@@ -460,12 +477,17 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
|
|
|
|
|
|
template <class CharT, class Traits>
|
|
|
- class to_target_stream: boost::noncopyable {
|
|
|
+ class to_target_stream {
|
|
|
//`[start, finish)` is the range to output by `operator >>`
|
|
|
const CharT* start;
|
|
|
const CharT* const finish;
|
|
|
|
|
|
public:
|
|
|
+ to_target_stream(to_target_stream&&) = delete;
|
|
|
+ to_target_stream(const to_target_stream&) = delete;
|
|
|
+ to_target_stream& operator=(to_target_stream&&) = delete;
|
|
|
+ to_target_stream& operator=(const to_target_stream&) = delete;
|
|
|
+
|
|
|
to_target_stream(const CharT* begin, const CharT* end) noexcept
|
|
|
: start(begin)
|
|
|
, finish(end)
|
|
@@ -473,6 +495,9 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
|
|
|
private:
|
|
|
template <typename Type>
|
|
|
+#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
|
|
|
+ __attribute__((no_sanitize("unsigned-integer-overflow")))
|
|
|
+#endif
|
|
|
bool shr_unsigned(Type& output) {
|
|
|
if (start == finish) return false;
|
|
|
CharT const minus = lcast_char_constants<CharT>::minus;
|
|
@@ -494,6 +519,9 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
}
|
|
|
|
|
|
template <typename Type>
|
|
|
+#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
|
|
|
+ __attribute__((no_sanitize("unsigned-integer-overflow")))
|
|
|
+#endif
|
|
|
bool shr_signed(Type& output) {
|
|
|
if (start == finish) return false;
|
|
|
CharT const minus = lcast_char_constants<CharT>::minus;
|
|
@@ -625,13 +653,13 @@ namespace boost { namespace detail { namespace lcast {
|
|
|
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
|
|
|
bool stream_out(char32_t& output) { return shr_xchar(output); }
|
|
|
#endif
|
|
|
- template<class Alloc>
|
|
|
- bool stream_out(std::basic_string<CharT,Traits,Alloc>& str) {
|
|
|
+ template<class CharTraits, class Alloc>
|
|
|
+ bool stream_out(std::basic_string<CharT,CharTraits,Alloc>& str) {
|
|
|
str.assign(start, finish); return true;
|
|
|
}
|
|
|
|
|
|
- template<class Alloc>
|
|
|
- bool stream_out(boost::container::basic_string<CharT,Traits,Alloc>& str) {
|
|
|
+ template<class CharTraits, class Alloc>
|
|
|
+ bool stream_out(boost::container::basic_string<CharT,CharTraits,Alloc>& str) {
|
|
|
str.assign(start, finish); return true;
|
|
|
}
|
|
|
|