aboutsummaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-06-25 10:10:34 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-06-25 10:10:34 +0200
commit8583e53229e7b6cbe8b28d615ba8a02e4732d65b (patch)
treedff66cf0e1ca6a5d587139307df87a328d165e5e /libs
parentb41581ed656dde74b7a7b961b8a5c08bc61fb7d4 (diff)
downloadkernel-8583e53229e7b6cbe8b28d615ba8a02e4732d65b.tar.xz
kernel-8583e53229e7b6cbe8b28d615ba8a02e4732d65b.zip
kstd: add more basic_string::insert overloads
Diffstat (limited to 'libs')
-rw-r--r--libs/kstd/kstd/bits/basic_string.hpp43
-rw-r--r--libs/kstd/kstd/string.test.cpp304
2 files changed, 347 insertions, 0 deletions
diff --git a/libs/kstd/kstd/bits/basic_string.hpp b/libs/kstd/kstd/bits/basic_string.hpp
index 5d2eecd7..0509e33a 100644
--- a/libs/kstd/kstd/bits/basic_string.hpp
+++ b/libs/kstd/kstd/bits/basic_string.hpp
@@ -734,6 +734,7 @@ namespace kstd
//!
//! @param index The position to insert the data at.
//! @param string The string to insert.
+ //! @return A reference to this string.
constexpr auto insert(size_type index, CharacterType const * string) -> basic_string &
{
if (string == nullptr)
@@ -744,6 +745,48 @@ namespace kstd
return do_insert(index, std::basic_string_view<value_type, traits_type>{string});
}
+ //! Insert the characters in the range [string, string + length) into this string at a given position.
+ //!
+ //! The inserted range may contain null characters.
+ //!
+ //! @param index The position to insert the data at.
+ //! @param range The pointer to the first character of the range.
+ //! @param length The length of the range.
+ //! @return A reference to this string.
+ constexpr auto insert(size_type index, CharacterType const * range, size_type length) -> basic_string &
+ {
+ if (range == nullptr)
+ {
+ os::panic("Tried to insert nullptr range");
+ }
+
+ return do_insert(index, std::basic_string_view<value_type, traits_type>{range, length});
+ }
+
+ //! Insert a given string into this string at a given position.
+ //!
+ //! @param index The position to insert the data at.
+ //! @param string The string to insert.
+ //! @return A reference to this string.
+ constexpr auto insert(size_type index, basic_string const & string) -> basic_string &
+ {
+ return do_insert(index, static_cast<std::basic_string_view<value_type, traits_type>>(string));
+ }
+
+ //! Insert the elements of a string view like object at a given position.
+ //!
+ //! @param index The position to insert the data at.
+ //! @param view_like The string view like object.
+ //! @return A reference to this string.
+ template<typename StringViewLike>
+ requires(std::is_convertible_v<StringViewLike const &, std::basic_string_view<CharacterType, Traits>> &&
+ !std::is_convertible_v<StringViewLike const &, CharacterType const *>)
+ constexpr auto insert(size_type index, StringViewLike const & view_like) -> basic_string &
+ {
+ auto view = static_cast<std::basic_string_view<CharacterType, Traits>>(view_like);
+ return do_insert(index, view);
+ }
+
//! Append a character to this string.
//!
//! @param character The character to append.
diff --git a/libs/kstd/kstd/string.test.cpp b/libs/kstd/kstd/string.test.cpp
index 19345e09..74be1f0b 100644
--- a/libs/kstd/kstd/string.test.cpp
+++ b/libs/kstd/kstd/string.test.cpp
@@ -2152,6 +2152,310 @@ SCENARIO("String modifiers", "[string]")
}
}
+SCENARIO("String insertion", "[string]")
+{
+ GIVEN("A short string")
+ {
+ auto s = kstd::string{"abcd"};
+ auto old_capacity = s.capacity();
+ auto old_size = s.size();
+
+ WHEN("inserting five copies of a character at the beginning")
+ {
+ s.insert(0, 5, 'A');
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string stays the same")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("The string is equal to the old string with the new characters prepended")
+ {
+ REQUIRE(s == kstd::string{"AAAAAabcd"});
+ }
+ }
+
+ WHEN("inserting five copies of a character in the middle")
+ {
+ s.insert(2, 5, 'A');
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string stays the same")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("The string is equal to the old string with the new characters inserted")
+ {
+ REQUIRE(s == kstd::string{"abAAAAAcd"});
+ }
+ }
+
+ WHEN("inserting five copies of a character at the end")
+ {
+ s.insert(4, 5, 'A');
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string stays the same")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("The string is equal to the old string with the new characters appended")
+ {
+ REQUIRE(s == kstd::string{"abcdAAAAA"});
+ }
+ }
+
+ WHEN("inserting five copies of a character behind the end")
+ {
+ THEN("an OS panic is triggered")
+ {
+ REQUIRE_THROWS_AS(s.insert(5, 5, 'A'), kstd::tests::os_panic);
+ }
+ }
+
+ WHEN("inserting 20 copies of a character")
+ {
+ s.insert(2, 20, 'A');
+
+ THEN("the capacity of the string grows")
+ {
+ REQUIRE(s.capacity() > old_capacity);
+ }
+
+ THEN("the string is equal t o the old string with the new characters inserted")
+ {
+ REQUIRE(s == kstd::string{"abAAAAAAAAAAAAAAAAAAAAcd"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 at the beginning")
+ {
+ s.insert(0, "AAAAA");
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string stays the same")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("The string is equal to the old string with the new characters prepended")
+ {
+ REQUIRE(s == kstd::string{"AAAAAabcd"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 in the middle")
+ {
+ s.insert(2, "AAAAA");
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string stays the same")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("The string is equal to the old string with the new characters inserted")
+ {
+ REQUIRE(s == kstd::string{"abAAAAAcd"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 at the end")
+ {
+ s.insert(4, "AAAAA");
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string stays the same")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("The string is equal to the old string with the new characters appended")
+ {
+ REQUIRE(s == kstd::string{"abcdAAAAA"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 behind the end")
+ {
+ THEN("an OS panic is triggered")
+ {
+ REQUIRE_THROWS_AS(s.insert(5, "AAAAA"), kstd::tests::os_panic);
+ }
+ }
+ }
+
+ GIVEN("A long string")
+ {
+ auto s = kstd::string{"abcdefghijABCDEFGHIJ"};
+ auto old_capacity = s.capacity();
+ auto old_size = s.size();
+
+ WHEN("inserting five copies of a character at the beginning")
+ {
+ s.insert(0, 5, 'A');
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 5);
+ }
+
+ THEN("The string is equal to the old string with the new characters prepended")
+ {
+ REQUIRE(s == kstd::string{"AAAAAabcdefghijABCDEFGHIJ"});
+ }
+ }
+
+ WHEN("inserting five copies of a character in the middle")
+ {
+ s.insert(10, 5, 'A');
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 5);
+ }
+
+ THEN("The string is equal to the old string with the new characters inserted")
+ {
+ REQUIRE(s == kstd::string{"abcdefghijAAAAAABCDEFGHIJ"});
+ }
+ }
+
+ WHEN("inserting five copies of a character at the end")
+ {
+ s.insert(20, 5, 'A');
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 5);
+ }
+
+ THEN("The string is equal to the old string with the new characters appended")
+ {
+ REQUIRE(s == kstd::string{"abcdefghijABCDEFGHIJAAAAA"});
+ }
+ }
+
+ WHEN("inserting five copies of a character behind the end")
+ {
+ THEN("an OS panic is triggered")
+ {
+ REQUIRE_THROWS_AS(s.insert(21, 5, 'A'), kstd::tests::os_panic);
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 at the beginning")
+ {
+ s.insert(0, "AAAAA");
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 5);
+ }
+
+ THEN("The string is equal to the old string with the new characters prepended")
+ {
+ REQUIRE(s == kstd::string{"AAAAAabcdefghijABCDEFGHIJ"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 in the middle")
+ {
+ s.insert(10, "AAAAA");
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the string increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 5);
+ }
+
+ THEN("The string is equal to the old string with the new characters inserted")
+ {
+ REQUIRE(s == kstd::string{"abcdefghijAAAAAABCDEFGHIJ"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 at the end")
+ {
+ s.insert(20, "AAAAA");
+
+ THEN("the size of the string is increased by 5")
+ {
+ REQUIRE(s.size() == old_size + 5);
+ }
+
+ THEN("The capacity of the increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 5);
+ }
+
+ THEN("The string is equal to the old string with the new characters appended")
+ {
+ REQUIRE(s == kstd::string{"abcdefghijABCDEFGHIJAAAAA"});
+ }
+ }
+
+ WHEN("inserting a C-style string of length 5 behind the end")
+ {
+ THEN("an OS panic is triggered")
+ {
+ REQUIRE_THROWS_AS(s.insert(21, "AAAAA"), kstd::tests::os_panic);
+ }
+ }
+ }
+}
+
SCENARIO("String concatenation", "[string]")
{
GIVEN("Two strings")