From 98ed4a79e930ae0ce3972b9277c4545704bbad82 Mon Sep 17 00:00:00 2001
From: fhgffy <102001626+fhgffy@users.noreply.github.com>
Date: Fri, 2 Oct 2026 09:27:12 -0700
Subject: [PATCH] Fix empty string-view construction and assignment
---
include/boost/container/string.hpp | 11 +++++--
test/string_view_compat_test.cpp | 47 +++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp
index 5793acfe..b29ba965 100644
--- a/include/boost/container/string.hpp
+++ b/include/boost/container/string.hpp
@@ -838,7 +838,7 @@ class basic_string
: base_t()
{
this->priv_terminate_string();
- this->assign(s, n); // assign checks for s != 0
+ this->assign(s, n); // assign checks for s != 0 when n != 0
}
//! Effects: Constructs a basic_string taking the allocator as parameter,
@@ -847,7 +847,7 @@ class basic_string
: base_t(a)
{
this->priv_terminate_string();
- this->assign(s, n); // assign checks for s != 0
+ this->assign(s, n); // assign checks for s != 0 when n != 0
}
//! Effects: Constructs a basic_string with a default-constructed allocator,
@@ -1652,6 +1652,7 @@ class basic_string
}
//! Requires: s points to an array of at least n elements of CharT.
+ //! If n is zero, s may be null.
//!
//! Effects: Replaces the string controlled by *this with a string of
//! length n whose elements are a copy of those pointed to by s.
@@ -1661,7 +1662,11 @@ class basic_string
//! Returns: *this
basic_string& assign(const CharT* s, size_type n)
{
- BOOST_ASSERT(s != 0);
+ BOOST_ASSERT(s != 0 || n == 0);
+ if(n == 0){
+ this->clear();
+ return *this;
+ }
return this->assign(s, s + difference_type(n));
}
diff --git a/test/string_view_compat_test.cpp b/test/string_view_compat_test.cpp
index 31b2acf8..d0ca2944 100644
--- a/test/string_view_compat_test.cpp
+++ b/test/string_view_compat_test.cpp
@@ -172,6 +172,49 @@ void assign_test()
BOOST_TEST(sv == s);
}
+template
+void empty_assign_test()
+{
+ typedef typename StringViewType::value_type char_type;
+ typedef boost::container::basic_string string_type;
+ const char_type empty[] = { char_type(0) };
+ const char_type value = char_type('y');
+ const StringViewType views[] = { StringViewType(), StringViewType(empty) };
+ const std::size_t sizes[] = { 0u, 7u, 128u };
+ for(std::size_t i = 0; i != sizeof(views)/sizeof(views[0]); ++i){
+ const StringViewType sv = views[i];
+ string_type constructed(sv);
+ BOOST_TEST(constructed.empty());
+ BOOST_TEST(constructed.c_str()[0] == char_type(0));
+ string_type constructed_with_allocator(sv, constructed.get_allocator());
+ BOOST_TEST(constructed_with_allocator.empty());
+ BOOST_TEST(constructed_with_allocator.c_str()[0] == char_type(0));
+
+ for(std::size_t j = 0; j != sizeof(sizes)/sizeof(sizes[0]); ++j){
+ string_type s(sizes[j], char_type('x'));
+ const std::size_t capacity = s.capacity();
+ BOOST_TEST(&s.assign(sv) == &s);
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.c_str()[0] == char_type(0));
+ BOOST_TEST(s.capacity() == capacity);
+
+ s.assign(sizes[j], char_type('x'));
+ BOOST_TEST(&(s = sv) == &s);
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.c_str()[0] == char_type(0));
+
+ s.assign(sizes[j], char_type('x'));
+ BOOST_TEST(&s.assign(sv.data(), sv.size()) == &s);
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.c_str()[0] == char_type(0));
+
+ s.assign(StringViewType(&value, 1u));
+ BOOST_TEST(s.size() == 1u);
+ BOOST_TEST(s[0] == value);
+ }
+ }
+}
+
template
void plus_equal_test()
{
@@ -310,6 +353,7 @@ void test_all()
constructor_test();
assignment_test();
assign_test();
+ empty_assign_test();
plus_equal_test();
append_test();
insert_test();
@@ -327,10 +371,11 @@ void test_all()
int main()
{
test_all();
+ empty_assign_test();
#ifdef BOOST_CONTAINER_TEST_HAS_STD_STRING_VIEW
test_all();
+ empty_assign_test();
#endif
return boost::report_errors();
}
-