Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions include/stdbigos/string_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#ifndef STDBIGOS_STRING_VIEW
#define STDBIGOS_STRING_VIEW

#include <stddef.h>

typedef struct {
const char* data;
size_t count;
} string_view;

static inline string_view strv_init(const char* str) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Names of functions that acting as methods for a structs should start with the full name of the struct

if (!str)
return (string_view){NULL, 0};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use nullptr instead of NULL

string_view ret;
ret.data = str;

const char* i = str;
while (*i) {
i++;
}

ret.count = (size_t)(i - str);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use strlen from stdbigos/string.h

return ret;
}

static inline size_t strvlen(string_view strv) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this function is necessary

return strv.count;
}

static inline size_t strvnlen(string_view strv, size_t maxlen) {
return strv.count < maxlen ? strv.count : maxlen;
}

static inline string_view strv_pop_front(string_view strv) {
if (strv.count == 0)
return strv;
strv.data++;
strv.count--;
return strv;
}

static inline string_view strv_pop_back(string_view strv) {
if (strv.count == 0)
return strv;
strv.count--;
return strv;
}

static inline int strvcmp(string_view a, string_view b) {
size_t min = a.count < b.count ? a.count : b.count;

for (size_t i = 0; i < min; i++) {
unsigned char ca = (unsigned char)a.data[i];
unsigned char cb = (unsigned char)b.data[i];

if (ca < cb)
return -1;
if (ca > cb)
return 1;
}

if (a.count < b.count)
return -1;
if (a.count > b.count)
return 1;
return 0;
}

static inline int strvncmp(string_view a, string_view b, size_t n) {
size_t min = a.count < b.count ? a.count : b.count;
if (min > n)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use MIN(a, b) from math.h

min = n;

for (size_t i = 0; i < min; i++) {
unsigned char ca = (unsigned char)a.data[i];
unsigned char cb = (unsigned char)b.data[i];

if (ca < cb)
return -1;
if (ca > cb)
return 1;
}

if (a.count < n && a.count < b.count)
return -1;
if (b.count < n && b.count < a.count)
return 1;
return 0;
}

static inline string_view strvchr(string_view strv, int c) {
if (!strv.data)
return (string_view){NULL, 0};
unsigned char ch = (unsigned char)c;
while (strv.count > 0 && (unsigned char)strv.data[0] != ch) {
strv = strv_pop_front(strv);
}
return strv;
}

static inline string_view strvtok(string_view strv, string_view delim) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't abbreviate names unnecessarily. Naming this like string_view_tokenise would be better imo. Also I think this function would be easier to use if it took a string view by reference so that returned string view has the token and the one taken as reference would have the rest of the string

if (!strv.data)
return (string_view){NULL, 0};
string_view ret;
ret.data = strv.data;
ret.count = 0;
while (strv.count > 0 && strvchr(delim, *strv.data).count == 0) {
strv = strv_pop_front(strv);
ret.count++;
}
return ret;
}

static inline size_t strvspn(string_view strv, string_view chars) {
if (!strv.data)
return 0;
for (size_t i = 0; i < strv.count; i++) {
if (strvchr(chars, strv.data[i]).count == 0)
return i;
}
return strv.count;
}

static inline size_t strvcspn(string_view strv, string_view chars) {
if (!strv.data)
return 0;
for (size_t i = 0; i < strv.count; i++) {
if (strvchr(chars, strv.data[i]).count > 0)
return i;
}
return strv.count;
}

static inline string_view strvpbrk(string_view strv, string_view breakset) {
if (!strv.data)
return (string_view){NULL, 0};
while (strv.count > 0 && strvchr(breakset, strv.data[0]).count == 0) {
strv = strv_pop_front(strv);
}
return strv;
}

static inline string_view strvstrv(string_view strv, string_view substrv) {
if (!strv.data)
return (string_view){NULL, 0};
if (substrv.count == 0)
return (string_view){strv.data, 0};
if (!substrv.data || strv.count < substrv.count)
return (string_view){NULL, 0};
size_t count = strv.count;
strv.count = substrv.count;
for (size_t i = 0; i <= count - substrv.count; i++) {
if (strvcmp(strv, substrv) == 0)
return strv;
strv.data++;
}
return (string_view){NULL, 0};
}

#endif // !STDBIGOS_STRING_VIEW
Loading