[libcxx-commits] [PATCH] D114395: [libc++] Fix the return value of max_size()

Louis Dionne via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Nov 22 13:47:19 PST 2021


ldionne created this revision.
ldionne requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

I assume nobody ever uses std::string_view::max_size() outside of
testing. However, we should still return a value that is based on
something with a reasonable rationale. Previously, we would forget
to take into account the size of the character type stored in the
string. This patch factors both that and the size of the string_view
itself into account.

Thanks to @mclow.lists for pointing out this issue.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114395

Files:
  libcxx/include/string_view
  libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp


Index: libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp
===================================================================
--- libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp
+++ libcxx/test/std/strings/string.view/string.view.capacity/capacity.pass.cpp
@@ -16,6 +16,7 @@
 
 #include <string_view>
 #include <cassert>
+#include <limits>
 
 #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<size_type>::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<Size>::max());
+        LIBCPP_ASSERT(sv.max_size() == (std::numeric_limits<Size>::max() - sizeof(SV)) / sizeof(CharT));
+    }
 }
 
 template<typename CharT>
Index: libcxx/include/string_view
===================================================================
--- libcxx/include/string_view
+++ 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<size_type>::max(); }
+    size_type max_size() const _NOEXCEPT { return (numeric_limits<size_type>::max() - sizeof(*this)) / sizeof(value_type); }
 
     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
     bool empty()         const _NOEXCEPT { return __size == 0; }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114395.389034.patch
Type: text/x-patch
Size: 1816 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211122/466e20ab/attachment.bin>


More information about the libcxx-commits mailing list