diff options
| -rw-r--r-- | README.md | 87 | ||||
| -rw-r--r-- | docs/cvec_api.md | 39 | ||||
| -rw-r--r-- | examples/phonebook.c | 72 | ||||
| -rw-r--r-- | examples/share_ptr.c | 75 | ||||
| -rw-r--r-- | examples/tmap.cpp | 53 |
5 files changed, 92 insertions, 234 deletions
@@ -39,8 +39,9 @@ using_cvec(i, int); int main(void) {
cvec_i vec = cvec_i_init();
- cvec_i_push_back(&vec, 1);
- cvec_i_push_back(&vec, 2);
+ cvec_i_push_back(&vec, 10);
+ cvec_i_push_back(&vec, 20);
+ cvec_i_push_back(&vec, 30);
c_foreach (i, cvec_i, vec)
printf(" %d", *i.ref);
@@ -48,47 +49,65 @@ int main(void) { cvec_i_del(&vec);
}
```
-Container with elements of structs:
+Here is five more...
```c
-#include <stc/cstr.h>
-#include <stc/cvec.h>
-
-typedef struct {
- cstr name; // dynamic string
- int id;
-} User;
-
-int User_compare(const User* a, const User* b) {
- int c = strcmp(a->name.str, b->name.str);
- return c != 0 ? c : a->id - b->id;
-}
-void User_del(User* self) {
- cstr_del(&self->name);
-}
-User User_clone(User user) {
- user.name = cstr_clone(user.name);
- return user;
-}
+#include <stc/cmap.h>
+#include <stc/csmap.h>
+#include <stc/clist.h>
+#include <stc/clist.h>
+#include <stc/cqueue.h>
+#include <stdio.h>
-// declare a memory managed, clonable vector of users:
-using_cvec(u, User, User_compare, User_del, User_clone);
+// declare your container types
+using_cset(i, int); // unordered hash set
+using_clist(i, int); // singly linked list
+using_cdeq(i, int); // deque
+using_cqueue(i, cdeq_i); // deque, using deque as adapter
+using_csmap(i, int, int); // sorted map
int main(void) {
- cvec_u vec = cvec_u_init();
- cvec_u_push_back(&vec, (User) {cstr_from("admin"), 0});
- cvec_u_push_back(&vec, (User) {cstr_from("joe"), 1});
-
- cvec_u vec2 = cvec_u_clone(vec);
- c_foreach (i, cvec_u, vec2)
- printf("%s: %d\n", i.ref->name.str, i.ref->id);
-
- c_del(cvec_u, &vec, &vec2); // cleanup
+ // define and initialize
+ c_init (cset_i, set, {10, 20, 30});
+ c_init (clist_i, list, {10, 20, 30});
+ c_init (cdeq_i, deq, {10, 20, 30});
+ c_init (cqueue_i, que, {10, 20, 30});
+ c_init (csmap_i, map, {{20, 2}, {10, 1}, {30, 3}});
+
+ // add one more element
+ cset_i_insert(&set, 40);
+ clist_i_push_front(&list, 5);
+ cdeq_i_push_front(&deq, 5);
+ cqueue_i_push(&que, 40);
+ csmap_i_emplace(&map, 40, 4);
+
+ // print them
+ c_foreach (i, cset_i, set) printf(" %d", *i.ref); puts("");
+ c_foreach (i, clist_i, list) printf(" %d", *i.ref); puts("");
+ c_foreach (i, cdeq_i, deq) printf(" %d", *i.ref); puts("");
+ c_foreach (i, cqueue_i, que) printf(" %d", *i.ref); puts("");
+ c_foreach (i, csmap_i, map) printf(" (%d: %d)", i.ref->first, i.ref->second);
+
+ // cleanup
+ cset_i_del(&set);
+ clist_i_del(&list);
+ cdeq_i_del(&deq);
+ cqueue_i_del(&que);
+ csmap_i_del(&map);
}
```
+Outputs
+```
+ 10 20 30 40
+ 5 10 20 30
+ 5 10 20 30
+ 10 20 30 40
+ (10: 1) (20: 2) (30: 3) (40: 4)
+```
+
Motivation
----------
-The aim is to make a small **Standard Template Containers library for C**. It should
+The aim was to make a small **Standard Template Containers library for C**. It should
- be easy to use, have intuitive naming and consistency across the library.
- be type safe. Have minimal usage of casting and void* pointers.
- be highly efficient. Both in speed and memory usage.
diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 23083920..a94d10e1 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -173,3 +173,42 @@ item: Mary item: Jake item: 2 elements so far ``` +### Example 3 + +Container with elements of structs: +```c +#include <stc/cstr.h> +#include <stc/cvec.h> + +typedef struct { + cstr name; // dynamic string + int id; +} User; + +int User_compare(const User* a, const User* b) { + int c = strcmp(a->name.str, b->name.str); + return c != 0 ? c : a->id - b->id; +} +void User_del(User* self) { + cstr_del(&self->name); +} +User User_clone(User user) { + user.name = cstr_clone(user.name); + return user; +} + +// declare a memory managed, clonable vector of users: +using_cvec(u, User, User_compare, User_del, User_clone); + +int main(void) { + cvec_u vec = cvec_u_init(); + cvec_u_push_back(&vec, (User) {cstr_from("admin"), 0}); + cvec_u_push_back(&vec, (User) {cstr_from("joe"), 1}); + + cvec_u vec2 = cvec_u_clone(vec); + c_foreach (i, cvec_u, vec2) + printf("%s: %d\n", i.ref->name.str, i.ref->id); + + c_del(cvec_u, &vec, &vec2); // cleanup +} +``` diff --git a/examples/phonebook.c b/examples/phonebook.c deleted file mode 100644 index 91d01072..00000000 --- a/examples/phonebook.c +++ /dev/null @@ -1,72 +0,0 @@ -// The MIT License (MIT)
-// Copyright (c) 2018 Maksim Andrianov
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-
-// Program to emulates the phone book.
-
-#include <stdio.h>
-#include <stc/cmap.h>
-#include <stc/cstr.h>
-
-using_cmap_str();
-
-void print_phone_book(cmap_str phone_book)
-{
- c_foreach (i, cmap_str, phone_book)
- printf("%s\t- %s\n", i.ref->first.str, i.ref->second.str);
-}
-
-int main(int argc, char **argv)
-{
- bool erased;
- cmap_str phone_book = cmap_inits;
- c_push_items(&phone_book, cmap_str, {
- {"Lilia Friedman", "(892) 670-4739"},
- {"Tariq Beltran", "(489) 600-7575"},
- {"Laiba Juarez", "(303) 885-5692"},
- {"Elliott Mooney", "(945) 616-4482"},
- });
-
- printf("Phone book:\n");
- print_phone_book(phone_book);
-
- c_try_emplace(&phone_book, cmap_str, "Zak Byers", cstr_from("(551) 396-1880"));
- c_try_emplace(&phone_book, cmap_str, "Zak Byers", cstr_from("(551) 396-1990"));
-
- printf("\nPhone book after adding Zak Byers:\n");
- print_phone_book(phone_book);
-
- if (cmap_str_find(&phone_book, "Tariq Beltran") != NULL)
- printf("\nTariq Beltran is in phone book\n");
-
- erased = cmap_str_erase(&phone_book, "Tariq Beltran");
- erased = cmap_str_erase(&phone_book, "Elliott Mooney");
-
- printf("\nPhone book after erasing Tariq and Elliott:\n");
- print_phone_book(phone_book);
-
- cmap_str_insert_or_assign(&phone_book, "Zak Byers", "(555) 396-188");
-
- printf("\nPhone book after update phone of Zak Byers:\n");
- print_phone_book(phone_book);
-
- cmap_str_del(&phone_book);
- puts("done");
-}
\ No newline at end of file diff --git a/examples/share_ptr.c b/examples/share_ptr.c deleted file mode 100644 index 9387bd61..00000000 --- a/examples/share_ptr.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <stc/cptr.h>
-#include <stc/clist.h>
-#include <stc/cvec.h>
-#include <stc/cstr.h>
-#include <stdio.h>
-
-typedef struct { cstr_t name, last; } Person;
-
-Person* Person_make(Person* p, const char* name, const char* last) {
- p->name = cstr_from(name), p->last = cstr_from(last);
- return p;
-}
-void Person_del(Person* p) {
- printf("del: %s\n", p->name.str);
- c_del(cstr, &p->name, &p->last);
-}
-int Person_compare(const Person* p, const Person* q) {
- int cmp = strcmp(p->name.str, q->name.str);
- return cmp == 0 ? strcmp(p->last.str, q->last.str) : cmp;
-}
-
-using_csptr(pe, Person, Person_compare, Person_del);
-using_clist(pe, csptr_pe, csptr_pe_compare, csptr_pe_del, csptr_pe_clone);
-using_cvec(pe, csptr_pe, csptr_pe_compare, csptr_pe_del, csptr_pe_clone);
-
-int main() {
- clist_pe queue = clist_pe_init();
- cvec_pe vec = cvec_pe_init();
-
- Person tmp = {cstr_from("Joe"), cstr_from("Jordan")};
- csptr_pe joe = csptr_pe_make(tmp);
- clist_pe_push_back(&queue, csptr_pe_clone(joe));
- cvec_pe_push_back(&vec, csptr_pe_clone(joe));
-
- puts("Push 10:");
- c_forrange (i, 10) {
- csptr_pe p = csptr_pe_from(c_new(Person));
- p.get->name = cstr_from_fmt("Name %d", (i * 7) % 10);
- p.get->last = cstr_from_fmt("Last %d", (i * 7) % 10);
- clist_pe_push_back(&queue, p);
- cvec_pe_push_back(&vec, csptr_pe_clone(p)); // Don't forget to share!
- }
- c_foreach (i, clist_pe, queue)
- printf(" %s\n", i.ref->get->name.str);
-
- puts("Sort and pop 3:");
- clist_pe_sort(&queue);
- cvec_pe_sort(&vec);
- c_forrange (3) {
- clist_pe_pop_front(&queue);
- cvec_pe_pop_back(&vec);
- }
-
- puts("Sorted queue:");
- c_foreach (i, clist_pe, queue)
- printf(" %s\n", i.ref->get->name.str);
- puts("Sorted vec:");
- c_foreach (i, cvec_pe, vec)
- printf(" %s\n", i.ref->get->name.str);
-
- Person lost; Person_make(&lost, "Name 5", "Last 5");
- csptr_pe ptmp = {&lost, NULL}; // share pointer without counter - OK.
- clist_pe_iter_t lit = clist_pe_find(&queue, ptmp);
- Person_del(&lost);
- if (lit.ref) printf("Found: %s\n", lit.ref->get->name.str);
-
- printf("use %ld\n", *joe.use_count);
- csptr_pe_del(&joe);
-
- puts("Destroy queue:");
- clist_pe_del(&queue);
-
- puts("Destroy vec:");
- cvec_pe_del(&vec);
-}
\ No newline at end of file diff --git a/examples/tmap.cpp b/examples/tmap.cpp deleted file mode 100644 index 793ce6cc..00000000 --- a/examples/tmap.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include <stc/csmap.h>
-#include <stc/cstr.h>
-#include <stc/crand.h>
-#include <stdio.h>
-#include <map>
-
-using_csmap(i, int, size_t);
-//using_csset_str();
-
-#include <time.h>
-
-int main(int argc, char **argv)
-{
- std::map<int, size_t> tmap;
- csmap_i map = csmap_i_init();
- csmap_i_iter_t it;
- time_t seed = time(NULL);
-
- size_t n = 2000000;
- uint64_t mask = (1ull << 22) - 1;
-
- clock_t t1 = clock();
- stc64_srandom(seed);
- for (size_t i = 0; i < n; ++i) {
- uint64_t x = stc64_random() & mask;
- tmap.emplace(x, i);
- }
- size_t s1 = tmap.size();
- stc64_srandom(seed);
- for (size_t i = 0; i < n - 50; ++i) {
- uint64_t x = stc64_random() & mask;
- tmap.erase(x);
- }
- clock_t t2 = clock();
-
- stc64_srandom(seed);
- for (size_t i = 0; i < n; ++i) {
- uint64_t x = stc64_random() & mask;
- csmap_i_emplace(&map, x, i);
- }
- size_t s2 = csmap_i_size(map);
- stc64_srandom(seed);
- for (size_t i = 0; i < n - 50; ++i) {
- uint64_t x = stc64_random() & mask;
- csmap_i_erase(&map, x);
- }
- clock_t t3 = clock();
-
- printf("%zu %zu\n", s1, s2);
- printf("%zu %zu\n", tmap.size(), csmap_i_size(map));
-
- printf("time: %f %f\n", ((float)t2-t1) / CLOCKS_PER_SEC, ((float)t3-t2) / CLOCKS_PER_SEC);
-}
|
