[Glacier] Add a StringView class and StrSplit method.

This commit is contained in:
Drew Galbraith 2023-11-02 20:23:28 -07:00
parent b6c220a350
commit a2e80952c8
8 changed files with 159 additions and 4 deletions

View File

@ -1,5 +1,8 @@
add_library(glacier STATIC add_library(glacier STATIC
string/string.cpp) string/string.cpp
string/string_view.cpp
string/str_split.cpp
)
target_include_directories(glacier target_include_directories(glacier
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}

View File

@ -11,10 +11,18 @@ class Vector {
Vector() : data_(nullptr), size_(0), capacity_(0) {} Vector() : data_(nullptr), size_(0), capacity_(0) {}
Vector(const Vector&) = delete; Vector(const Vector&) = delete;
// TODO: Implement Move Vector(Vector&& other)
Vector(Vector&&) = delete; : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
other.data_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
}
~Vector() { delete[] data_; } ~Vector() {
if (data_) {
delete[] data_;
}
}
// FIXME: Handle downsizing. // FIXME: Handle downsizing.
void Resize(uint64_t capacity); void Resize(uint64_t capacity);

View File

@ -0,0 +1,17 @@
#include "glacier/string/str_split.h"
namespace glcr {
Vector<StringView> StrSplit(const StringView& str, char delimiter) {
Vector<StringView> strings;
uint64_t cur_pos = 0;
uint64_t next_pos = 0;
while ((next_pos = str.find(delimiter, cur_pos)) != str.npos) {
strings.PushBack(str.substr(cur_pos, next_pos - cur_pos));
cur_pos = next_pos + 1;
}
strings.PushBack(str.substr(cur_pos, str.size() - cur_pos));
return strings;
}
} // namespace glcr

View File

@ -0,0 +1,11 @@
#pragma once
#include "glacier/container/vector.h"
#include "glacier/string/string_view.h"
namespace glcr {
// TODO: Add a split that uses a StringView as a delimeter.
Vector<StringView> StrSplit(const StringView& str, char delimeter);
} // namespace glcr

View File

@ -26,6 +26,8 @@ String::String(const char* cstr, uint64_t str_len) : length_(str_len) {
cstr_[length_] = '\0'; cstr_[length_] = '\0';
} }
String::String(StringView str) : String(str.data(), str.size()) {}
bool String::operator==(const String& other) { bool String::operator==(const String& other) {
if (other.length_ != length_) { if (other.length_ != length_) {
return false; return false;
@ -43,4 +45,6 @@ char String::operator[](uint64_t offset) const {
return cstr_[offset]; return cstr_[offset];
} }
String::operator StringView() const { return StringView(cstr_, length_); }
} // namespace glcr } // namespace glcr

View File

@ -2,6 +2,8 @@
#include <stdint.h> #include <stdint.h>
#include "glacier/string/string_view.h"
namespace glcr { namespace glcr {
class String { class String {
@ -9,6 +11,7 @@ class String {
String(); String();
String(const char* cstr); String(const char* cstr);
String(const char* cstr, uint64_t str_len); String(const char* cstr, uint64_t str_len);
String(StringView str);
const char* cstr() const { return cstr_; } const char* cstr() const { return cstr_; }
uint64_t length() const { return length_; } uint64_t length() const { return length_; }
@ -16,6 +19,7 @@ class String {
bool operator==(const String& str); bool operator==(const String& str);
char operator[](uint64_t offset) const; char operator[](uint64_t offset) const;
operator StringView() const;
private: private:
char* cstr_; char* cstr_;

View File

@ -0,0 +1,73 @@
#include "glacier/string/string_view.h"
namespace glcr {
namespace {
uint64_t cstrlen(const char* ptr) {
uint64_t len = 0;
while (ptr[len] != '\0') {
len++;
}
return len;
}
} // namespace
StringView::StringView() {}
StringView::StringView(const char* str) : value_(str), size_(cstrlen(str)) {}
StringView::StringView(const char* str, uint64_t count)
: value_(str), size_(count) {}
const char* StringView::data() const { return value_; }
uint64_t StringView::size() const { return size_; }
bool StringView::empty() const { return size_ == 0; }
char StringView::at(uint64_t pos) const { return value_[pos]; }
uint64_t StringView::find(char c, uint64_t pos) const {
for (uint64_t i = pos; i < size_; i++) {
if (value_[i] == c) {
return i;
}
}
return npos;
}
StringView StringView::substr(uint64_t start, uint64_t count) const {
// FIXME: Report an error here maybe.
if (start >= size_) {
return StringView{};
}
if (start + count > size_) {
count = size_ - start;
}
return StringView(value_ + start, count);
}
bool operator==(const StringView& str1, const StringView& str2) {
if (str1.empty() && str2.empty()) {
return true;
}
if (str1.size() != str2.size()) {
return false;
}
if (str1.data() == str2.data()) {
// Short circuit if they are the same exact string.
return true;
}
for (uint64_t i = 0; i < str1.size(); i++) {
if (str1.at(i) != str2.at(i)) {
return false;
}
}
return true;
}
bool operator!=(const StringView& str1, const StringView& str2) {
return !(str1 == str2);
}
} // namespace glcr

View File

@ -0,0 +1,35 @@
#pragma once
#include <stdint.h>
namespace glcr {
class StringView {
public:
static const uint64_t npos = -1;
StringView();
StringView(const StringView& other) = default;
StringView(const char* str);
StringView(const char* str, uint64_t count);
const char* data() const;
uint64_t size() const;
bool empty() const;
char at(uint64_t pos) const;
uint64_t find(char c, uint64_t pos = 0) const;
StringView substr(uint64_t start, uint64_t count) const;
private:
const char* value_ = nullptr;
uint64_t size_ = 0;
};
bool operator==(const StringView& str1, const StringView& str2);
bool operator!=(const StringView& str1, const StringView& str2);
} // namespace glcr