Skip to content

Commit

Permalink
tweak: string compliance fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Force67 committed May 12, 2024
1 parent 9a3fb21 commit 463ce77
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 43 deletions.
77 changes: 48 additions & 29 deletions base/containers/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ namespace base {

enum class VectorReservePolicy {
kForPushback, // < This optimization allows you to utilize push_back without
// immediately increasing the capacity, reserving additional space
// only when necessary.
kForData, // < This reserve operation functions similarly to what you're
// accustomed to with std::vector. It preallocates capacity, effectively
// simulating the insertion of a number of "empty" elements. If you
// intend to copy data, especially using .data(), opt for this approach.
// immediately increasing the capacity, reserving additional
// space only when necessary.
kForData, // < This reserve operation functions similarly to what you're
// accustomed to with std::vector. It preallocates capacity,
// effectively simulating the insertion of a number of "empty"
// elements. If you intend to copy data, especially using .data(),
// opt for this approach.
};

template <typename T, class TAllocator = base::DefaultAllocator>
Expand Down Expand Up @@ -106,9 +107,10 @@ class Vector {

// increase internal capacity
void reserve(mem_size new_reserved_capacity) {
DCHECK(new_reserved_capacity != 0 && capacity() != 0,
"Vector::reserve: Use resize instead of resize for populating an empty "
"Vector");
DCHECK(
new_reserved_capacity != 0 && capacity() != 0,
"Vector::reserve: Use resize instead of resize for populating an empty "
"Vector");

if (new_reserved_capacity > capacity()) [[likely]]
GrowCapacity(capacity(), new_reserved_capacity);
Expand Down Expand Up @@ -166,24 +168,24 @@ class Vector {

[[nodiscard]] T* find(const T& element_match) const {
if (empty()) [[unlikely]]
return nullptr;
return nullptr;

mem_size left = 0;
mem_size right = size() - 1;
mem_size left = 0;
mem_size right = size() - 1;

while (left <= right) {
mem_size middle = left + (right - left) / 2;
T& middle_element = *(begin() + middle);
while (left <= right) {
mem_size middle = left + (right - left) / 2;
T& middle_element = *(begin() + middle);

if (middle_element == element_match)
return &middle_element;
else if (middle_element < element_match)
left = middle + 1;
else
right = middle - 1;
}
if (middle_element == element_match)
return &middle_element;
else if (middle_element < element_match)
left = middle + 1;
else
right = middle - 1;
}

return nullptr;
return nullptr;
}

// single element at a specified position.
Expand Down Expand Up @@ -219,8 +221,8 @@ class Vector {
}
// Insert new elements
for (auto it = pos; it != pos + count; ++it) {
::new (static_cast<void*>(&*it)) T(value);
}
::new (static_cast<void*>(&*it)) T(value);
}
end_ += count;
}

Expand All @@ -238,10 +240,10 @@ class Vector {
for (auto it = end_ + distance - 1; it >= pos + distance; --it) {
*it = base::move(*(it - distance));
}

// Copy new elements
memcpy(pos, first, distance * sizeof(T));
//std::copy(first, last, pos);
// std::copy(first, last, pos);
end_ += distance;
}

Expand All @@ -257,14 +259,15 @@ class Vector {
if (dest > end_ || source > end_)
return false;

// if we remove in the middle, we memmove the upper objects down by one place.
// if we remove in the middle, we memmove the upper objects down by one
// place.
memmove(dest, source, end_ - source);
--end_;
end_->~T();
return true;
}

bool erase(T* element_ptr) {
bool erase(T* element_ptr) {
if (element_ptr < data_ || element_ptr >= end_) {
return false; // Pointer is out of bounds
}
Expand Down Expand Up @@ -349,6 +352,22 @@ class Vector {
return false;
}

template <typename TFunc>
void ForEach(TFunc&& func) {
for (auto* it = begin(); it != end(); ++it) {
func(*it);
}
}

template <typename TFunc>
T* FindIf(TFunc&& func) {
for (auto* it = begin(); it != end(); ++it) {
if (func(*it))
return it;
}
return nullptr;
}

private:
mem_size CalculateNewCapacity(mem_size cap) {
return cap > 0 ? cap * /*capacity_mult_*/ kDefaultMult : 1;
Expand Down
10 changes: 5 additions & 5 deletions base/filesystem/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace base {
#if defined(OS_WIN)
#define BASE_PATH_SEP_MACRO L'\\'
#define BASE_PATH_LITERAL(x) L##x
#endif
#endif

#if defined(OS_POSIX)
#define BASE_PATH_SEP_MACRO '/'
Expand Down Expand Up @@ -59,12 +59,12 @@ class BASE_EXPORT Path {
Path() = default;

// all of these will CHECK if the desired encoding is violated
Path(const char* ascii_only);
/*implicit*/ Path(const char* ascii_only); // implicit to allow: path / blah.c_str()
Path(const base::StringRefU8);
Path(const base::StringRefW);
Path(const BufferType& path);
explicit Path(const BufferType& path);
// from other.
Path(const Path& other);
/*implicit*/ Path(const Path& other);

// append operations
friend Path operator/(const Path& lhs, const Path& rhs);
Expand All @@ -83,7 +83,7 @@ class BASE_EXPORT Path {
// append another path to this path, and insert a seperator in between of them
Path& Append(const Path&);


bool AppendExtension(const char* ascii_only, const bool ensure_dot = true);

// modifies the buffer to the internal path notation e.g. backslashes on windows or
// forward slashes on *nix
Expand Down
9 changes: 9 additions & 0 deletions base/filesystem/posix/path_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ Path::Path(const base::StringRefW wide_text) {
Normalize(path_buf_);
}

bool Path::AppendExtension(const char* ascii_only, const bool ensure_dot) {
DCHECK(base::DoIsStringASCII(ascii_only, base::CountStringLength(ascii_only)),
"Extension must be ASCII only");
if (ascii_only[0] != '.' && ensure_dot) {
path_buf_ += '.';
}
path_buf_ += base::String(ascii_only);
}

void Path::Normalize(BufferType& buffer) {
for (std::size_t i = 0; i < buffer.size(); ++i) {
auto& c = buffer[i];
Expand Down
18 changes: 15 additions & 3 deletions base/filesystem/win/path_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,26 @@ Path::Path(const base::StringRefW wide_text) {
Normalize(path_buf_);
}

bool Path::AppendExtension(const char* ascii_only, const bool ensure_dot) {
const auto ext = base::ASCIIToWide(ascii_only);
if (ext.empty()) {
return false;
}
if (ext[0] != L'.' && ensure_dot) {
path_buf_ += L'.';
}
path_buf_ += ext;
return true;
}

void Path::Normalize(BufferType& buffer) {
for (mem_size i = 0; i < buffer.size(); i++) {
auto& c = buffer[i];
bool matches = c == L'/';

// windows folk like to put two forward slashes in their path names, so we have
// to check if the next character also contains a forward slash, and if so,
// remove it
// windows folk like to put two forward slashes in their path names, so we
// have to check if the next character also contains a forward slash, and if
// so, remove it
if (matches && i + 1 <= buffer.size()) {
if (buffer[i + 1] == L'/') {
buffer.erase(buffer.begin() + (i + 1));
Expand Down
25 changes: 21 additions & 4 deletions base/strings/base_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class BasicBaseString {
BasicBaseString() noexcept = default;

// construct from a string
explicit BasicBaseString(const character_type* str) { assign(str); }
/*implicit*/ BasicBaseString(const character_type* str) { assign(str); }
explicit BasicBaseString(const character_type* str,
mem_size len_in_characters) {
assign(str, len_in_characters);
Expand All @@ -52,7 +52,7 @@ class BasicBaseString {

// construct from a character array
template <mem_size N>
explicit BasicBaseString(const character_type (&arr)[N]) {
/*implicit*/ BasicBaseString(const character_type (&arr)[N]) {
assign(arr, N - 1);
}

Expand Down Expand Up @@ -170,6 +170,16 @@ class BasicBaseString {
}
append(str, base::CountStringLength(str));
}
void append(const mem_size n, const character_type c) {
mem_size new_size = size_in_chars_ + n;
if (new_size >= cap_in_chars_) {
Reallocate(new_size);
}
memset(&data_[size_in_chars_], c, n * sizeof(character_type));
size_in_chars_ = new_size;
data_[size_in_chars_] = '\0';
}


void push_back(character_type c) {
const auto new_size = size_in_chars_ + 1;
Expand Down Expand Up @@ -364,9 +374,16 @@ class BasicBaseString {
BUGCHECK(index < size_in_chars_, "Index out of bounds");
return data_[index];
}
character_type* at(mem_size index) {
character_type& at(mem_size index) {
BUGCHECK(index < size_in_chars_, "Index out of bounds");
return data_ + index;
return data_[index];
}

character_type* at_if(mem_size index) {
if (index < size_in_chars_) {
return data_ + index;
}
return nullptr;
}

// search functions ========================================
Expand Down
17 changes: 15 additions & 2 deletions base/strings/base_string_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ TYPED_TEST(BaseStringTest, Construction) {
ASSERT_EQ(base_str_copy.compare(base_str_from_c_str), 0);
}

TEST(BaseStringTest, ConstructFromArray) {
using BaseStringType = base::BasicBaseString<char8_t>;
using StdStringType = std::basic_string<char8_t>;

const char8_t kTestSentence8[] = u8"Hello, world!";
const char8_t kTestSentence8Copy[] = u8"Hello, world!";
const char8_t kTestSentence8Copy2[] = u8"Hello, world!";
const char8_t kTestSentence8Copy3[] = u8"Hello, world!";

const BaseStringType base_str(kTestSentence8);
BaseStringType base_str_copy(kTestSentence8Copy);
}

TYPED_TEST(BaseStringTest, Assignment) {
using BaseStringType = typename TestFixture::BaseStringType;
using StdStringType = typename TestFixture::StdStringType;
Expand Down Expand Up @@ -143,7 +156,7 @@ TEST(BaseStringTest, CompareSubstring) {
const BaseStringType str3("Hello, Universe!");
ASSERT_NE(str1.compare(0, str1.size(), str3), 0);
}
#if 1

TYPED_TEST(BaseStringTest, Concatenation) {
using BaseStringType = typename TestFixture::BaseStringType;
using StdStringType = typename TestFixture::StdStringType;
Expand All @@ -165,7 +178,7 @@ TYPED_TEST(BaseStringTest, Concatenation) {
ASSERT_EQ(base_str.size(), std_str_from_c_str_twice.size());
ASSERT_EQ(base_str.compare(std_str_from_c_str_twice), 0);
}
#endif

#if 1
TEST(BaseStringTest, PushBack) {
using BaseStringType = typename base::BasicBaseString<char>;
Expand Down

0 comments on commit 463ce77

Please sign in to comment.