diff --git a/libcxx/include/string_view b/libcxx/include/string_view --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -331,7 +331,7 @@ size_type length() const _NOEXCEPT { return __size; } _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT { return numeric_limits::max(); } + size_type max_size() const _NOEXCEPT { return (numeric_limits::max() - sizeof(*this)) / sizeof(value_type); } _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size == 0; } diff --git a/libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp b/libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp --- a/libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp +++ b/libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "test_macros.h" @@ -42,6 +43,18 @@ assert ( sv1.size() == sv1.length()); assert ( sv1.max_size() > sv1.size()); } + + // Sanity check max_size(). It has to be smaller than numeric_limits::max(), + // because representing std::string_view requires _at least_ one byte. In reality it + // needs a lot more than that, however any implementation that fails this check probably + // has a bug. + { + typedef typename SV::value_type CharT; + typedef typename SV::size_type Size; + SV sv; + assert(sv.max_size() < std::numeric_limits::max()); + LIBCPP_ASSERT(sv.max_size() == (std::numeric_limits::max() - sizeof(SV)) / sizeof(CharT)); + } } template