summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/csview_api.md17
-rw-r--r--examples/books.c60
-rw-r--r--examples/box.c61
-rw-r--r--examples/box2.c86
-rw-r--r--examples/hashmap.c48
-rw-r--r--examples/rawptr_elements.c (renamed from examples/ptr_elems.c)0
-rw-r--r--examples/sptr_demo.c (renamed from examples/sharedptr.c)0
-rw-r--r--examples/sptr_music.c (renamed from examples/sptr_ex.c)0
-rw-r--r--examples/sview_split.c17
-rw-r--r--include/stc/alt/cstr.h113
-rw-r--r--include/stc/cstr.h18
11 files changed, 344 insertions, 76 deletions
diff --git a/docs/csview_api.md b/docs/csview_api.md
index 2653dafa..7daa67ee 100644
--- a/docs/csview_api.md
+++ b/docs/csview_api.md
@@ -25,11 +25,11 @@ All csview definitions and prototypes are available by including a single header
## Methods
```c
+csview c_sv(const char literal_only[]); // alias for csview_new
csview csview_new(const char literal_only[]); // make csview from literal, no strlen()
csview csview_from_s(cstr s); // same as cstr_sv()
csview csview_from(const char* str); // make csview from const char*
csview csview_from_n(const char* str, size_t n); // construct
-csview c_sv(const char literal_only[]); // same as csview_new()
size_t csview_size(csview sv);
size_t csview_length(csview sv);
@@ -57,10 +57,10 @@ void csview_next(csview_iter* it);
#### Extended cstr methods
```c
cstr cstr_from_v(csview sv); // construct cstr from csview
+csview cstr_to_v(const cstr* self); // convert to csview from cstr*
cstr cstr_from_replace_all_v(csview sv, csview find, csview replace);
csview cstr_sv(cstr s); // convert to csview from cstr
-csview cstr_to_v(const cstr* self); // convert to csview from cstr*
csview cstr_substr(cstr s, intptr_t pos, size_t n); // negative pos counts from end
csview cstr_slice(cstr s, intptr_t p1, intptr_t p2); // negative p1, p2 counts from end
@@ -91,11 +91,12 @@ uint64_t csview_hash(const csview* x, size_t dummy);
## Constants and macros
-| Name | Value | Usage |
-|:-----------------|:--------------------|:----------------------------------|
-| `csview_null` | same as `c_sv("")` | `sview = csview_null;` |
-| `csview_npos` | same as `cstr_npos` | |
-| `csview_ARG(sv)` | printf argument | `printf("%.*s", csview_ARG(sv));` |
+| Name | Value | Usage |
+|:---------------|:---------------------|:----------------------------------------------|
+| `csview_null` | same as `c_sv("")` | `sview = csview_null;` |
+| `csview_npos` | same as `cstr_npos` | |
+| `c_svarg(sv)` | printf format csview | |
+| `c_svfmt` | printf argument | `printf("view: " c_svfmt "\n", c_svarg(sv));` |
## Example
```c
@@ -110,7 +111,7 @@ int main ()
size_t pos = cstr_find(str1, "live"); // position of "live" in str1
csview sv2 = cstr_substr(str1, pos, 4); // get "live"
csview sv3 = cstr_slice(str1, -8, -1); // get "details"
- printf("%.*s %.*s %.*s\n", csview_ARG(sv1), csview_ARG(sv2), csview_ARG(sv3));
+ printf(c_svfmt c_svfmt c_svfmt "\n", c_svarg(sv1), c_svarg(sv2), c_svarg(sv3));
cstr s1 = cstr_new("Apples are red");
cstr s2 = cstr_from_v(cstr_substr(s1, -3, 3)); // "red"
diff --git a/examples/books.c b/examples/books.c
new file mode 100644
index 00000000..f9340679
--- /dev/null
+++ b/examples/books.c
@@ -0,0 +1,60 @@
+// https://doc.rust-lang.org/std/collections/struct.HashMap.html
+
+#define i_key_str
+#define i_val_str
+#include <stc/cmap.h>
+
+// Type inference lets us omit an explicit type signature (which
+// would be `HashMap<String, String>` in this example).
+int main()
+{
+ c_auto (cmap_str, book_reviews)
+ {
+ // Review some books.
+ cmap_str_emplace(&book_reviews,
+ "Adventures of Huckleberry Finn",
+ "My favorite book."
+ );
+ cmap_str_emplace(&book_reviews,
+ "Grimms' Fairy Tales",
+ "Masterpiece."
+ );
+ cmap_str_emplace(&book_reviews,
+ "Pride and Prejudice",
+ "Very enjoyable"
+ );
+ cmap_str_insert(&book_reviews,
+ cstr_new("The Adventures of Sherlock Holmes"),
+ cstr_new("Eye lyked it alot.")
+ );
+
+ // Check for a specific one.
+ // When collections store owned values (String), they can still be
+ // queried using references (&str).
+ if (cmap_str_contains(&book_reviews, "Les Misérables")) {
+ printf("We've got %zu reviews, but Les Misérables ain't one.",
+ cmap_str_size(book_reviews));
+ }
+
+ // oops, this review has a lot of spelling mistakes, let's delete it.
+ cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes");
+
+ // Look up the values associated with some keys.
+ const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland"};
+ c_forrange (i, c_arraylen(to_find)) {
+ const cmap_str_value* b;
+ if ((b = cmap_str_get(&book_reviews, to_find[i])))
+ printf("%s: %s\n", b->first.str, b->second.str);
+ else
+ printf("%s is unreviewed.\n", to_find[i]);
+ }
+
+ // Look up the value for a key (will panic if the key is not found).
+ printf("Review for Jane: %s\n", cmap_str_at(&book_reviews, "Pride and Prejudice")->str);
+
+ // Iterate over everything.
+ c_forpair (book, review, cmap_str, book_reviews) {
+ printf("%s: \"%s\"\n", _.book.str, _.review.str);
+ }
+ }
+} \ No newline at end of file
diff --git a/examples/box.c b/examples/box.c
new file mode 100644
index 00000000..c7763bb8
--- /dev/null
+++ b/examples/box.c
@@ -0,0 +1,61 @@
+/* cbox: heap allocated boxed type */
+#include <stc/cstr.h>
+
+typedef struct { cstr name, last; } Person;
+
+Person Person_from(const char* name, const char* last) {
+ return (Person){.name = cstr_from(name), .last = cstr_from(last)};
+}
+
+int Person_cmp(const Person* a, const Person* b) {
+ int c = strcmp(a->name.str, b->name.str);
+ return c ? c : strcmp(a->last.str, b->last.str);
+}
+
+Person Person_clone(Person p) {
+ p.name = cstr_clone(p.name);
+ p.last = cstr_clone(p.last);
+ return p;
+}
+void Person_del(Person* p) {
+ printf("del: %s %s\n", p->name.str, p->last.str);
+ c_del(cstr, &p->name, &p->last);
+}
+
+#define i_val Person
+#define i_cmp Person_cmp
+#define i_from Person_clone
+#define i_del Person_del
+#define i_tag prs
+#include <stc/cbox.h>
+
+#define i_val_ref cbox_prs
+#define i_tag prs
+#include <stc/cvec.h>
+
+
+int main()
+{
+ c_auto (cvec_prs, vec)
+ c_auto (cbox_prs, p, q)
+ {
+ p = cbox_prs_new(Person_from("Dave", "Cooper"));
+
+ q = cbox_prs_clone(p);
+ cstr_assign(&q.get->name, "Dale");
+
+ printf("%s %s.\n", p.get->name.str, p.get->last.str);
+ printf("%s %s.\n", q.get->name.str, q.get->last.str);
+
+ cvec_prs_push_back(&vec, cbox_prs_new(Person_from("Laura", "Palmer")));
+ cvec_prs_push_back(&vec, cbox_prs_new(Person_from("Shelly", "Johnson")));
+
+ c_foreach (i, cvec_prs, vec)
+ printf("%s: %s\n", i.ref->get->name.str, i.ref->get->last.str);
+
+ c_autovar (Person per = Person_from("Laura", "Palmer"), Person_del(&per)) {
+ const cbox_prs *v = cvec_prs_get(&vec, (cbox_prs){&per});
+ if (v) printf("found: %s: %s\n", v->get->name.str, v->get->last.str);
+ }
+ }
+}
diff --git a/examples/box2.c b/examples/box2.c
new file mode 100644
index 00000000..79304609
--- /dev/null
+++ b/examples/box2.c
@@ -0,0 +1,86 @@
+// https://doc.rust-lang.org/rust-by-example/std/box.html
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stc/ccommon.h>
+
+struct {
+ double x;
+ double y;
+} typedef Point;
+
+// A Rectangle can be specified by where its top left and bottom right
+// corners are in space
+struct {
+ Point top_left;
+ Point bottom_right;
+} typedef Rectangle;
+
+#define i_val Point
+#define i_opt c_no_compare
+#include <stc/cbox.h>
+
+#define i_val cbox_Point
+#define i_opt c_no_compare
+#define i_tag BoxPoint
+#include <stc/cbox.h>
+
+#define i_val Rectangle
+#define i_opt c_no_compare
+#include <stc/cbox.h>
+
+Point origin(void) {
+ return (Point){ .x=0.0, .y=0.0 };
+}
+
+cbox_Point boxed_origin(void) {
+ // Allocate this point on the heap, and return a pointer to it
+ return cbox_Point_new((Point){ .x=0.0, .y=0.0 });
+}
+
+
+int main(void) {
+ // (all the type annotations are superfluous)
+ // Stack allocated variables
+ Point point = origin();
+ Rectangle rectangle = (Rectangle){
+ .top_left = origin(),
+ .bottom_right = (Point){ .x=3.0, .y=-4.0 }
+ };
+
+ // Heap allocated rectangle
+ c_auto (cbox_Rectangle, boxed_rectangle)
+ c_auto (cbox_Point, boxed_point)
+ c_auto (cbox_BoxPoint, box_in_a_box)
+ {
+ boxed_rectangle = cbox_Rectangle_new((Rectangle){
+ .top_left = origin(),
+ .bottom_right = (Point){ .x=3.0, .y=-4.0 }
+ });
+
+ // The output of functions can be boxed
+ boxed_point = cbox_Point_new(origin());
+
+ // Double indirection
+ box_in_a_box = cbox_BoxPoint_new(boxed_origin());
+
+ printf("Point occupies %zu bytes on the stack\n",
+ sizeof(point));
+ printf("Rectangle occupies %zu bytes on the stack\n",
+ sizeof(rectangle));
+
+ // box size == pointer size
+ printf("Boxed point occupies %zu bytes on the stack\n",
+ sizeof(boxed_point));
+ printf("Boxed rectangle occupies %zu bytes on the stack\n",
+ sizeof(boxed_rectangle));
+ printf("Boxed box occupies %zu bytes on the stack\n",
+ sizeof(box_in_a_box));
+
+ // Copy the data contained in `boxed_point` into `unboxed_point`
+ Point unboxed_point = *boxed_point.get;
+ printf("Unboxed point occupies %zu bytes on the stack\n",
+ sizeof(unboxed_point));
+ }
+} \ No newline at end of file
diff --git a/examples/hashmap.c b/examples/hashmap.c
new file mode 100644
index 00000000..c3e9afce
--- /dev/null
+++ b/examples/hashmap.c
@@ -0,0 +1,48 @@
+// https://doc.rust-lang.org/rust-by-example/std/hash.html
+
+#define i_key_str
+#define i_val_str
+#include <stdio.h>
+#include <stc/cmap.h>
+
+const char* call(const char* number) {
+ if (!strcmp(number, "798-1364"))
+ return "We're sorry, the call cannot be completed as dialed."
+ " Please hang up and try again.";
+ else if (!strcmp(number, "645-7689"))
+ return "Hello, this is Mr. Awesome's Pizza. My name is Fred."
+ " What can I get for you today?";
+ else
+ return "Hi! Who is this again?";
+}
+
+int main(void) {
+ c_auto (cmap_str, contacts)
+ {
+ cmap_str_emplace(&contacts, "Daniel", "798-1364");
+ cmap_str_emplace(&contacts, "Ashley", "645-7689");
+ cmap_str_emplace(&contacts, "Katie", "435-8291");
+ cmap_str_emplace(&contacts, "Robert", "956-1745");
+
+ const cmap_str_value* v;
+ if ((v = cmap_str_get(&contacts, "Daniel")))
+ printf("Calling Daniel: %s\n", call(v->second.str));
+ else
+ printf("Don't have Daniel's number.");
+
+ cmap_str_emplace(&contacts, "Daniel", "164-6743");
+
+ if ((v = cmap_str_get(&contacts, "Ashley")))
+ printf("Calling Ashley: %s\n", call(v->second.str));
+ else
+ printf("Don't have Ashley's number.");
+
+ cmap_str_erase(&contacts, "Ashley");
+
+ puts("");
+ c_forpair (contact, number, cmap_str, contacts) {
+ printf("Calling %s: %s\n", _.contact.str, call(_.number.str));
+ }
+ puts("");
+ }
+}
diff --git a/examples/ptr_elems.c b/examples/rawptr_elements.c
index c5416822..c5416822 100644
--- a/examples/ptr_elems.c
+++ b/examples/rawptr_elements.c
diff --git a/examples/sharedptr.c b/examples/sptr_demo.c
index c3da5287..c3da5287 100644
--- a/examples/sharedptr.c
+++ b/examples/sptr_demo.c
diff --git a/examples/sptr_ex.c b/examples/sptr_music.c
index e8e08b5f..e8e08b5f 100644
--- a/examples/sptr_ex.c
+++ b/examples/sptr_music.c
diff --git a/examples/sview_split.c b/examples/sview_split.c
new file mode 100644
index 00000000..3a079583
--- /dev/null
+++ b/examples/sview_split.c
@@ -0,0 +1,17 @@
+#include <stc/csview.h>
+#define c_arg(a) a
+int main()
+{
+ // No memory allocations or string length calculations!
+ const csview date = c_sv("2021/03/12");
+ const csview year = csview_first_token(date, c_sv("/"));
+ const csview month = csview_next_token(date, c_sv("/"), year);
+ const csview day = csview_next_token(date, c_sv("/"), month);
+
+ printf(c_svfmt ", " c_svfmt ", " c_svfmt "\n", c_svarg(year), c_svarg(month), c_svarg(day));
+
+ c_auto (cstr, y, m, d) {
+ y = cstr_from_v(year), m = cstr_from_v(month), d = cstr_from_v(day);
+ printf("%s, %s, %s\n", y.str, m.str, d.str);
+ }
+} \ No newline at end of file
diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h
index 1dc895ff..76b3a800 100644
--- a/include/stc/alt/cstr.h
+++ b/include/stc/alt/cstr.h
@@ -32,31 +32,27 @@
#include <string.h>
#include <stdio.h>
-#ifndef cstr_size_t
-typedef size_t cstr_size_t;
-#endif
-typedef struct { char* data; cstr_size_t size, cap; } cstr_rep_t;
-typedef const char cstr_literal_t[];
+typedef struct { char* data; size_t size, cap; } _cstr_rep_t;
typedef union {
- struct { char* data; cstr_size_t size, ncap; } lon;
- struct { char data[sizeof(cstr_rep_t)]; } sso;
+ struct { char data[sizeof(_cstr_rep_t) - 1], cap_len; } sso;
+ struct { char* data; size_t size, ncap; } lon;
} cstr;
/**************************** PRIVATE API **********************************/
enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 };
-#define cstr_is_long(s) (bool)((s)->sso.data[SSO_CAP] & 128)
+#define cstr_is_long(s) (bool)((s)->sso.cap_len & 128)
#define cstr_select_(s, memb) (cstr_is_long(s) ? cstr_l_##memb : cstr_s_##memb)
#define cstr_s_cap(s) SSO_CAP
-#define cstr_s_size(s) ((cstr_size_t)(SSO_CAP - (s)->sso.data[SSO_CAP]))
-#define cstr_s_set_size(s, len) ((s)->sso.data[SSO_CAP] = SSO_CAP - (len), (s)->sso.data[len] = 0)
+#define cstr_s_size(s) ((size_t)(SSO_CAP - (s)->sso.cap_len))
+#define cstr_s_set_size(s, len) ((s)->sso.cap_len = SSO_CAP - (len), (s)->sso.data[len] = 0)
#define cstr_s_data(s) (s)->sso.data
#define cstr_s_end(s) ((s)->sso.data + cstr_s_size(s))
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8)
+#define byte_rotl_(x, b) ((x) << (b)*8 | (x) >> (sizeof(x) - (b))*8)
#define cstr_l_cap(s) (~byte_rotl_((s)->lon.ncap, sizeof((s)->lon.ncap) - 1))
#define cstr_l_set_cap(s, cap) ((s)->lon.ncap = ~byte_rotl_(cap, 1))
#else
@@ -69,42 +65,41 @@ enum { SSO_CAP = offsetof(cstr, lon.ncap) + sizeof((cstr){{0}}.lon.ncap) - 1 };
#define cstr_l_end(s) ((s)->lon.data + cstr_l_size(s))
#define cstr_l_del(s) free((s)->lon.data)
-STC_API char* cstr_init_(cstr* self, cstr_size_t len, cstr_size_t cap);
+STC_API char* cstr_init_(cstr* self, size_t len, size_t cap);
STC_API void cstr_internal_move_(cstr* self, size_t pos1, size_t pos2);
-STC_INLINE void cstr_set_size_(cstr* self, cstr_size_t len) {
+STC_INLINE void cstr_set_size_(cstr* self, size_t len) {
cstr_select_(self, set_size(self, len));
}
-STC_INLINE cstr_rep_t cstr_rep_(cstr* self) {
+STC_INLINE _cstr_rep_t cstr_rep_(cstr* self) {
return cstr_is_long(self)
- ? c_make(cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)}
- : c_make(cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)};
+ ? c_make(_cstr_rep_t){self->lon.data, cstr_l_size(self), cstr_l_cap(self)}
+ : c_make(_cstr_rep_t){self->sso.data, cstr_s_size(self), cstr_s_cap(self)};
}
/**************************** PUBLIC API **********************************/
-#define cstr_new(lit) cstr_from_n(lit, sizeof((cstr_literal_t){lit}) - 1)
-#define cstr_npos (~(cstr_size_t)0 >> 1)
+#define cstr_new(literal) cstr_from_n(literal, sizeof((c_strlit){literal}) - 1)
+#define cstr_npos (SIZE_MAX >> 1)
+#define cstr_null (cstr){.sso = {.cap_len = SSO_CAP}}
-STC_API char* cstr_reserve(cstr* self, cstr_size_t cap);
+STC_API char* cstr_reserve(cstr* self, size_t cap);
STC_API void cstr_shrink_to_fit(cstr* self);
-STC_API void cstr_resize(cstr* self, cstr_size_t size, char value);
+STC_API void cstr_resize(cstr* self, size_t size, char value);
STC_API char* strnstrn(const char *s, const char *needle, size_t slen, size_t nlen);
-STC_API cstr_size_t cstr_find_n(cstr s, const char* needle, cstr_size_t pos, cstr_size_t nmax);
-STC_API void cstr_assign_n(cstr* self, const char* str, cstr_size_t n);
-STC_API void cstr_append_n(cstr* self, const char* str, cstr_size_t n);
+STC_API size_t cstr_find_n(cstr s, const char* needle, size_t pos, size_t nmax);
+STC_API void cstr_assign_n(cstr* self, const char* str, size_t n);
+STC_API void cstr_append_n(cstr* self, const char* str, size_t n);
STC_API bool cstr_getdelim(cstr *self, int delim, FILE *fp);
STC_API void cstr_erase_n(cstr* self, size_t pos, size_t n);
STC_INLINE cstr cstr_init(void) {
- cstr s;
- cstr_s_set_size(&s, 0);
- return s;
+ return cstr_null;
}
-STC_INLINE cstr cstr_from_n(const char* str, cstr_size_t n) {
+STC_INLINE cstr cstr_from_n(const char* str, size_t n) {
cstr s;
memcpy(cstr_init_(&s, n, n), str, n);
return s;
@@ -114,20 +109,20 @@ STC_INLINE cstr cstr_from(const char* str) {
return cstr_from_n(str, strlen(str));
}
-STC_INLINE cstr cstr_with_size(cstr_size_t size, char value) {
+STC_INLINE cstr cstr_with_size(size_t size, char value) {
cstr s;
memset(cstr_init_(&s, size, size), value, size);
return s;
}
-STC_INLINE cstr cstr_with_capacity(cstr_size_t cap) {
+STC_INLINE cstr cstr_with_capacity(size_t cap) {
cstr s;
cstr_init_(&s, 0, cap);
return s;
}
STC_INLINE cstr cstr_clone(cstr s) {
- cstr_rep_t rep = cstr_rep_(&s);
+ _cstr_rep_t rep = cstr_rep_(&s);
return cstr_from_n(rep.data, rep.size);
}
@@ -151,15 +146,15 @@ STC_INLINE bool cstr_empty(cstr s) {
return cstr_select_(&s, size(&s)) == 0;
}
-STC_INLINE cstr_size_t cstr_size(cstr s) {
+STC_INLINE size_t cstr_size(cstr s) {
return cstr_select_(&s, size(&s));
}
-STC_INLINE cstr_size_t cstr_length(cstr s) {
+STC_INLINE size_t cstr_length(cstr s) {
return cstr_select_(&s, size(&s));
}
-STC_INLINE cstr_size_t cstr_capacity(cstr s) {
+STC_INLINE size_t cstr_capacity(cstr s) {
return cstr_select_(&s, cap(&s));
}
@@ -179,7 +174,7 @@ STC_INLINE int cstr_compare(const cstr* s1, const cstr* s2) {
return strcmp(cstr_str(s1), cstr_str(s2));
}
-STC_INLINE cstr_size_t cstr_find(cstr s, const char* needle) {
+STC_INLINE size_t cstr_find(cstr s, const char* needle) {
const char *str = cstr_str(&s), *res = strstr(str, needle);
return res ? res - str : cstr_npos;
}
@@ -207,7 +202,7 @@ STC_INLINE bool cstr_starts_with_s(cstr s, cstr sub) {
}
STC_INLINE bool cstr_ends_with(cstr s, const char* sub) {
- cstr_rep_t rep = cstr_rep_(&s); cstr_size_t n = strlen(sub);
+ _cstr_rep_t rep = cstr_rep_(&s); size_t n = strlen(sub);
return n <= rep.size && memcmp(rep.data + rep.size - n, sub, n) == 0;
}
@@ -220,7 +215,7 @@ STC_INLINE void cstr_assign(cstr* self, const char* str) {
}
STC_INLINE void cstr_copy(cstr* self, cstr s) {
- cstr_rep_t rep = cstr_rep_(&s);
+ _cstr_rep_t rep = cstr_rep_(&s);
cstr_assign_n(self, rep.data, rep.size);
}
@@ -229,7 +224,7 @@ STC_INLINE void cstr_append(cstr* self, const char* str) {
}
STC_INLINE void cstr_append_s(cstr* self, cstr s) {
- cstr_rep_t rep = cstr_rep_(&s);
+ _cstr_rep_t rep = cstr_rep_(&s);
cstr_append_n(self, rep.data, rep.size);
}
@@ -243,7 +238,7 @@ STC_INLINE void cstr_replace(cstr* self, size_t pos, size_t len, const char* str
}
STC_INLINE void cstr_replace_s(cstr* self, size_t pos, size_t len, cstr s) {
- cstr_rep_t rep = cstr_rep_(&s);
+ _cstr_rep_t rep = cstr_rep_(&s);
cstr_replace_n(self, pos, len, rep.data, rep.size);
}
@@ -256,7 +251,7 @@ STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str) {
}
STC_INLINE void cstr_insert_s(cstr* self, size_t pos, cstr s) {
- cstr_rep_t rep = cstr_rep_(&s);
+ _cstr_rep_t rep = cstr_rep_(&s);
cstr_replace_n(self, pos, 0, rep.data, rep.size);
}
@@ -271,15 +266,15 @@ STC_INLINE bool cstr_getline(cstr *self, FILE *fp) {
STC_DEF void cstr_internal_move_(cstr* self, size_t pos1, size_t pos2) {
if (pos1 == pos2)
return;
- cstr_rep_t rep = cstr_rep_(self);
- cstr_size_t newlen = rep.size + pos2 - pos1;
+ _cstr_rep_t rep = cstr_rep_(self);
+ size_t newlen = rep.size + pos2 - pos1;
if (newlen > rep.cap)
rep.data = cstr_reserve(self, (rep.size*3 >> 1) + pos2 - pos1);
memmove(&rep.data[pos2], &rep.data[pos1], rep.size - pos1);
cstr_set_size_(self, newlen);
}
-STC_DEF char* cstr_init_(cstr* self, cstr_size_t len, cstr_size_t cap) {
+STC_DEF char* cstr_init_(cstr* self, size_t len, size_t cap) {
if (cap > SSO_CAP) {
self->lon.data = (char *)malloc(cap + 1);
cstr_l_set_size(self, len);
@@ -291,7 +286,7 @@ STC_DEF char* cstr_init_(cstr* self, cstr_size_t len, cstr_size_t cap) {
}
STC_DEF void cstr_shrink_to_fit(cstr* self) {
- cstr_rep_t rep = cstr_rep_(self);
+ _cstr_rep_t rep = cstr_rep_(self);
if (rep.size == rep.cap)
return;
if (rep.size > SSO_CAP) {
@@ -304,7 +299,7 @@ STC_DEF void cstr_shrink_to_fit(cstr* self) {
}
}
-STC_DEF char* cstr_reserve(cstr* self, cstr_size_t cap) {
+STC_DEF char* cstr_reserve(cstr* self, size_t cap) {
if (cstr_is_long(self)) {
if (cap > cstr_l_cap(self)) {
self->lon.data = (char *)realloc(self->lon.data, cap + 1);
@@ -315,7 +310,7 @@ STC_DEF char* cstr_reserve(cstr* self, cstr_size_t cap) {
/* from short to long: */
if (cap > cstr_s_cap(self)) {
char* data = (char *)malloc(cap + 1);
- cstr_size_t len = cstr_s_size(self);
+ size_t len = cstr_s_size(self);
memcpy(data, self->sso.data, len);
self->lon.data = data;
cstr_l_set_size(self, len);
@@ -325,8 +320,8 @@ STC_DEF char* cstr_reserve(cstr* self, cstr_size_t cap) {
return self->sso.data;
}
-STC_DEF void cstr_resize(cstr* self, cstr_size_t size, char value) {
- cstr_rep_t rep = cstr_rep_(self);
+STC_DEF void cstr_resize(cstr* self, size_t size, char value) {
+ _cstr_rep_t rep = cstr_rep_(self);
if (size > rep.size) {
if (size > rep.cap) rep.data = cstr_reserve(self, size);
memset(rep.data + rep.size, value, size - rep.size);
@@ -345,17 +340,17 @@ STC_DEF char* strnstrn(const char *s, const char *needle, size_t slen, size_t nl
return NULL;
}
-STC_DEF cstr_size_t
-cstr_find_n(cstr s, const char* needle, cstr_size_t pos, cstr_size_t nmax) {
- cstr_rep_t rep = cstr_rep_(&s);
- cstr_size_t nlen = (cstr_size_t) strlen(needle);
+STC_DEF size_t
+cstr_find_n(cstr s, const char* needle, size_t pos, size_t nmax) {
+ _cstr_rep_t rep = cstr_rep_(&s);
+ size_t nlen = (size_t) strlen(needle);
if (pos > rep.size) return cstr_npos;
char* res = strnstrn(rep.data + pos, needle, rep.size, nmax < nlen ? nmax : nlen);
return res ? res - rep.data : cstr_npos;
}
-STC_DEF void cstr_assign_n(cstr* self, const char* str, cstr_size_t n) {
- cstr_rep_t rep = cstr_rep_(self);
+STC_DEF void cstr_assign_n(cstr* self, const char* str, size_t n) {
+ _cstr_rep_t rep = cstr_rep_(self);
if (n > rep.cap) {
rep.data = (char *)realloc(cstr_is_long(self) ? rep.data : NULL, n + 1);
cstr_l_set_cap(self, n);
@@ -364,10 +359,10 @@ STC_DEF void cstr_assign_n(cstr* self, const char* str, cstr_size_t n) {
cstr_set_size_(self, n);
}
-STC_DEF void cstr_append_n(cstr* self, const char* str, cstr_size_t n) {
- cstr_rep_t rep = cstr_rep_(self);
+STC_DEF void cstr_append_n(cstr* self, const char* str, size_t n) {
+ _cstr_rep_t rep = cstr_rep_(self);
if (rep.size + n > rep.cap) {
- cstr_size_t off = (cstr_size_t)(str - rep.data); /* handle self append */
+ size_t off = (size_t)(str - rep.data); /* handle self append */
rep.data = cstr_reserve(self, (rep.size*3 >> 1) + n);
if (off <= rep.size) str = rep.data + off;
}
@@ -379,8 +374,8 @@ STC_DEF bool cstr_getdelim(cstr *self, int delim, FILE *fp) {
int c = fgetc(fp);
if (c == EOF)
return false;
- cstr_size_t pos = 0;
- cstr_rep_t rep = cstr_rep_(self);
+ size_t pos = 0;
+ _cstr_rep_t rep = cstr_rep_(self);
for (;;) {
if (c == delim || c == EOF) {
cstr_set_size_(self, pos);
@@ -396,7 +391,7 @@ STC_DEF bool cstr_getdelim(cstr *self, int delim, FILE *fp) {
}
STC_DEF void cstr_erase_n(cstr* self, size_t pos, size_t n) {
- cstr_rep_t rep = cstr_rep_(self);
+ _cstr_rep_t rep = cstr_rep_(self);
if (n > rep.size - pos) n = rep.size - pos;
memmove(&rep.data[pos], &rep.data[pos + n], rep.size - (pos + n));
cstr_set_size_(self, rep.size - n);
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index 3d8d3097..a46de3c3 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -37,14 +37,14 @@ typedef char cstr_value;
#define cstr_npos (SIZE_MAX >> 1)
STC_LIBRARY_ONLY( extern const cstr cstr_null; )
-struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; };
-#define _cstr_rep(self) c_container_of((self)->str, struct cstr_rep, str)
-STC_STATIC_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}};
+typedef struct { size_t size, cap; char str[sizeof(size_t)]; } _cstr_rep_t;
+#define _cstr_rep(self) c_container_of((self)->str, _cstr_rep_t, str)
+STC_STATIC_ONLY( static _cstr_rep_t _cstr_nullrep = {0, 0, {0}};
static const cstr cstr_null = {_cstr_nullrep.str}; )
/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */
-#define _cstr_opt_mem(cap) ((((offsetof(struct cstr_rep, str) + (cap) + 8)>>4)<<4) + 8)
+#define _cstr_opt_mem(cap) ((((offsetof(_cstr_rep_t, str) + (cap) + 8)>>4)<<4) + 8)
/* optimal string capacity: 7, 23, 39, ... */
-#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(struct cstr_rep, str) - 1)
+#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(_cstr_rep_t, str) - 1)
STC_API cstr cstr_from_n(const char* str, size_t n);
STC_API cstr cstr_from_fmt(const char* fmt, ...);
@@ -174,15 +174,15 @@ cstr_ends_with(cstr s, const char* sub) {
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-STC_LIBRARY_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}};
+STC_LIBRARY_ONLY( static _cstr_rep_t _cstr_nullrep = {0, 0, {0}};
const cstr cstr_null = {_cstr_nullrep.str}; )
STC_DEF size_t
cstr_reserve(cstr* self, const size_t cap) {
- struct cstr_rep* rep = _cstr_rep(self);
+ _cstr_rep_t* rep = _cstr_rep(self);
const size_t oldcap = rep->cap;
if (cap > oldcap) {
- rep = (struct cstr_rep*) c_realloc(oldcap ? rep : NULL, _cstr_opt_mem(cap));
+ rep = (_cstr_rep_t*) c_realloc(oldcap ? rep : NULL, _cstr_opt_mem(cap));
self->str = rep->str;
if (oldcap == 0) self->str[rep->size = 0] = '\0';
return (rep->cap = _cstr_opt_cap(cap));
@@ -201,7 +201,7 @@ cstr_resize(cstr* self, const size_t len, const char fill) {
STC_DEF cstr
cstr_from_n(const char* str, const size_t n) {
if (n == 0) return cstr_null;
- struct cstr_rep* rep = (struct cstr_rep*) c_malloc(_cstr_opt_mem(n));
+ _cstr_rep_t* rep = (_cstr_rep_t*) c_malloc(_cstr_opt_mem(n));
cstr s = {(char *) memcpy(rep->str, str, n)};
s.str[rep->size = n] = '\0';
rep->cap = _cstr_opt_cap(n);