[Glacier] Add a StringView class and StrSplit method.
This commit is contained in:
parent
b6c220a350
commit
a2e80952c8
|
@ -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}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue