diff --git a/include/boost/lexical_cast/detail/converter_lexical_streams.hpp b/include/boost/lexical_cast/detail/converter_lexical_streams.hpp index f2e8e08..d7e5b31 100644 --- a/include/boost/lexical_cast/detail/converter_lexical_streams.hpp +++ b/include/boost/lexical_cast/detail/converter_lexical_streams.hpp @@ -96,6 +96,16 @@ namespace boost { namespace boost { namespace detail { namespace lcast { + template + using enable_if_compatible_char_t = typename std::enable_if< + std::is_same::value || ( + std::is_same::value && ( + std::is_same::value || + std::is_same::value + ) + ), bool + >::type; + template struct exact { static_assert(!std::is_const::value, ""); @@ -256,16 +266,6 @@ namespace boost { namespace detail { namespace lcast { } #endif public: - template - using enable_if_compatible_char_t = typename std::enable_if< - std::is_same::value || ( - std::is_same::value && ( - std::is_same::value || - std::is_same::value - ) - ), bool - >::type; - template bool stream_in(lcast::exact> x) noexcept { start = x.payload.data(); @@ -294,7 +294,7 @@ namespace boost { namespace detail { namespace lcast { } template - enable_if_compatible_char_t + enable_if_compatible_char_t stream_in(lcast::exact> x) noexcept { auto buf = boost::conversion::detail::make_buffer_view(x.payload.begin(), x.payload.end()); return stream_in(lcast::exact{buf}); @@ -311,7 +311,7 @@ namespace boost { namespace detail { namespace lcast { #endif template - enable_if_compatible_char_t + enable_if_compatible_char_t stream_in(lcast::exact x) { return shl_char_array(reinterpret_cast(x.payload)); } template @@ -334,20 +334,20 @@ namespace boost { namespace detail { namespace lcast { } template - enable_if_compatible_char_t + enable_if_compatible_char_t stream_in(lcast::exact> x) noexcept { return shl_char_array_limited(reinterpret_cast(x.payload.data()), N); } template - enable_if_compatible_char_t + enable_if_compatible_char_t stream_in(lcast::exact> x) noexcept { return shl_char_array_limited(reinterpret_cast(x.payload.data()), N); } #ifndef BOOST_NO_CXX17_HDR_STRING_VIEW template - enable_if_compatible_char_t + enable_if_compatible_char_t stream_in(lcast::exact> x) noexcept { start = reinterpret_cast(x.payload.data()); finish = start + x.payload.size(); @@ -355,7 +355,7 @@ namespace boost { namespace detail { namespace lcast { } #endif template - enable_if_compatible_char_t + enable_if_compatible_char_t stream_in(lcast::exact> x) noexcept { start = reinterpret_cast(x.payload.data()); finish = start + x.payload.size(); @@ -667,14 +667,14 @@ namespace boost { namespace detail { namespace lcast { } template - bool stream_out(std::array& output) noexcept { - static_assert(sizeof(C) == sizeof(CharT), ""); + enable_if_compatible_char_t + stream_out(std::array& output) noexcept { return shr_std_array(output); } template - bool stream_out(boost::array& output) noexcept { - static_assert(sizeof(C) == sizeof(CharT), ""); + enable_if_compatible_char_t + stream_out(boost::array& output) noexcept { return shr_std_array(output); } diff --git a/test/arrays_test.cpp b/test/arrays_test.cpp index 298ec86..ea09039 100644 --- a/test/arrays_test.cpp +++ b/test/arrays_test.cpp @@ -24,6 +24,101 @@ using namespace boost; #define BOOST_LC_RUNU32 #endif +namespace user_namespace { + +struct user_type { + char payload; +}; + +template +inline std::ostream& operator<<(std::ostream& os, const boost::array& array) { + for (const auto& x : array) { + os << '@' << x.payload; + } + return os; +} + +template +inline std::ostream& operator<<(std::ostream& os, const std::array& array) { + for (const auto& x : array) { + os << '@' << x.payload; + } + return os; +} + +template +inline std::istream& operator>>(std::istream& is, boost::array& array) { + for (auto& x : array) { + char at{}; + is >> at >> x.payload; + BOOST_TEST_EQ(at, '@'); + } + return is; +} + +template +inline std::istream& operator>>(std::istream& is, std::array& array) { + for (auto& x : array) { + char at{}; + is >> at >> x.payload; + } + return is; +} + + + +struct another_user_type { + another_user_type() + : payload('\0') + , payload1('-') + {} + + another_user_type(char in_payload, char in_payload1) + : payload(in_payload) + , payload1(in_payload1) + {} + + char payload; + char payload1; +}; + +template +inline std::ostream& operator<<(std::ostream& os, const boost::array& array) { + for (const auto& x : array) { + os << '@' << x.payload; + } + return os; +} + +template +inline std::ostream& operator<<(std::ostream& os, const std::array& array) { + for (const auto& x : array) { + os << '@' << x.payload; + } + return os; +} + +template +inline std::istream& operator>>(std::istream& is, boost::array& array) { + for (auto& x : array) { + char at{}; + is >> at >> x.payload; + BOOST_TEST_EQ(at, '@'); + } + return is; +} + +template +inline std::istream& operator>>(std::istream& is, std::array& array) { + for (auto& x : array) { + char at{}; + is >> at >> x.payload; + } + return is; +} + +} + template