aboutsummaryrefslogtreecommitdiff
path: root/libs/kstd
diff options
context:
space:
mode:
Diffstat (limited to 'libs/kstd')
-rw-r--r--libs/kstd/CMakeLists.txt1
-rw-r--r--libs/kstd/kstd/bits/basic_string.test.cpp1962
-rw-r--r--libs/kstd/kstd/string.test.cpp2007
3 files changed, 1907 insertions, 2063 deletions
diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt
index d85f003..5a95757 100644
--- a/libs/kstd/CMakeLists.txt
+++ b/libs/kstd/CMakeLists.txt
@@ -77,7 +77,6 @@ if(BUILD_TESTING)
"kstd/flat_map.test.cpp"
"kstd/format.test.cpp"
"kstd/vector.test.cpp"
- "kstd/bits/basic_string.test.cpp"
"kstd/bits/observer_ptr.test.cpp"
"kstd/test_support/os_panic.test.cpp"
"kstd/string.test.cpp"
diff --git a/libs/kstd/kstd/bits/basic_string.test.cpp b/libs/kstd/kstd/bits/basic_string.test.cpp
deleted file mode 100644
index 8f3a00d..0000000
--- a/libs/kstd/kstd/bits/basic_string.test.cpp
+++ /dev/null
@@ -1,1962 +0,0 @@
-#include <kstd/bits/basic_string.hpp>
-
-#include <kstd/allocator>
-#include <kstd/test_support/os_panic.hpp>
-
-#include <catch2/catch_test_macros.hpp>
-
-#include <cstring>
-#include <forward_list>
-#include <initializer_list>
-#include <iterator>
-#include <memory>
-#include <sstream>
-#include <string_view>
-#include <type_traits>
-#include <utility>
-
-using char_string = kstd::basic_string<char>;
-
-SCENARIO("Basic string of char initialization and construction", "[string]")
-{
- THEN("All type aliases are present")
- {
- REQUIRE(std::is_same_v<char_string::traits_type, kstd::char_traits<char>>);
- REQUIRE(std::is_same_v<char_string::value_type, char>);
- REQUIRE(std::is_same_v<char_string::allocator_type, kstd::allocator<char>>);
- REQUIRE(std::is_same_v<char_string::size_type, std::allocator_traits<kstd::allocator<char>>::size_type>);
- REQUIRE(
- std::is_same_v<char_string::difference_type, std::allocator_traits<kstd::allocator<char>>::difference_type>);
- REQUIRE(std::is_same_v<char_string::reference, char &>);
- REQUIRE(std::is_same_v<char_string::const_reference, char const &>);
- REQUIRE(std::is_same_v<char_string::pointer, std::allocator_traits<kstd::allocator<char>>::pointer>);
- REQUIRE(std::is_same_v<char_string::const_pointer, std::allocator_traits<kstd::allocator<char>>::const_pointer>);
- REQUIRE(std::is_same_v<char_string::iterator, char *>);
- REQUIRE(std::is_same_v<char_string::const_iterator, char const *>);
- REQUIRE(std::is_same_v<char_string::reverse_iterator, std::reverse_iterator<char *>>);
- REQUIRE(std::is_same_v<char_string::const_reverse_iterator, std::reverse_iterator<char const *>>);
- }
-
- THEN("npos is present")
- {
- REQUIRE(char_string::npos == char_string::size_type(-1));
- }
-
- GIVEN("An empty context")
- {
- WHEN("constructing by default")
- {
- auto s = char_string{};
-
- THEN("the string is empty")
- {
- REQUIRE(s.empty());
- }
-
- THEN("the size is equal to zero")
- {
- REQUIRE(s.size() == 0);
- }
-
- THEN("the length is equal to zero")
- {
- REQUIRE(s.length() == 0);
- }
-
- THEN("at raises a panic")
- {
- REQUIRE_THROWS_AS(s.at(0), kstd::tests::os_panic);
- }
-
- THEN("data returns a pointer poiting to a null byte")
- {
- REQUIRE(*s.data() == '\0');
- }
-
- THEN("c_str returns a pointer poiting to a null byte")
- {
- REQUIRE(*s.c_str() == '\0');
- }
-
- THEN("the string is convertible to an empty string view")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.empty());
- }
- }
-
- WHEN("constructing with 10 copies of the letter 'a'")
- {
- auto s = char_string{10, 'a'};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 10")
- {
- REQUIRE(s.size() == 10);
- }
-
- THEN("the length is equal to 10")
- {
- REQUIRE(s.length() == 10);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns a")
- {
- REQUIRE(s.at(s.size() - 1) == 'a');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns a")
- {
- REQUIRE(s[s.size() - 1] == 'a');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns a")
- {
- REQUIRE(s.back() == 'a');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 10")
- {
- REQUIRE(std::strlen(s.c_str()) == 10);
- }
-
- THEN("the string converts to a string view of length 10")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 10);
- }
- }
-
- WHEN("constructing with 20 copies of the letter 'a'")
- {
- auto s = char_string{20, 'a'};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
-
- THEN("the capacity is equal to 20")
- {
- REQUIRE(s.capacity() == 20);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns a")
- {
- REQUIRE(s.at(s.size() - 1) == 'a');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns a")
- {
- REQUIRE(s[s.size() - 1] == 'a');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns a")
- {
- REQUIRE(s.back() == 'a');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 20")
- {
- REQUIRE(std::strlen(s.c_str()) == 20);
- }
-
- THEN("the string converts to a string view of length 20")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 20);
- }
- }
-
- WHEN("constructing with an input iterator pair of 10 characters")
- {
- auto source = std::istringstream{"abcdefghij"};
- auto s = char_string{std::istream_iterator<char>{source}, std::istream_iterator<char>{}};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 10")
- {
- REQUIRE(s.size() == 10);
- }
-
- THEN("the length is equal to 10")
- {
- REQUIRE(s.length() == 10);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns j")
- {
- REQUIRE(s.at(s.size() - 1) == 'j');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns j")
- {
- REQUIRE(s[s.size() - 1] == 'j');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns j")
- {
- REQUIRE(s.back() == 'j');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 10")
- {
- REQUIRE(std::strlen(s.c_str()) == 10);
- }
-
- THEN("the string converts to a string view of length 10")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 10);
- }
- }
-
- WHEN("constructing with an input iterator pair of 20 characters")
- {
- auto source = std::istringstream{"abcdefghijABCDEFGHIJ"};
- auto s = char_string{std::istream_iterator<char>{source}, std::istream_iterator<char>{}};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
-
- THEN("the capacity is greater than or equal to 20")
- {
- REQUIRE(s.capacity() >= 20);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns J")
- {
- REQUIRE(s.at(s.size() - 1) == 'J');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns J")
- {
- REQUIRE(s[s.size() - 1] == 'J');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 20")
- {
- REQUIRE(std::strlen(s.c_str()) == 20);
- }
-
- THEN("the string converts to a string view of length 20")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 20);
- }
- }
-
- WHEN("constructing with a forward iterator pair of 10 characters")
- {
- auto source = std::forward_list{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
- auto s = char_string{source.cbegin(), source.cend()};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 10")
- {
- REQUIRE(s.size() == 10);
- }
-
- THEN("the length is equal to 10")
- {
- REQUIRE(s.length() == 10);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns j")
- {
- REQUIRE(s.at(s.size() - 1) == 'j');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns j")
- {
- REQUIRE(s[s.size() - 1] == 'j');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns j")
- {
- REQUIRE(s.back() == 'j');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 10")
- {
- REQUIRE(std::strlen(s.c_str()) == 10);
- }
-
- THEN("the string converts to a string view of length 10")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 10);
- }
- }
-
- WHEN("constructing with a forward iterator pair of 20 characters")
- {
- auto source = std::forward_list{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
- auto s = char_string{source.cbegin(), source.cend()};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
-
- THEN("the capacity is equal to 20")
- {
- REQUIRE(s.capacity() == 20);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns J")
- {
- REQUIRE(s.at(s.size() - 1) == 'J');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns J")
- {
- REQUIRE(s[s.size() - 1] == 'J');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 20")
- {
- REQUIRE(std::strlen(s.c_str()) == 20);
- }
-
- THEN("the string converts to a string view of length 20")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 20);
- }
- }
-
- WHEN("constructing from a null pointer with zero size")
- {
- auto s = char_string{static_cast<char const *>(nullptr), 0};
-
- THEN("the string is empty")
- {
- REQUIRE(s.empty());
- }
-
- THEN("the size is equal to 0")
- {
- REQUIRE(s.size() == 0);
- }
-
- THEN("the length is equal to 0")
- {
- REQUIRE(s.length() == 0);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at raises a panic")
- {
- REQUIRE_THROWS_AS(s.at(0), kstd::tests::os_panic);
- }
-
- THEN("data returns a pointer poiting to a null byte")
- {
- REQUIRE(*s.data() == '\0');
- }
-
- THEN("c_str returns a pointer poiting to a null byte")
- {
- REQUIRE(*s.c_str() == '\0');
- }
-
- THEN("the string is convertible to an empty string view")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.empty());
- }
- }
-
- WHEN("constructing from a from a null pointer and non-zero size")
- {
- THEN("a panic is raised")
- {
- REQUIRE_THROWS_AS((char_string{static_cast<char const *>(nullptr), 1}), kstd::tests::os_panic);
- }
- }
-
- WHEN("constructing from a non-null pointer and zero size")
- {
- auto ptr = "abcd";
- auto s = char_string{ptr, 0};
-
- THEN("the string is empty")
- {
- REQUIRE(s.empty());
- }
-
- THEN("the size is equal to 0")
- {
- REQUIRE(s.size() == 0);
- }
-
- THEN("the length is equal to 0")
- {
- REQUIRE(s.length() == 0);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at raises a panic")
- {
- REQUIRE_THROWS_AS(s.at(0), kstd::tests::os_panic);
- }
-
- THEN("data returns a pointer poiting to a null byte")
- {
- REQUIRE(*s.data() == '\0');
- }
-
- THEN("c_str returns a pointer poiting to a null byte")
- {
- REQUIRE(*s.c_str() == '\0');
- }
-
- THEN("the string is convertible to an empty string view")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.empty());
- }
- }
-
- WHEN("constructing from a non-null pointer and a size of 4")
- {
- auto ptr = "abcd";
- auto s = char_string{ptr, 4};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 4")
- {
- REQUIRE(s.size() == 4);
- }
-
- THEN("the length is equal to 4")
- {
- REQUIRE(s.length() == 4);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns d")
- {
- REQUIRE(s.at(s.size() - 1) == 'd');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns d")
- {
- REQUIRE(s[s.size() - 1] == 'd');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns d")
- {
- REQUIRE(s.back() == 'd');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 4")
- {
- REQUIRE(std::strlen(s.c_str()) == 4);
- }
-
- THEN("the string converts to a string view of length 4")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 4);
- }
- }
-
- WHEN("constructing from a non-null pointer and a size of 20")
- {
- auto ptr = "abcdefghijABCDEFGHIJ";
- auto s = char_string{ptr, 20};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
-
- THEN("the capacity is equal to 20")
- {
- REQUIRE(s.capacity() == 20);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns J")
- {
- REQUIRE(s.at(s.size() - 1) == 'J');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns J")
- {
- REQUIRE(s[s.size() - 1] == 'J');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 20")
- {
- REQUIRE(std::strlen(s.c_str()) == 20);
- }
-
- THEN("the string converts to a string view of length 20")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 20);
- }
- }
-
- WHEN("constructing from a C-style string of length 4")
- {
- auto ptr = "abcd";
- auto s = char_string{ptr};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 4")
- {
- REQUIRE(s.size() == 4);
- }
-
- THEN("the length is equal to 4")
- {
- REQUIRE(s.length() == 4);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns d")
- {
- REQUIRE(s.at(s.size() - 1) == 'd');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns d")
- {
- REQUIRE(s[s.size() - 1] == 'd');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns d")
- {
- REQUIRE(s.back() == 'd');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 4")
- {
- REQUIRE(std::strlen(s.c_str()) == 4);
- }
-
- THEN("the string converts to a string view of length 4")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 4);
- }
- }
-
- WHEN("constructing from a C-style string of length 20")
- {
- auto ptr = "abcdefghijABCDEFGHIJ";
- auto s = char_string{ptr};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
-
- THEN("the capacity is equal to 20")
- {
- REQUIRE(s.capacity() == 20);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns J")
- {
- REQUIRE(s.at(s.size() - 1) == 'J');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns J")
- {
- REQUIRE(s[s.size() - 1] == 'J');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 20")
- {
- REQUIRE(std::strlen(s.c_str()) == 20);
- }
-
- THEN("the string converts to a string view of length 20")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 20);
- }
- }
-
- WHEN("constructing from a string view of length 4")
- {
- using namespace std::string_view_literals;
-
- auto view = "abcd"sv;
- auto s = char_string{view};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 4")
- {
- REQUIRE(s.size() == 4);
- }
-
- THEN("the length is equal to 4")
- {
- REQUIRE(s.length() == 4);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns d")
- {
- REQUIRE(s.at(s.size() - 1) == 'd');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns d")
- {
- REQUIRE(s[s.size() - 1] == 'd');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns d")
- {
- REQUIRE(s.back() == 'd');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 4")
- {
- REQUIRE(std::strlen(s.c_str()) == 4);
- }
-
- THEN("the string converts to a string view of length 4")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 4);
- }
- }
-
- WHEN("constructing from a string view of length 20")
- {
- using namespace std::string_view_literals;
-
- auto view = "abcdefghijABCDEFGHIJ"sv;
- auto s = char_string{view};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
-
- THEN("the capacity is equal to 20")
- {
- REQUIRE(s.capacity() == 20);
- }
-
- THEN("at(0) returns a")
- {
- REQUIRE(s.at(0) == 'a');
- }
-
- THEN("at(size() - 1) returns J")
- {
- REQUIRE(s.at(s.size() - 1) == 'J');
- }
-
- THEN("[0] returns a")
- {
- REQUIRE(s[0] == 'a');
- }
-
- THEN("[size() - 1] returns J")
- {
- REQUIRE(s[s.size() - 1] == 'J');
- }
-
- THEN("front returns a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back returns J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("data returns a pointer pointing to an a")
- {
- REQUIRE(*s.data() == 'a');
- }
-
- THEN("c_str returns a pointer pointing to an a")
- {
- REQUIRE(*s.c_str() == 'a');
- }
-
- THEN("c_str points to the start of a c-string of length 20")
- {
- REQUIRE(std::strlen(s.c_str()) == 20);
- }
-
- THEN("the string converts to a string view of length 20")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 20);
- }
- }
-
- WHEN("constructing from a substring of a string view of length 4")
- {
- using namespace std::string_view_literals;
-
- auto view = "abcd"sv;
- auto s = char_string{view, 1, 4};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 3")
- {
- REQUIRE(s.size() == 3);
- }
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
-
- THEN("the capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("at(0) returns b")
- {
- REQUIRE(s.at(0) == 'b');
- }
-
- THEN("at(size() - 1) returns d")
- {
- REQUIRE(s.at(s.size() - 1) == 'd');
- }
-
- THEN("[0] returns b")
- {
- REQUIRE(s[0] == 'b');
- }
-
- THEN("[size() - 1] returns d")
- {
- REQUIRE(s[s.size() - 1] == 'd');
- }
-
- THEN("front returns b")
- {
- REQUIRE(s.front() == 'b');
- }
-
- THEN("back returns d")
- {
- REQUIRE(s.back() == 'd');
- }
-
- THEN("data returns a pointer pointing to an b")
- {
- REQUIRE(*s.data() == 'b');
- }
-
- THEN("c_str returns a pointer pointing to an b")
- {
- REQUIRE(*s.c_str() == 'b');
- }
-
- THEN("c_str points to the start of a c-string of length 3")
- {
- REQUIRE(std::strlen(s.c_str()) == 3);
- }
-
- THEN("the string converts to a string view of length 3")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 3);
- }
- }
-
- WHEN("constructing from a substring of a string view of length 20")
- {
- using namespace std::string_view_literals;
-
- auto view = "abcdefghijABCDEFGHIJ"sv;
- auto s = char_string{view, 1, 20};
-
- THEN("the string is not empty")
- {
- REQUIRE_FALSE(s.empty());
- }
-
- THEN("the size is equal to 19")
- {
- REQUIRE(s.size() == 19);
- }
-
- THEN("the length is equal to 19")
- {
- REQUIRE(s.length() == 19);
- }
-
- THEN("the capacity is equal to 19")
- {
- REQUIRE(s.capacity() == 19);
- }
-
- THEN("at(0) returns b")
- {
- REQUIRE(s.at(0) == 'b');
- }
-
- THEN("at(size() - 1) returns J")
- {
- REQUIRE(s.at(s.size() - 1) == 'J');
- }
-
- THEN("[0] returns b")
- {
- REQUIRE(s[0] == 'b');
- }
-
- THEN("[size() - 1] returns J")
- {
- REQUIRE(s[s.size() - 1] == 'J');
- }
-
- THEN("front returns b")
- {
- REQUIRE(s.front() == 'b');
- }
-
- THEN("back returns J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("data returns a pointer pointing to an b")
- {
- REQUIRE(*s.data() == 'b');
- }
-
- THEN("c_str returns a pointer pointing to an b")
- {
- REQUIRE(*s.c_str() == 'b');
- }
-
- THEN("c_str points to the start of a c-string of length 19")
- {
- REQUIRE(std::strlen(s.c_str()) == 19);
- }
-
- THEN("the string converts to a string view of length 19")
- {
- auto view = static_cast<std::string_view>(s);
- REQUIRE(view.length() == 19);
- }
- }
- }
-
- GIVEN("An existing short string, of length 10")
- {
- auto other = char_string{"abcdefghij"};
-
- WHEN("constructing by copy")
- {
- auto s = other;
-
- THEN("the sizes are identical")
- {
- REQUIRE(s.size() == other.size());
- }
-
- THEN("the capacities are idendtical")
- {
- REQUIRE(s.capacity() == other.capacity());
- }
-
- THEN("the underlying strings are identical")
- {
- REQUIRE_FALSE(std::strcmp(s.data(), other.data()));
- }
- }
-
- WHEN("constructing by move")
- {
- auto s = std::move(other);
-
- THEN("size is equal to 10")
- {
- REQUIRE(s.size() == 10);
- }
-
- THEN("capacity is equal to 15")
- {
- REQUIRE(s.capacity() == 15);
- }
-
- THEN("front() return an a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back() return a j")
- {
- REQUIRE(s.back() == 'j');
- }
-
- THEN("The moved from object's size is 0")
- {
- REQUIRE(other.size() == 0);
- }
-
- THEN("The moved from object's capacity is 15")
- {
- REQUIRE(other.capacity() == 15);
- }
-
- THEN("c_str() on the moved from object points to a null byte")
- {
- REQUIRE(*other.c_str() == '\0');
- }
- }
- }
-
- GIVEN("An existing short string, of length 20")
- {
- auto other = char_string{"abcdefghijABCDEFGHIJ"};
-
- WHEN("constructing by copy")
- {
- auto s = other;
-
- THEN("the sizes are identical")
- {
- REQUIRE(s.size() == other.size());
- }
-
- THEN("the capacities are idendtical")
- {
- REQUIRE(s.capacity() == other.capacity());
- }
-
- THEN("the underlying strings are identical")
- {
- REQUIRE_FALSE(std::strcmp(s.data(), other.data()));
- }
- }
-
- WHEN("constructing by move")
- {
- auto s = std::move(other);
-
- THEN("size is equal to 20")
- {
- REQUIRE(s.size() == 20);
- }
-
- THEN("capacity is equal to 20")
- {
- REQUIRE(s.capacity() == 20);
- }
-
- THEN("front() return an a")
- {
- REQUIRE(s.front() == 'a');
- }
-
- THEN("back() return a J")
- {
- REQUIRE(s.back() == 'J');
- }
-
- THEN("The moved from object's size is 0")
- {
- REQUIRE(other.size() == 0);
- }
-
- THEN("The moved from object's capacity is 15")
- {
- REQUIRE(other.capacity() == 15);
- }
-
- THEN("c_str() on the moved from object points to a null byte")
- {
- REQUIRE(*other.c_str() == '\0');
- }
- }
- }
-}
-
-SCENARIO("Basic string assignment", "[string]")
-{
- GIVEN("Two short strings")
- {
- auto s1 = char_string{"abcd"};
- auto s2 = char_string{"defghij"};
-
- WHEN("copy assigning the shorter to the longer one")
- {
- s2 = s1;
-
- THEN("the new length of the longer one is equal to the length of the shorter one")
- {
- REQUIRE(s2.length() == s1.length());
- }
-
- THEN("the underlying data of the two is identical")
- {
- REQUIRE_FALSE(std::strcmp(s1.data(), s2.data()));
- }
- }
-
- WHEN("copy assigning the longer to the shorter one")
- {
- s1 = s2;
-
- THEN("the new length of the shorter one is equal to the length of the longer one")
- {
- REQUIRE(s1.length() == s2.length());
- }
-
- THEN("the underlying data of the two is identical")
- {
- REQUIRE_FALSE(std::strcmp(s2.data(), s1.data()));
- }
- }
-
- WHEN("move assigning the shorter to the longer one")
- {
- s2 = std::move(s1);
-
- THEN("the new length of the longer one is equal to the original length of the shorter one")
- {
- REQUIRE(s2.length() == 4);
- }
-
- THEN("the length of the moved from one is 0")
- {
- REQUIRE(s1.length() == 0);
- }
-
- THEN("the capacity of the moved from one is 15")
- {
- REQUIRE(s1.capacity() == 15);
- }
-
- THEN("the capacity of the moved to one is 15")
- {
- REQUIRE(s2.capacity() == 15);
- }
- }
-
- WHEN("move assigning the longer to the shorter one")
- {
- s1 = std::move(s2);
-
- THEN("the new length of the shorter one is equal to the original length of the longer one")
- {
- REQUIRE(s1.length() == 7);
- }
-
- THEN("the length of the moved from one is 0")
- {
- REQUIRE(s2.length() == 0);
- }
-
- THEN("the capacity of the moved from one is 15")
- {
- REQUIRE(s2.capacity() == 15);
- }
-
- THEN("the capacity of the moved to one is 15")
- {
- REQUIRE(s1.capacity() == 15);
- }
- }
- }
-
- GIVEN("One short and one long string")
- {
- auto s1 = char_string{"abcd"};
- auto s2 = char_string{"ABCDEFGHIJabcdefghij"};
-
- WHEN("copy assigning the shorter to the longer one")
- {
- s2 = s1;
-
- THEN("the new length of the longer one is equal to the length of the shorter one")
- {
- REQUIRE(s2.length() == s1.length());
- }
-
- THEN("the new capacity of the longer one is 15")
- {
- REQUIRE(s2.capacity() == 15);
- }
-
- THEN("the underlying data of the two is identical")
- {
- REQUIRE_FALSE(std::strcmp(s1.data(), s2.data()));
- }
- }
-
- WHEN("copy assigning the longer to the shorter one")
- {
- s1 = s2;
-
- THEN("the new length of the shorter one is equal to the length of the longer one")
- {
- REQUIRE(s1.length() == s2.length());
- }
-
- THEN("the new capacity of the shorter one is 20")
- {
- REQUIRE(s1.capacity() == 20);
- }
-
- THEN("the underlying data of the two is identical")
- {
- REQUIRE_FALSE(std::strcmp(s2.data(), s1.data()));
- }
- }
-
- WHEN("move assigning the shorter to the longer one")
- {
- s2 = std::move(s1);
-
- THEN("the new length of the longer one is equal to the original length of the shorter one")
- {
- REQUIRE(s2.length() == 4);
- }
-
- THEN("the length of the moved from one is 0")
- {
- REQUIRE(s1.length() == 0);
- }
-
- THEN("the capacity of the moved from one is 15")
- {
- REQUIRE(s1.capacity() == 15);
- }
-
- THEN("the capacity of the moved to one is 15")
- {
- REQUIRE(s2.capacity() == 15);
- }
- }
-
- WHEN("move assigning the longer to the shorter one")
- {
- s1 = std::move(s2);
-
- THEN("the new length of the shorter one is equal to the original length of the longer one")
- {
- REQUIRE(s1.length() == 20);
- }
-
- THEN("the length of the moved from one is 0")
- {
- REQUIRE(s2.length() == 0);
- }
-
- THEN("the capacity of the moved from one is 15")
- {
- REQUIRE(s2.capacity() == 15);
- }
-
- THEN("the capacity of the moved to one is 15")
- {
- REQUIRE(s1.capacity() == 20);
- }
- }
- }
-
- GIVEN("Two long strings")
- {
- auto s1 = char_string{"abcdefghijABCDEFGH"};
- auto s2 = char_string{"ABCDEFGHIJabcdefghij"};
-
- WHEN("copy assigning the shorter to the longer one")
- {
- s2 = s1;
-
- THEN("the new length of the longer one is equal to the length of the shorter one")
- {
- REQUIRE(s2.length() == s1.length());
- }
-
- THEN("the new capacity of the longer one is still 20")
- {
- REQUIRE(s2.capacity() == 20);
- }
-
- THEN("the underlying data of the two is identical")
- {
- REQUIRE_FALSE(std::strcmp(s1.data(), s2.data()));
- }
- }
-
- WHEN("copy assigning the longer to the shorter one")
- {
- s1 = s2;
-
- THEN("the new length of the shorter one is equal to the length of the longer one")
- {
- REQUIRE(s1.length() == s2.length());
- }
-
- THEN("the new capacity of the shorter one is 20")
- {
- REQUIRE(s1.capacity() == 20);
- }
-
- THEN("the underlying data of the two is identical")
- {
- REQUIRE_FALSE(std::strcmp(s2.data(), s1.data()));
- }
- }
-
- WHEN("move assigning the shorter to the longer one")
- {
- s2 = std::move(s1);
-
- THEN("the new length of the longer one is equal to the original length of the shorter one")
- {
- REQUIRE(s2.length() == 18);
- }
-
- THEN("the length of the moved from one is 0")
- {
- REQUIRE(s1.length() == 0);
- }
-
- THEN("the capacity of the moved from one is 15")
- {
- REQUIRE(s1.capacity() == 15);
- }
-
- THEN("the capacity of the moved to one is 15")
- {
- REQUIRE(s2.capacity() == 18);
- }
- }
-
- WHEN("move assigning the longer to the shorter one")
- {
- s1 = std::move(s2);
-
- THEN("the new length of the shorter one is equal to the original length of the longer one")
- {
- REQUIRE(s1.length() == 20);
- }
-
- THEN("the length of the moved from one is 0")
- {
- REQUIRE(s2.length() == 0);
- }
-
- THEN("the capacity of the moved from one is 15")
- {
- REQUIRE(s2.capacity() == 15);
- }
-
- THEN("the capacity of the moved to one is 15")
- {
- REQUIRE(s1.capacity() == 20);
- }
- }
- }
-
- GIVEN("An short string")
- {
- auto s = char_string{"abcd"};
-
- WHEN("assigning a new, shorter c-style string of length 3")
- {
- s = "def";
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
- }
-
- WHEN("assigning a new, longer, c-style string of length 5")
- {
- s = "defgh";
-
- THEN("the length is equal to 5")
- {
- REQUIRE(s.length() == 5);
- }
- }
-
- WHEN("assigning a new, longer, c-style string of length 20")
- {
- s = "ABCDEFGHIJabcdefghij";
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
- }
-
- WHEN("assigning a single character")
- {
- s = 'z';
-
- THEN("the length is equal to 1")
- {
- REQUIRE(s.length() == 1);
- }
- }
-
- WHEN("assigning an shorter initializer list of length 3")
- {
- s = {'d', 'e', 'f'};
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
- }
-
- WHEN("assigning an longer initializer list of length 5")
- {
- s = {'d', 'e', 'f', 'g', 'h'};
-
- THEN("the length is equal to 5")
- {
- REQUIRE(s.length() == 5);
- }
- }
-
- WHEN("assigning an longer initializer list of length 20")
- {
- s = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
- }
-
- WHEN("assigning from a shorter string view of length 3")
- {
- using namespace std::string_view_literals;
-
- s = "def"sv;
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
- }
-
- WHEN("assigning from a longer string view of length 5")
- {
- using namespace std::string_view_literals;
-
- s = "defgh"sv;
-
- THEN("the length is equal to 5")
- {
- REQUIRE(s.length() == 5);
- }
- }
-
- WHEN("assigning from a longer string view of length 20")
- {
- using namespace std::string_view_literals;
-
- s = "ABCDEFGHIJabcdefghij"sv;
-
- THEN("the length is equal to 20")
- {
- REQUIRE(s.length() == 20);
- }
- }
- }
-
- GIVEN("An long string")
- {
- auto s = char_string{"abcdefghijABCDEFGHIJ"};
-
- WHEN("assigning a new, shorter c-style string of length 3")
- {
- s = "def";
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
- }
-
- WHEN("assigning a new, longer, c-style string of length 22")
- {
- s = "ABCDEFGHIJabcdefghijkl";
-
- THEN("the length is equal to 22")
- {
- REQUIRE(s.length() == 22);
- }
- }
-
- WHEN("assigning a single character")
- {
- s = 'z';
-
- THEN("the length is equal to 1")
- {
- REQUIRE(s.length() == 1);
- }
- }
-
- WHEN("assigning an shorter initializer list of length 3")
- {
- s = {'d', 'e', 'f'};
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
- }
-
- WHEN("assigning an longer initializer list of length 22")
- {
- s = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'a',
- 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'};
-
- THEN("the length is equal to 22")
- {
- REQUIRE(s.length() == 22);
- }
- }
-
- WHEN("assigning from a shorter string view of length 3")
- {
- using namespace std::string_view_literals;
-
- s = "def"sv;
-
- THEN("the length is equal to 3")
- {
- REQUIRE(s.length() == 3);
- }
- }
-
- WHEN("assigning from a longer string view of length 22")
- {
- using namespace std::string_view_literals;
-
- s = "ABCDEFGHIJabcdefghijkl"sv;
-
- THEN("the length is equal to 22")
- {
- REQUIRE(s.length() == 22);
- }
- }
- }
-}
-
-SCENARIO("Basic string of char modifiers", "[string]")
-{
- GIVEN("A short string")
- {
- auto s = char_string{"abcd"};
- auto old_capacity = s.capacity();
- auto old_size = s.size();
- auto old_data = s.data();
-
- WHEN("reserving a smaller capacity")
- {
- s.reserve(1);
-
- THEN("the capacity does not change")
- {
- REQUIRE(s.capacity() == old_capacity);
- }
-
- THEN("the content stays the same")
- {
- REQUIRE(s == "abcd");
- }
-
- THEN("the size stays the same")
- {
- REQUIRE(s.size() == old_size);
- }
-
- THEN("the data pointer stays the same")
- {
- REQUIRE(s.data() == old_data);
- }
- }
-
- WHEN("reserving equal capacity")
- {
- s.reserve(old_capacity);
-
- THEN("the capacity does not change")
- {
- REQUIRE(s.capacity() == old_capacity);
- }
-
- THEN("the content stays the same")
- {
- REQUIRE(s == "abcd");
- }
-
- THEN("the size stays the same")
- {
- REQUIRE(s.size() == old_size);
- }
-
- THEN("the data pointer stays the same")
- {
- REQUIRE(static_cast<void const *>(s.data()) == static_cast<void const *>(old_data));
- }
- }
-
- WHEN("reserving larger capacity")
- {
- s.reserve(old_capacity + 1);
-
- THEN("the capacity increases")
- {
- REQUIRE(s.capacity() >= old_capacity + 1);
- }
-
- THEN("the content stays the same")
- {
- REQUIRE(s == "abcd");
- }
-
- THEN("the size stays the same")
- {
- REQUIRE(s.size() == old_size);
- }
-
- THEN("the data pointer changes")
- {
- REQUIRE(s.data() != old_data);
- }
- }
- }
-}
diff --git a/libs/kstd/kstd/string.test.cpp b/libs/kstd/kstd/string.test.cpp
index b81cd3a..e5925aa 100644
--- a/libs/kstd/kstd/string.test.cpp
+++ b/libs/kstd/kstd/string.test.cpp
@@ -1,158 +1,1959 @@
#include <kstd/string>
+#include <kstd/allocator>
+#include <kstd/test_support/os_panic.hpp>
+
#include <catch2/catch_test_macros.hpp>
#include <algorithm>
#include <cstring>
+#include <forward_list>
+#include <iterator>
+#include <memory>
+#include <sstream>
#include <string_view>
+#include <type_traits>
+#include <utility>
+
+TEST_CASE("String static interface")
+{
+ REQUIRE(std::is_same_v<kstd::string::traits_type, kstd::char_traits<char>>);
+ REQUIRE(std::is_same_v<kstd::string::value_type, char>);
+ REQUIRE(std::is_same_v<kstd::string::allocator_type, kstd::allocator<char>>);
+ REQUIRE(std::is_same_v<kstd::string::size_type, std::allocator_traits<kstd::allocator<char>>::size_type>);
+ REQUIRE(std::is_same_v<kstd::string::difference_type, std::allocator_traits<kstd::allocator<char>>::difference_type>);
+ REQUIRE(std::is_same_v<kstd::string::reference, char &>);
+ REQUIRE(std::is_same_v<kstd::string::const_reference, char const &>);
+ REQUIRE(std::is_same_v<kstd::string::pointer, std::allocator_traits<kstd::allocator<char>>::pointer>);
+ REQUIRE(std::is_same_v<kstd::string::const_pointer, std::allocator_traits<kstd::allocator<char>>::const_pointer>);
+ REQUIRE(std::is_same_v<kstd::string::iterator, char *>);
+ REQUIRE(std::is_same_v<kstd::string::const_iterator, char const *>);
+ REQUIRE(std::is_same_v<kstd::string::reverse_iterator, std::reverse_iterator<char *>>);
+ REQUIRE(std::is_same_v<kstd::string::const_reverse_iterator, std::reverse_iterator<char const *>>);
+
+ REQUIRE(kstd::string::npos == kstd::string::size_type(-1));
+}
SCENARIO("String initialization and construction", "[string]")
{
- GIVEN("Nothing")
+ GIVEN("An empty context")
{
- WHEN("constructing an empty string")
+ WHEN("constructing by default")
{
- auto str = kstd::string{};
+ auto s = kstd::string{};
- THEN("the size is zero and therefore the string is empty")
+ THEN("the string is empty")
{
- REQUIRE(str.empty());
- REQUIRE(str.size() == 0);
+ REQUIRE(s.empty());
+ }
+
+ THEN("the size is equal to zero")
+ {
+ REQUIRE(s.size() == 0);
+ }
+
+ THEN("the length is equal to zero")
+ {
+ REQUIRE(s.length() == 0);
+ }
+
+ THEN("at raises a panic")
+ {
+ REQUIRE_THROWS_AS(s.at(0), kstd::tests::os_panic);
+ }
+
+ THEN("data returns a pointer poiting to a null byte")
+ {
+ REQUIRE(*s.data() == '\0');
+ }
+
+ THEN("c_str returns a pointer poiting to a null byte")
+ {
+ REQUIRE(*s.c_str() == '\0');
+ }
+
+ THEN("the string is convertible to an empty string view")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.empty());
+ }
+ }
+
+ WHEN("constructing with 10 copies of the letter 'a'")
+ {
+ auto s = kstd::string{10, 'a'};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 10")
+ {
+ REQUIRE(s.size() == 10);
+ }
+
+ THEN("the length is equal to 10")
+ {
+ REQUIRE(s.length() == 10);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns a")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'a');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns a")
+ {
+ REQUIRE(s[s.size() - 1] == 'a');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns a")
+ {
+ REQUIRE(s.back() == 'a');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 10")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 10);
+ }
+
+ THEN("the string converts to a string view of length 10")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 10);
+ }
+ }
+
+ WHEN("constructing with 20 copies of the letter 'a'")
+ {
+ auto s = kstd::string{20, 'a'};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+
+ THEN("the capacity is equal to 20")
+ {
+ REQUIRE(s.capacity() == 20);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns a")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'a');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns a")
+ {
+ REQUIRE(s[s.size() - 1] == 'a');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns a")
+ {
+ REQUIRE(s.back() == 'a');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 20")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 20);
+ }
+
+ THEN("the string converts to a string view of length 20")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 20);
+ }
+ }
+
+ WHEN("constructing with an input iterator pair of 10 characters")
+ {
+ auto source = std::istringstream{"abcdefghij"};
+ auto s = kstd::string{std::istream_iterator<char>{source}, std::istream_iterator<char>{}};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 10")
+ {
+ REQUIRE(s.size() == 10);
+ }
+
+ THEN("the length is equal to 10")
+ {
+ REQUIRE(s.length() == 10);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns j")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'j');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns j")
+ {
+ REQUIRE(s[s.size() - 1] == 'j');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns j")
+ {
+ REQUIRE(s.back() == 'j');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 10")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 10);
+ }
+
+ THEN("the string converts to a string view of length 10")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 10);
+ }
+ }
+
+ WHEN("constructing with an input iterator pair of 20 characters")
+ {
+ auto source = std::istringstream{"abcdefghijABCDEFGHIJ"};
+ auto s = kstd::string{std::istream_iterator<char>{source}, std::istream_iterator<char>{}};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+
+ THEN("the capacity is greater than or equal to 20")
+ {
+ REQUIRE(s.capacity() >= 20);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns J")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'J');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns J")
+ {
+ REQUIRE(s[s.size() - 1] == 'J');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 20")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 20);
+ }
+
+ THEN("the string converts to a string view of length 20")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 20);
+ }
+ }
+
+ WHEN("constructing with a forward iterator pair of 10 characters")
+ {
+ auto source = std::forward_list{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
+ auto s = kstd::string{source.cbegin(), source.cend()};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 10")
+ {
+ REQUIRE(s.size() == 10);
+ }
+
+ THEN("the length is equal to 10")
+ {
+ REQUIRE(s.length() == 10);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns j")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'j');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns j")
+ {
+ REQUIRE(s[s.size() - 1] == 'j');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns j")
+ {
+ REQUIRE(s.back() == 'j');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 10")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 10);
+ }
+
+ THEN("the string converts to a string view of length 10")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 10);
+ }
+ }
+
+ WHEN("constructing with a forward iterator pair of 20 characters")
+ {
+ auto source = std::forward_list{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
+ auto s = kstd::string{source.cbegin(), source.cend()};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+
+ THEN("the capacity is equal to 20")
+ {
+ REQUIRE(s.capacity() == 20);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns J")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'J');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns J")
+ {
+ REQUIRE(s[s.size() - 1] == 'J');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
}
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 20")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 20);
+ }
+
+ THEN("the string converts to a string view of length 20")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 20);
+ }
+ }
+
+ WHEN("constructing from a null pointer with zero size")
+ {
+ auto s = kstd::string{static_cast<char const *>(nullptr), 0};
+
THEN("the string is empty")
{
- REQUIRE(str == std::string_view{});
+ REQUIRE(s.empty());
+ }
+
+ THEN("the size is equal to 0")
+ {
+ REQUIRE(s.size() == 0);
+ }
+
+ THEN("the length is equal to 0")
+ {
+ REQUIRE(s.length() == 0);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at raises a panic")
+ {
+ REQUIRE_THROWS_AS(s.at(0), kstd::tests::os_panic);
+ }
+
+ THEN("data returns a pointer poiting to a null byte")
+ {
+ REQUIRE(*s.data() == '\0');
+ }
+
+ THEN("c_str returns a pointer poiting to a null byte")
+ {
+ REQUIRE(*s.c_str() == '\0');
+ }
+
+ THEN("the string is convertible to an empty string view")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.empty());
+ }
+ }
+
+ WHEN("constructing from a from a null pointer and non-zero size")
+ {
+ THEN("a panic is raised")
+ {
+ REQUIRE_THROWS_AS((kstd::string{static_cast<char const *>(nullptr), 1}), kstd::tests::os_panic);
+ }
+ }
+
+ WHEN("constructing from a non-null pointer and zero size")
+ {
+ auto ptr = "abcd";
+ auto s = kstd::string{ptr, 0};
+
+ THEN("the string is empty")
+ {
+ REQUIRE(s.empty());
+ }
+
+ THEN("the size is equal to 0")
+ {
+ REQUIRE(s.size() == 0);
+ }
+
+ THEN("the length is equal to 0")
+ {
+ REQUIRE(s.length() == 0);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at raises a panic")
+ {
+ REQUIRE_THROWS_AS(s.at(0), kstd::tests::os_panic);
+ }
+
+ THEN("data returns a pointer poiting to a null byte")
+ {
+ REQUIRE(*s.data() == '\0');
+ }
+
+ THEN("c_str returns a pointer poiting to a null byte")
+ {
+ REQUIRE(*s.c_str() == '\0');
+ }
+
+ THEN("the string is convertible to an empty string view")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.empty());
+ }
+ }
+
+ WHEN("constructing from a non-null pointer and a size of 4")
+ {
+ auto ptr = "abcd";
+ auto s = kstd::string{ptr, 4};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 4")
+ {
+ REQUIRE(s.size() == 4);
+ }
+
+ THEN("the length is equal to 4")
+ {
+ REQUIRE(s.length() == 4);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns d")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'd');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns d")
+ {
+ REQUIRE(s[s.size() - 1] == 'd');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns d")
+ {
+ REQUIRE(s.back() == 'd');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 4")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 4);
+ }
+
+ THEN("the string converts to a string view of length 4")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 4);
+ }
+ }
+
+ WHEN("constructing from a non-null pointer and a size of 20")
+ {
+ auto ptr = "abcdefghijABCDEFGHIJ";
+ auto s = kstd::string{ptr, 20};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+
+ THEN("the capacity is equal to 20")
+ {
+ REQUIRE(s.capacity() == 20);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns J")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'J');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns J")
+ {
+ REQUIRE(s[s.size() - 1] == 'J');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 20")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 20);
+ }
+
+ THEN("the string converts to a string view of length 20")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 20);
+ }
+ }
+
+ WHEN("constructing from a C-style string of length 4")
+ {
+ auto ptr = "abcd";
+ auto s = kstd::string{ptr};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 4")
+ {
+ REQUIRE(s.size() == 4);
+ }
+
+ THEN("the length is equal to 4")
+ {
+ REQUIRE(s.length() == 4);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns d")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'd');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns d")
+ {
+ REQUIRE(s[s.size() - 1] == 'd');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns d")
+ {
+ REQUIRE(s.back() == 'd');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 4")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 4);
+ }
+
+ THEN("the string converts to a string view of length 4")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 4);
+ }
+ }
+
+ WHEN("constructing from a C-style string of length 20")
+ {
+ auto ptr = "abcdefghijABCDEFGHIJ";
+ auto s = kstd::string{ptr};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+
+ THEN("the capacity is equal to 20")
+ {
+ REQUIRE(s.capacity() == 20);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns J")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'J');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns J")
+ {
+ REQUIRE(s[s.size() - 1] == 'J');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 20")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 20);
+ }
+
+ THEN("the string converts to a string view of length 20")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 20);
+ }
+ }
+
+ WHEN("constructing from a string view of length 4")
+ {
+ using namespace std::string_view_literals;
+
+ auto view = "abcd"sv;
+ auto s = kstd::string{view};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 4")
+ {
+ REQUIRE(s.size() == 4);
+ }
+
+ THEN("the length is equal to 4")
+ {
+ REQUIRE(s.length() == 4);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns d")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'd');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns d")
+ {
+ REQUIRE(s[s.size() - 1] == 'd');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns d")
+ {
+ REQUIRE(s.back() == 'd');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 4")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 4);
+ }
+
+ THEN("the string converts to a string view of length 4")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 4);
+ }
+ }
+
+ WHEN("constructing from a string view of length 20")
+ {
+ using namespace std::string_view_literals;
+
+ auto view = "abcdefghijABCDEFGHIJ"sv;
+ auto s = kstd::string{view};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+
+ THEN("the capacity is equal to 20")
+ {
+ REQUIRE(s.capacity() == 20);
+ }
+
+ THEN("at(0) returns a")
+ {
+ REQUIRE(s.at(0) == 'a');
+ }
+
+ THEN("at(size() - 1) returns J")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'J');
+ }
+
+ THEN("[0] returns a")
+ {
+ REQUIRE(s[0] == 'a');
+ }
+
+ THEN("[size() - 1] returns J")
+ {
+ REQUIRE(s[s.size() - 1] == 'J');
+ }
+
+ THEN("front returns a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back returns J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("data returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.data() == 'a');
+ }
+
+ THEN("c_str returns a pointer pointing to an a")
+ {
+ REQUIRE(*s.c_str() == 'a');
+ }
+
+ THEN("c_str points to the start of a c-string of length 20")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 20);
+ }
+
+ THEN("the string converts to a string view of length 20")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 20);
+ }
+ }
+
+ WHEN("constructing from a substring of a string view of length 4")
+ {
+ using namespace std::string_view_literals;
+
+ auto view = "abcd"sv;
+ auto s = kstd::string{view, 1, 4};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 3")
+ {
+ REQUIRE(s.size() == 3);
+ }
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+
+ THEN("the capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("at(0) returns b")
+ {
+ REQUIRE(s.at(0) == 'b');
+ }
+
+ THEN("at(size() - 1) returns d")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'd');
+ }
+
+ THEN("[0] returns b")
+ {
+ REQUIRE(s[0] == 'b');
+ }
+
+ THEN("[size() - 1] returns d")
+ {
+ REQUIRE(s[s.size() - 1] == 'd');
+ }
+
+ THEN("front returns b")
+ {
+ REQUIRE(s.front() == 'b');
+ }
+
+ THEN("back returns d")
+ {
+ REQUIRE(s.back() == 'd');
+ }
+
+ THEN("data returns a pointer pointing to an b")
+ {
+ REQUIRE(*s.data() == 'b');
+ }
+
+ THEN("c_str returns a pointer pointing to an b")
+ {
+ REQUIRE(*s.c_str() == 'b');
+ }
+
+ THEN("c_str points to the start of a c-string of length 3")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 3);
+ }
+
+ THEN("the string converts to a string view of length 3")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 3);
+ }
+ }
+
+ WHEN("constructing from a substring of a string view of length 20")
+ {
+ using namespace std::string_view_literals;
+
+ auto view = "abcdefghijABCDEFGHIJ"sv;
+ auto s = kstd::string{view, 1, 20};
+
+ THEN("the string is not empty")
+ {
+ REQUIRE_FALSE(s.empty());
+ }
+
+ THEN("the size is equal to 19")
+ {
+ REQUIRE(s.size() == 19);
+ }
+
+ THEN("the length is equal to 19")
+ {
+ REQUIRE(s.length() == 19);
+ }
+
+ THEN("the capacity is equal to 19")
+ {
+ REQUIRE(s.capacity() == 19);
+ }
+
+ THEN("at(0) returns b")
+ {
+ REQUIRE(s.at(0) == 'b');
+ }
+
+ THEN("at(size() - 1) returns J")
+ {
+ REQUIRE(s.at(s.size() - 1) == 'J');
+ }
+
+ THEN("[0] returns b")
+ {
+ REQUIRE(s[0] == 'b');
+ }
+
+ THEN("[size() - 1] returns J")
+ {
+ REQUIRE(s[s.size() - 1] == 'J');
+ }
+
+ THEN("front returns b")
+ {
+ REQUIRE(s.front() == 'b');
+ }
+
+ THEN("back returns J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("data returns a pointer pointing to an b")
+ {
+ REQUIRE(*s.data() == 'b');
+ }
+
+ THEN("c_str returns a pointer pointing to an b")
+ {
+ REQUIRE(*s.c_str() == 'b');
+ }
+
+ THEN("c_str points to the start of a c-string of length 19")
+ {
+ REQUIRE(std::strlen(s.c_str()) == 19);
+ }
+
+ THEN("the string converts to a string view of length 19")
+ {
+ auto view = static_cast<std::string_view>(s);
+ REQUIRE(view.length() == 19);
}
}
}
- GIVEN("A string view")
+ GIVEN("An existing short string, of length 10")
{
- auto view = std::string_view{"Blub Blub"};
+ auto other = kstd::string{"abcdefghij"};
+
+ WHEN("constructing by copy")
+ {
+ auto s = other;
+
+ THEN("the sizes are identical")
+ {
+ REQUIRE(s.size() == other.size());
+ }
- WHEN("constructing a string from string_view")
+ THEN("the capacities are idendtical")
+ {
+ REQUIRE(s.capacity() == other.capacity());
+ }
+
+ THEN("the underlying strings are identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s.data(), other.data()));
+ }
+ }
+
+ WHEN("constructing by move")
{
- auto str = kstd::string{view};
+ auto s = std::move(other);
+
+ THEN("size is equal to 10")
+ {
+ REQUIRE(s.size() == 10);
+ }
+
+ THEN("capacity is equal to 15")
+ {
+ REQUIRE(s.capacity() == 15);
+ }
+
+ THEN("front() return an a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back() return a j")
+ {
+ REQUIRE(s.back() == 'j');
+ }
- THEN("the string is not empty and has the same size as the view")
+ THEN("The moved from object's size is 0")
{
- REQUIRE_FALSE(str.empty());
- REQUIRE(str.size() == view.size());
+ REQUIRE(other.size() == 0);
}
- THEN("the string contains the same characters as the view")
+ THEN("The moved from object's capacity is 15")
{
- REQUIRE(str == view);
+ REQUIRE(other.capacity() == 15);
+ }
+
+ THEN("c_str() on the moved from object points to a null byte")
+ {
+ REQUIRE(*other.c_str() == '\0');
}
}
}
- GIVEN("A C-style string")
+ GIVEN("An existing short string, of length 20")
{
- auto c_str = "Blub Blub";
+ auto other = kstd::string{"abcdefghijABCDEFGHIJ"};
- WHEN("constructing a string from the C-style string")
+ WHEN("constructing by copy")
{
- auto str = kstd::string{c_str};
+ auto s = other;
- THEN("the string is not empty and has the same size as the C-style string")
+ THEN("the sizes are identical")
{
- REQUIRE_FALSE(str.empty());
- REQUIRE(str.size() == std::strlen(c_str));
+ REQUIRE(s.size() == other.size());
}
- THEN("the string contains the same characters as the C-style string")
+ THEN("the capacities are idendtical")
{
- REQUIRE(str == c_str);
+ REQUIRE(s.capacity() == other.capacity());
+ }
+
+ THEN("the underlying strings are identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s.data(), other.data()));
+ }
+ }
+
+ WHEN("constructing by move")
+ {
+ auto s = std::move(other);
+
+ THEN("size is equal to 20")
+ {
+ REQUIRE(s.size() == 20);
+ }
+
+ THEN("capacity is equal to 20")
+ {
+ REQUIRE(s.capacity() == 20);
+ }
+
+ THEN("front() return an a")
+ {
+ REQUIRE(s.front() == 'a');
+ }
+
+ THEN("back() return a J")
+ {
+ REQUIRE(s.back() == 'J');
+ }
+
+ THEN("The moved from object's size is 0")
+ {
+ REQUIRE(other.size() == 0);
+ }
+
+ THEN("The moved from object's capacity is 15")
+ {
+ REQUIRE(other.capacity() == 15);
+ }
+
+ THEN("c_str() on the moved from object points to a null byte")
+ {
+ REQUIRE(*other.c_str() == '\0');
}
}
}
+}
- GIVEN("A character")
+SCENARIO("String assignment", "[string]")
+{
+ GIVEN("Two short strings")
{
- auto ch = 'x';
+ auto s1 = kstd::string{"abcd"};
+ auto s2 = kstd::string{"defghij"};
+
+ WHEN("copy assigning the shorter to the longer one")
+ {
+ s2 = s1;
+
+ THEN("the new length of the longer one is equal to the length of the shorter one")
+ {
+ REQUIRE(s2.length() == s1.length());
+ }
+
+ THEN("the underlying data of the two is identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s1.data(), s2.data()));
+ }
+ }
+
+ WHEN("copy assigning the longer to the shorter one")
+ {
+ s1 = s2;
- WHEN("constructing a string from the character")
+ THEN("the new length of the shorter one is equal to the length of the longer one")
+ {
+ REQUIRE(s1.length() == s2.length());
+ }
+
+ THEN("the underlying data of the two is identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s2.data(), s1.data()));
+ }
+ }
+
+ WHEN("move assigning the shorter to the longer one")
+ {
+ s2 = std::move(s1);
+
+ THEN("the new length of the longer one is equal to the original length of the shorter one")
+ {
+ REQUIRE(s2.length() == 4);
+ }
+
+ THEN("the length of the moved from one is 0")
+ {
+ REQUIRE(s1.length() == 0);
+ }
+
+ THEN("the capacity of the moved from one is 15")
+ {
+ REQUIRE(s1.capacity() == 15);
+ }
+
+ THEN("the capacity of the moved to one is 15")
+ {
+ REQUIRE(s2.capacity() == 15);
+ }
+ }
+
+ WHEN("move assigning the longer to the shorter one")
{
- auto str = kstd::string{ch};
+ s1 = std::move(s2);
+
+ THEN("the new length of the shorter one is equal to the original length of the longer one")
+ {
+ REQUIRE(s1.length() == 7);
+ }
+
+ THEN("the length of the moved from one is 0")
+ {
+ REQUIRE(s2.length() == 0);
+ }
- THEN("the string is not empty and has size 1")
+ THEN("the capacity of the moved from one is 15")
{
- REQUIRE_FALSE(str.empty());
- REQUIRE(str.size() == 1);
+ REQUIRE(s2.capacity() == 15);
}
- THEN("the string contains the same character as the given character")
+ THEN("the capacity of the moved to one is 15")
{
- REQUIRE(str == std::string_view{&ch, 1});
+ REQUIRE(s1.capacity() == 15);
}
}
}
- GIVEN("Another string")
+ GIVEN("One short and one long string")
{
- auto other = kstd::string{"Blub Blub"};
+ auto s1 = kstd::string{"abcd"};
+ auto s2 = kstd::string{"ABCDEFGHIJabcdefghij"};
- WHEN("copy constructing a new string")
+ WHEN("copy assigning the shorter to the longer one")
{
- auto str = kstd::string{other};
+ s2 = s1;
- THEN("the new string contains the same characters as the original")
+ THEN("the new length of the longer one is equal to the length of the shorter one")
{
- REQUIRE(static_cast<std::string_view>(str) == static_cast<std::string_view>(other));
+ REQUIRE(s2.length() == s1.length());
+ }
+
+ THEN("the new capacity of the longer one is 15")
+ {
+ REQUIRE(s2.capacity() == 15);
+ }
+
+ THEN("the underlying data of the two is identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s1.data(), s2.data()));
}
}
- auto str = kstd::string{"Blub"};
+ WHEN("copy assigning the longer to the shorter one")
+ {
+ s1 = s2;
- WHEN("copy assigning another string")
+ THEN("the new length of the shorter one is equal to the length of the longer one")
+ {
+ REQUIRE(s1.length() == s2.length());
+ }
+
+ THEN("the new capacity of the shorter one is 20")
+ {
+ REQUIRE(s1.capacity() == 20);
+ }
+
+ THEN("the underlying data of the two is identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s2.data(), s1.data()));
+ }
+ }
+
+ WHEN("move assigning the shorter to the longer one")
{
- auto other = kstd::string{"Blub Blub"};
- str = other;
+ s2 = std::move(s1);
- THEN("the string contains the same characters as the assigned string")
+ THEN("the new length of the longer one is equal to the original length of the shorter one")
{
- REQUIRE(static_cast<std::string_view>(str) == static_cast<std::string_view>(other));
+ REQUIRE(s2.length() == 4);
+ }
+
+ THEN("the length of the moved from one is 0")
+ {
+ REQUIRE(s1.length() == 0);
+ }
+
+ THEN("the capacity of the moved from one is 15")
+ {
+ REQUIRE(s1.capacity() == 15);
+ }
+
+ THEN("the capacity of the moved to one is 15")
+ {
+ REQUIRE(s2.capacity() == 15);
+ }
+ }
+
+ WHEN("move assigning the longer to the shorter one")
+ {
+ s1 = std::move(s2);
+
+ THEN("the new length of the shorter one is equal to the original length of the longer one")
+ {
+ REQUIRE(s1.length() == 20);
+ }
+
+ THEN("the length of the moved from one is 0")
+ {
+ REQUIRE(s2.length() == 0);
+ }
+
+ THEN("the capacity of the moved from one is 15")
+ {
+ REQUIRE(s2.capacity() == 15);
+ }
+
+ THEN("the capacity of the moved to one is 15")
+ {
+ REQUIRE(s1.capacity() == 20);
}
}
}
- GIVEN("A string")
+ GIVEN("Two long strings")
{
- auto str = kstd::string{"Hello"};
+ auto s1 = kstd::string{"abcdefghijABCDEFGH"};
+ auto s2 = kstd::string{"ABCDEFGHIJabcdefghij"};
- WHEN("copy assigning a string view")
+ WHEN("copy assigning the shorter to the longer one")
{
- auto view = std::string_view{"Hello, world!"};
- str = view;
+ s2 = s1;
- THEN("the string contains the same characters as the assigned view")
+ THEN("the new length of the longer one is equal to the length of the shorter one")
{
- REQUIRE(str == view);
+ REQUIRE(s2.length() == s1.length());
+ }
+
+ THEN("the new capacity of the longer one is still 20")
+ {
+ REQUIRE(s2.capacity() == 20);
+ }
+
+ THEN("the underlying data of the two is identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s1.data(), s2.data()));
+ }
+ }
+
+ WHEN("copy assigning the longer to the shorter one")
+ {
+ s1 = s2;
+
+ THEN("the new length of the shorter one is equal to the length of the longer one")
+ {
+ REQUIRE(s1.length() == s2.length());
+ }
+
+ THEN("the new capacity of the shorter one is 20")
+ {
+ REQUIRE(s1.capacity() == 20);
+ }
+
+ THEN("the underlying data of the two is identical")
+ {
+ REQUIRE_FALSE(std::strcmp(s2.data(), s1.data()));
+ }
+ }
+
+ WHEN("move assigning the shorter to the longer one")
+ {
+ s2 = std::move(s1);
+
+ THEN("the new length of the longer one is equal to the original length of the shorter one")
+ {
+ REQUIRE(s2.length() == 18);
+ }
+
+ THEN("the length of the moved from one is 0")
+ {
+ REQUIRE(s1.length() == 0);
+ }
+
+ THEN("the capacity of the moved from one is 15")
+ {
+ REQUIRE(s1.capacity() == 15);
+ }
+
+ THEN("the capacity of the moved to one is 15")
+ {
+ REQUIRE(s2.capacity() == 18);
+ }
+ }
+
+ WHEN("move assigning the longer to the shorter one")
+ {
+ s1 = std::move(s2);
+
+ THEN("the new length of the shorter one is equal to the original length of the longer one")
+ {
+ REQUIRE(s1.length() == 20);
+ }
+
+ THEN("the length of the moved from one is 0")
+ {
+ REQUIRE(s2.length() == 0);
+ }
+
+ THEN("the capacity of the moved from one is 15")
+ {
+ REQUIRE(s2.capacity() == 15);
+ }
+
+ THEN("the capacity of the moved to one is 15")
+ {
+ REQUIRE(s1.capacity() == 20);
}
}
}
- GIVEN("A string")
+ GIVEN("An short string")
{
- auto str = kstd::string{"Hello"};
+ auto s = kstd::string{"abcd"};
+
+ WHEN("assigning a new, shorter c-style string of length 3")
+ {
+ s = "def";
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+ }
+
+ WHEN("assigning a new, longer, c-style string of length 5")
+ {
+ s = "defgh";
+
+ THEN("the length is equal to 5")
+ {
+ REQUIRE(s.length() == 5);
+ }
+ }
+
+ WHEN("assigning a new, longer, c-style string of length 20")
+ {
+ s = "ABCDEFGHIJabcdefghij";
- WHEN("copy assigning a C-style string")
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+ }
+
+ WHEN("assigning a single character")
{
- auto c_str = "Hello, world!";
- str = c_str;
+ s = 'z';
- THEN("the string contains the same characters as the assigned C-style string")
+ THEN("the length is equal to 1")
{
- REQUIRE(str == c_str);
+ REQUIRE(s.length() == 1);
+ }
+ }
+
+ WHEN("assigning an shorter initializer list of length 3")
+ {
+ s = {'d', 'e', 'f'};
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+ }
+
+ WHEN("assigning an longer initializer list of length 5")
+ {
+ s = {'d', 'e', 'f', 'g', 'h'};
+
+ THEN("the length is equal to 5")
+ {
+ REQUIRE(s.length() == 5);
+ }
+ }
+
+ WHEN("assigning an longer initializer list of length 20")
+ {
+ s = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+ }
+
+ WHEN("assigning from a shorter string view of length 3")
+ {
+ using namespace std::string_view_literals;
+
+ s = "def"sv;
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+ }
+
+ WHEN("assigning from a longer string view of length 5")
+ {
+ using namespace std::string_view_literals;
+
+ s = "defgh"sv;
+
+ THEN("the length is equal to 5")
+ {
+ REQUIRE(s.length() == 5);
+ }
+ }
+
+ WHEN("assigning from a longer string view of length 20")
+ {
+ using namespace std::string_view_literals;
+
+ s = "ABCDEFGHIJabcdefghij"sv;
+
+ THEN("the length is equal to 20")
+ {
+ REQUIRE(s.length() == 20);
+ }
+ }
+ }
+
+ GIVEN("An long string")
+ {
+ auto s = kstd::string{"abcdefghijABCDEFGHIJ"};
+
+ WHEN("assigning a new, shorter c-style string of length 3")
+ {
+ s = "def";
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+ }
+
+ WHEN("assigning a new, longer, c-style string of length 22")
+ {
+ s = "ABCDEFGHIJabcdefghijkl";
+
+ THEN("the length is equal to 22")
+ {
+ REQUIRE(s.length() == 22);
+ }
+ }
+
+ WHEN("assigning a single character")
+ {
+ s = 'z';
+
+ THEN("the length is equal to 1")
+ {
+ REQUIRE(s.length() == 1);
+ }
+ }
+
+ WHEN("assigning an shorter initializer list of length 3")
+ {
+ s = {'d', 'e', 'f'};
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+ }
+
+ WHEN("assigning an longer initializer list of length 22")
+ {
+ s = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'a',
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'};
+
+ THEN("the length is equal to 22")
+ {
+ REQUIRE(s.length() == 22);
+ }
+ }
+
+ WHEN("assigning from a shorter string view of length 3")
+ {
+ using namespace std::string_view_literals;
+
+ s = "def"sv;
+
+ THEN("the length is equal to 3")
+ {
+ REQUIRE(s.length() == 3);
+ }
+ }
+
+ WHEN("assigning from a longer string view of length 22")
+ {
+ using namespace std::string_view_literals;
+
+ s = "ABCDEFGHIJabcdefghijkl"sv;
+
+ THEN("the length is equal to 22")
+ {
+ REQUIRE(s.length() == 22);
}
}
}
}
-SCENARIO("String concatenation", "[string]")
+SCENARIO("String modifiers", "[string]")
{
+ GIVEN("A short string")
+ {
+ auto s = kstd::string{"abcd"};
+ auto old_capacity = s.capacity();
+ auto old_size = s.size();
+ auto old_data = s.data();
+
+ WHEN("reserving a smaller capacity")
+ {
+ s.reserve(1);
+
+ THEN("the capacity does not change")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("the content stays the same")
+ {
+ REQUIRE(s == "abcd");
+ }
+
+ THEN("the size stays the same")
+ {
+ REQUIRE(s.size() == old_size);
+ }
+
+ THEN("the data pointer stays the same")
+ {
+ REQUIRE(s.data() == old_data);
+ }
+ }
+
+ WHEN("reserving equal capacity")
+ {
+ s.reserve(old_capacity);
+
+ THEN("the capacity does not change")
+ {
+ REQUIRE(s.capacity() == old_capacity);
+ }
+
+ THEN("the content stays the same")
+ {
+ REQUIRE(s == "abcd");
+ }
+
+ THEN("the size stays the same")
+ {
+ REQUIRE(s.size() == old_size);
+ }
+
+ THEN("the data pointer stays the same")
+ {
+ REQUIRE(static_cast<void const *>(s.data()) == static_cast<void const *>(old_data));
+ }
+ }
+
+ WHEN("reserving larger capacity")
+ {
+ s.reserve(old_capacity + 1);
+
+ THEN("the capacity increases")
+ {
+ REQUIRE(s.capacity() >= old_capacity + 1);
+ }
+
+ THEN("the content stays the same")
+ {
+ REQUIRE(s == "abcd");
+ }
+
+ THEN("the size stays the same")
+ {
+ REQUIRE(s.size() == old_size);
+ }
+
+ THEN("the data pointer changes")
+ {
+ REQUIRE(s.data() != old_data);
+ }
+ }
+ }
+
GIVEN("Two strings")
{
auto str1 = kstd::string{"Blub"};
@@ -187,21 +1988,6 @@ SCENARIO("String concatenation", "[string]")
REQUIRE(str1.size() == str2.size() + 4);
}
}
-
- WHEN("using operator+ to concatenate the two strings into a new string")
- {
- auto str3 = str1 + str2;
-
- THEN("the new string contains the characters of both strings concatenated")
- {
- REQUIRE(str3 == "Blub Blub");
- }
-
- THEN("the size of the new string is the sum of the sizes of both strings")
- {
- REQUIRE(str3.size() == str1.size() + str2.size());
- }
- }
}
GIVEN("A string and a string view")
@@ -260,6 +2046,51 @@ SCENARIO("String concatenation", "[string]")
}
}
}
+
+ GIVEN("A non-empty string")
+ {
+ auto str = kstd::string{"Blub Blub"};
+
+ WHEN("clearing the string")
+ {
+ str.clear();
+
+ THEN("the string is empty and has size zero")
+ {
+ REQUIRE(str.empty());
+ REQUIRE(str.size() == 0);
+ }
+
+ THEN("the string contains no characters")
+ {
+ REQUIRE(str == std::string_view{});
+ }
+ }
+ }
+}
+
+SCENARIO("String concatenation", "[string]")
+{
+ GIVEN("Two strings")
+ {
+ auto str1 = kstd::string{"Blub"};
+ auto str2 = kstd::string{" Blub"};
+
+ WHEN("using operator+ to concatenate the two strings into a new string")
+ {
+ auto str3 = str1 + str2;
+
+ THEN("the new string contains the characters of both strings concatenated")
+ {
+ REQUIRE(str3 == "Blub Blub");
+ }
+
+ THEN("the size of the new string is the sum of the sizes of both strings")
+ {
+ REQUIRE(str3.size() == str1.size() + str2.size());
+ }
+ }
+ }
}
SCENARIO("String conversion and comparison", "[string]")
@@ -317,30 +2148,6 @@ SCENARIO("String conversion and comparison", "[string]")
}
}
-SCENARIO("String clearing", "[string]")
-{
- GIVEN("A non-empty string")
- {
- auto str = kstd::string{"Blub Blub"};
-
- WHEN("clearing the string")
- {
- str.clear();
-
- THEN("the string is empty and has size zero")
- {
- REQUIRE(str.empty());
- REQUIRE(str.size() == 0);
- }
-
- THEN("the string contains no characters")
- {
- REQUIRE(str == std::string_view{});
- }
- }
- }
-}
-
SCENARIO("String iteration", "[string]")
{
GIVEN("A string")