summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/sortedmaps
diff options
context:
space:
mode:
Diffstat (limited to 'misc/examples/sortedmaps')
-rw-r--r--misc/examples/sortedmaps/csmap_erase.c82
-rw-r--r--misc/examples/sortedmaps/csmap_find.c73
-rw-r--r--misc/examples/sortedmaps/csmap_insert.c107
-rw-r--r--misc/examples/sortedmaps/csset_erase.c41
-rw-r--r--misc/examples/sortedmaps/gauss2.c45
-rw-r--r--misc/examples/sortedmaps/listmap.c65
-rw-r--r--misc/examples/sortedmaps/mapmap.c64
-rw-r--r--misc/examples/sortedmaps/multimap.c103
-rw-r--r--misc/examples/sortedmaps/new_smap.c67
-rw-r--r--misc/examples/sortedmaps/sorted_map.c67
10 files changed, 714 insertions, 0 deletions
diff --git a/misc/examples/sortedmaps/csmap_erase.c b/misc/examples/sortedmaps/csmap_erase.c
new file mode 100644
index 00000000..8d4eeae3
--- /dev/null
+++ b/misc/examples/sortedmaps/csmap_erase.c
@@ -0,0 +1,82 @@
+// map_erase.c
+// From C++ example: https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-16
+#define i_implement
+#include <stc/cstr.h>
+#include <stdio.h>
+
+#define i_key int
+#define i_val_str
+#define i_type mymap
+#include <stc/csmap.h>
+
+void printmap(mymap m)
+{
+ c_foreach (elem, mymap, m)
+ printf(" [%d, %s]", elem.ref->first, cstr_str(&elem.ref->second));
+ printf("\nsize() == %" c_ZI "\n\n", mymap_size(&m));
+}
+
+int main(void)
+{
+ mymap m1 = {0};
+
+ // Fill in some data to test with, one at a time
+ mymap_insert(&m1, 1, cstr_lit("A"));
+ mymap_insert(&m1, 2, cstr_lit("B"));
+ mymap_insert(&m1, 3, cstr_lit("C"));
+ mymap_insert(&m1, 4, cstr_lit("D"));
+ mymap_insert(&m1, 5, cstr_lit("E"));
+
+ puts("Starting data of map m1 is:");
+ printmap(m1);
+ // The 1st member function removes an element at a given position
+ mymap_erase_at(&m1, mymap_advance(mymap_begin(&m1), 1));
+ puts("After the 2nd element is deleted, the map m1 is:");
+ printmap(m1);
+
+ // Fill in some data to test with
+ mymap m2 = c_init(mymap, {
+ {10, "Bob"},
+ {11, "Rob"},
+ {12, "Robert"},
+ {13, "Bert"},
+ {14, "Bobby"},
+ });
+
+ puts("Starting data of map m2 is:");
+ printmap(m2);
+ mymap_iter it1 = mymap_advance(mymap_begin(&m2), 1);
+ mymap_iter it2 = mymap_find(&m2, mymap_back(&m2)->first);
+
+ puts("to remove:");
+ c_foreach (i, mymap, it1, it2)
+ printf(" [%d, %s]", i.ref->first, cstr_str(&i.ref->second));
+ puts("");
+ // The 2nd member function removes elements
+ // in the range [First, Last)
+ mymap_erase_range(&m2, it1, it2);
+ puts("After the middle elements are deleted, the map m2 is:");
+ printmap(m2);
+
+ mymap m3 = {0};
+
+ // Fill in some data to test with, one at a time, using emplace
+ mymap_emplace(&m3, 1, "red");
+ mymap_emplace(&m3, 2, "yellow");
+ mymap_emplace(&m3, 3, "blue");
+ mymap_emplace(&m3, 4, "green");
+ mymap_emplace(&m3, 5, "orange");
+ mymap_emplace(&m3, 6, "purple");
+ mymap_emplace(&m3, 7, "pink");
+
+ puts("Starting data of map m3 is:");
+ printmap(m3);
+ // The 3rd member function removes elements with a given Key
+ int count = mymap_erase(&m3, 2);
+ // The 3rd member function also returns the number of elements removed
+ printf("The number of elements removed from m3 is: %d\n", count);
+ puts("After the element with a key of 2 is deleted, the map m3 is:");
+ printmap(m3);
+
+ c_drop(mymap, &m1, &m2, &m3);
+}
diff --git a/misc/examples/sortedmaps/csmap_find.c b/misc/examples/sortedmaps/csmap_find.c
new file mode 100644
index 00000000..c392338d
--- /dev/null
+++ b/misc/examples/sortedmaps/csmap_find.c
@@ -0,0 +1,73 @@
+// This implements the c++ std::map::find example at:
+// https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-17
+#define i_implement
+#include <stc/cstr.h>
+
+#define i_key int
+#define i_val_str
+#define i_tag istr
+#include <stc/csmap.h>
+
+#define i_key csmap_istr_raw
+#define i_tag istr
+#include <stc/cvec.h>
+
+void print_elem(csmap_istr_raw p) {
+ printf("(%d, %s) ", p.first, p.second);
+}
+
+#define using_print_collection(CX) \
+ void print_collection_##CX(const CX* t) { \
+ printf("%" c_ZI " elements: ", CX##_size(t)); \
+ \
+ c_foreach (p, CX, *t) { \
+ print_elem(CX##_value_toraw(p.ref)); \
+ } \
+ puts(""); \
+ }
+
+using_print_collection(csmap_istr)
+using_print_collection(cvec_istr)
+
+void findit(csmap_istr c, csmap_istr_key val)
+{
+ printf("Trying find() on value %d\n", val);
+ csmap_istr_iter result = csmap_istr_find(&c, val); // prefer contains() or get()
+ if (result.ref) {
+ printf("Element found: "); print_elem(csmap_istr_value_toraw(result.ref)); puts("");
+ } else {
+ puts("Element not found.");
+ }
+}
+
+int main(void)
+{
+ csmap_istr m1 = c_init(csmap_istr, {{40, "Zr"}, {45, "Rh"}});
+ cvec_istr v = {0};
+
+ puts("The starting map m1 is (key, value):");
+ print_collection_csmap_istr(&m1);
+
+ typedef cvec_istr_value pair;
+ cvec_istr_push(&v, c_LITERAL(pair){43, "Tc"});
+ cvec_istr_push(&v, c_LITERAL(pair){41, "Nb"});
+ cvec_istr_push(&v, c_LITERAL(pair){46, "Pd"});
+ cvec_istr_push(&v, c_LITERAL(pair){42, "Mo"});
+ cvec_istr_push(&v, c_LITERAL(pair){44, "Ru"});
+ cvec_istr_push(&v, c_LITERAL(pair){44, "Ru"}); // attempt a duplicate
+
+ puts("Inserting the following vector data into m1:");
+ print_collection_cvec_istr(&v);
+
+ c_foreach (i, cvec_istr, cvec_istr_begin(&v), cvec_istr_end(&v))
+ csmap_istr_emplace(&m1, i.ref->first, i.ref->second);
+
+ puts("The modified map m1 is (key, value):");
+ print_collection_csmap_istr(&m1);
+ puts("");
+ findit(m1, 45);
+ findit(m1, 6);
+
+ csmap_istr_drop(&m1);
+ cvec_istr_drop(&v);
+}
diff --git a/misc/examples/sortedmaps/csmap_insert.c b/misc/examples/sortedmaps/csmap_insert.c
new file mode 100644
index 00000000..04b8ddc6
--- /dev/null
+++ b/misc/examples/sortedmaps/csmap_insert.c
@@ -0,0 +1,107 @@
+// This implements the std::map insert c++ example at:
+// https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-19
+#define i_key int
+#define i_val int
+#define i_tag ii // Map of int => int
+#include <stc/csmap.h>
+
+#define i_implement
+#include <stc/cstr.h>
+#define i_key int
+#define i_val_str
+#define i_tag istr // Map of int => cstr
+#include <stc/csmap.h>
+
+#define i_key csmap_ii_raw
+#define i_tag ii
+#include <stc/cvec.h>
+
+void print_ii(csmap_ii map) {
+ c_foreach (e, csmap_ii, map)
+ printf("(%d, %d) ", e.ref->first, e.ref->second);
+ puts("");
+}
+
+void print_istr(csmap_istr map) {
+ c_foreach (e, csmap_istr, map)
+ printf("(%d, %s) ", e.ref->first, cstr_str(&e.ref->second));
+ puts("");
+}
+
+int main(void)
+{
+ // insert single values
+ csmap_ii m1 = {0};
+ csmap_ii_insert(&m1, 1, 10);
+ csmap_ii_push(&m1, c_LITERAL(csmap_ii_value){2, 20});
+
+ puts("The original key and mapped values of m1 are:");
+ print_ii(m1);
+
+ // intentionally attempt a duplicate, single element
+ csmap_ii_result ret = csmap_ii_insert(&m1, 1, 111);
+ if (!ret.inserted) {
+ csmap_ii_value pr = *ret.ref;
+ puts("Insert failed, element with key value 1 already exists.");
+ printf(" The existing element is (%d, %d)\n", pr.first, pr.second);
+ }
+ else {
+ puts("The modified key and mapped values of m1 are:");
+ print_ii(m1);
+ }
+ puts("");
+
+ csmap_ii_insert(&m1, 3, 30);
+ puts("The modified key and mapped values of m1 are:");
+ print_ii(m1);
+ puts("");
+
+ // The templatized version inserting a jumbled range
+ csmap_ii m2 = {0};
+ cvec_ii v = {0};
+ typedef cvec_ii_value ipair;
+ cvec_ii_push(&v, c_LITERAL(ipair){43, 294});
+ cvec_ii_push(&v, c_LITERAL(ipair){41, 262});
+ cvec_ii_push(&v, c_LITERAL(ipair){45, 330});
+ cvec_ii_push(&v, c_LITERAL(ipair){42, 277});
+ cvec_ii_push(&v, c_LITERAL(ipair){44, 311});
+
+ puts("Inserting the following vector data into m2:");
+ c_foreach (e, cvec_ii, v)
+ printf("(%d, %d) ", e.ref->first, e.ref->second);
+ puts("");
+
+ c_foreach (e, cvec_ii, v)
+ csmap_ii_insert_or_assign(&m2, e.ref->first, e.ref->second);
+
+ puts("The modified key and mapped values of m2 are:");
+ c_foreach (e, csmap_ii, m2)
+ printf("(%d, %d) ", e.ref->first, e.ref->second);
+ puts("\n");
+
+ // The templatized versions move-constructing elements
+ csmap_istr m3 = {0};
+ csmap_istr_value ip1 = {475, cstr_lit("blue")}, ip2 = {510, cstr_lit("green")};
+
+ // single element
+ csmap_istr_insert(&m3, ip1.first, cstr_move(&ip1.second));
+ puts("After the first move insertion, m3 contains:");
+ print_istr(m3);
+
+ // single element
+ csmap_istr_insert(&m3, ip2.first, cstr_move(&ip2.second));
+ puts("After the second move insertion, m3 contains:");
+ print_istr(m3);
+ puts("");
+
+ csmap_ii m4 = {0};
+ // Insert the elements from an initializer_list
+ m4 = c_init(csmap_ii, {{4, 44}, {2, 22}, {3, 33}, {1, 11}, {5, 55}});
+ puts("After initializer_list insertion, m4 contains:");
+ print_ii(m4);
+ puts("");
+
+ cvec_ii_drop(&v);
+ csmap_istr_drop(&m3);
+ c_drop(csmap_ii, &m1, &m2, &m4);
+}
diff --git a/misc/examples/sortedmaps/csset_erase.c b/misc/examples/sortedmaps/csset_erase.c
new file mode 100644
index 00000000..9c7f5e1a
--- /dev/null
+++ b/misc/examples/sortedmaps/csset_erase.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+#define i_key int
+#include <stc/csset.h>
+
+int main(void)
+{
+ csset_int set = c_init(csset_int, {30, 20, 80, 40, 60, 90, 10, 70, 50});
+
+ c_foreach (k, csset_int, set)
+ printf(" %d", *k.ref);
+ puts("");
+
+ int val = 64;
+ csset_int_iter it;
+ printf("Show values >= %d:\n", val);
+ it = csset_int_lower_bound(&set, val);
+
+ c_foreach (k, csset_int, it, csset_int_end(&set))
+ printf(" %d", *k.ref);
+ puts("");
+
+ printf("Erase values >= %d:\n", val);
+ while (it.ref)
+ it = csset_int_erase_at(&set, it);
+
+ c_foreach (k, csset_int, set)
+ printf(" %d", *k.ref);
+ puts("");
+
+ val = 40;
+ printf("Erase values < %d:\n", val);
+ it = csset_int_lower_bound(&set, val);
+ csset_int_erase_range(&set, csset_int_begin(&set), it);
+
+ c_foreach (k, csset_int, set)
+ printf(" %d", *k.ref);
+ puts("");
+
+ csset_int_drop(&set);
+}
diff --git a/misc/examples/sortedmaps/gauss2.c b/misc/examples/sortedmaps/gauss2.c
new file mode 100644
index 00000000..02ce4bc5
--- /dev/null
+++ b/misc/examples/sortedmaps/gauss2.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <time.h>
+
+#define i_implement
+#include <stc/cstr.h>
+#include <stc/crand.h>
+
+// Declare int -> int sorted map.
+#define i_key int
+#define i_val int
+#include <stc/csmap.h>
+
+int main(void)
+{
+ enum {N = 5000000};
+ uint64_t seed = (uint64_t)time(NULL);
+ crand_t rng = crand_init(seed);
+ const double Mean = round(crand_f64(&rng)*98.0 - 49.0), StdDev = crand_f64(&rng)*10.0 + 1.0, Scale = 74.0;
+
+ printf("Demo of gaussian / normal distribution of %d random samples\n", N);
+ printf("Mean %f, StdDev %f\n", Mean, StdDev);
+
+ // Setup random engine with normal distribution.
+ crand_normal_t dist = crand_normal_init(Mean, StdDev);
+
+ // Create and init histogram map with defered destruct
+ csmap_int hist = {0};
+ cstr bar = {0};
+
+ c_forrange (N) {
+ int index = (int)round(crand_normal(&rng, &dist));
+ csmap_int_insert(&hist, index, 0).ref->second += 1;
+ }
+
+ // Print the gaussian bar chart
+ c_forpair (index, count, csmap_int, hist) {
+ int n = (int)round((double)*_.count * StdDev * Scale * 2.5 / (double)N);
+ if (n > 0) {
+ cstr_resize(&bar, n, '*');
+ printf("%4d %s\n", *_.index, cstr_str(&bar));
+ }
+ }
+ cstr_drop(&bar);
+ csmap_int_drop(&hist);
+}
diff --git a/misc/examples/sortedmaps/listmap.c b/misc/examples/sortedmaps/listmap.c
new file mode 100644
index 00000000..04a605a7
--- /dev/null
+++ b/misc/examples/sortedmaps/listmap.c
@@ -0,0 +1,65 @@
+// This implements the multimap c++ example found at:
+// https://en.cppreference.com/w/cpp/container/multimap/insert
+
+// Multimap entries
+#define i_implement
+#include <stc/cstr.h>
+#define i_key_str
+#include <stc/clist.h>
+
+// Map of int => clist_str.
+#define i_type Multimap
+#define i_key int
+#define i_valclass clist_str // set i_val = clist_str, bind clist_str_clone and clist_str_drop
+#define i_cmp -c_default_cmp // like std::greater<int>
+#include <stc/csmap.h>
+
+void print(const char* lbl, const Multimap mmap)
+{
+ printf("%s ", lbl);
+ c_foreach (e, Multimap, mmap) {
+ c_foreach (s, clist_str, e.ref->second)
+ printf("{%d,%s} ", e.ref->first, cstr_str(s.ref));
+ }
+ puts("");
+}
+
+void insert(Multimap* mmap, int key, const char* str)
+{
+ clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second;
+ clist_str_emplace_back(list, str);
+}
+
+int main(void)
+{
+ Multimap mmap = {0};
+
+ // list-initialize
+ typedef struct {int a; const char* b;} pair;
+ c_forlist (i, pair, {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}})
+ insert(&mmap, i.ref->a, i.ref->b);
+ print("#1", mmap);
+
+ // insert using value_type
+ insert(&mmap, 5, "pqr");
+ print("#2", mmap);
+
+ // insert using make_pair
+ insert(&mmap, 6, "uvw");
+ print("#3", mmap);
+
+ insert(&mmap, 7, "xyz");
+ print("#4", mmap);
+
+ // insert using initialization_list
+ c_forlist (i, pair, {{5, "one"}, {5, "two"}})
+ insert(&mmap, i.ref->a, i.ref->b);
+ print("#5", mmap);
+
+ // FOLLOWING NOT IN ORIGINAL EXAMPLE:
+ // erase all entries with key 5
+ Multimap_erase(&mmap, 5);
+ print("+5", mmap);
+
+ Multimap_drop(&mmap);
+}
diff --git a/misc/examples/sortedmaps/mapmap.c b/misc/examples/sortedmaps/mapmap.c
new file mode 100644
index 00000000..d3065659
--- /dev/null
+++ b/misc/examples/sortedmaps/mapmap.c
@@ -0,0 +1,64 @@
+// create a structure like: std::map<std::string, std::map<std::string, std::string>>:
+#define i_implement
+#include <stc/cstr.h>
+
+// People: std::map<std::string, std::string>
+#define i_type People
+#define i_key_str // name
+#define i_val_str // email
+#define i_keydrop(p) (printf("kdrop: %s\n", cstr_str(p)), cstr_drop(p)) // override
+#include <stc/cmap.h>
+
+// Departments: std::map<std::string, People>
+#define i_type Departments
+#define i_key_str // dep. name
+#define i_valclass People
+#include <stc/cmap.h>
+
+
+void add(Departments* deps, const char* name, const char* email, const char* dep)
+{
+ People *people = &Departments_emplace(deps, dep, People_init()).ref->second;
+ People_emplace_or_assign(people, name, email);
+}
+
+int contains(Departments* map, const char* name)
+{
+ int count = 0;
+ c_foreach (i, Departments, *map)
+ if (People_contains(&i.ref->second, name))
+ ++count;
+ return count;
+}
+
+int main(void)
+{
+ Departments map = {0};
+
+ add(&map, "Anna Kendro", "[email protected]", "Support");
+ add(&map, "Terry Dane", "[email protected]", "Development");
+ add(&map, "Kik Winston", "[email protected]", "Finance");
+ add(&map, "Nancy Drew", "[email protected]", "Development");
+ add(&map, "Nick Denton", "[email protected]", "Finance");
+ add(&map, "Stan Whiteword", "[email protected]", "Marketing");
+ add(&map, "Serena Bath", "[email protected]", "Support");
+ add(&map, "Patrick Dust", "[email protected]", "Finance");
+ add(&map, "Red Winger", "[email protected]", "Marketing");
+ add(&map, "Nick Denton", "[email protected]", "Support");
+ add(&map, "Colin Turth", "[email protected]", "Support");
+ add(&map, "Dennis Kay", "[email protected]", "Marketing");
+ add(&map, "Anne Dickens", "[email protected]", "Development");
+
+ c_foreach (i, Departments, map)
+ c_forpair (name, email, People, i.ref->second)
+ printf("%s: %s - %s\n", cstr_str(&i.ref->first), cstr_str(_.name), cstr_str(_.email));
+ puts("");
+
+ printf("found Nick Denton: %d\n", contains(&map, "Nick Denton"));
+ printf("found Patrick Dust: %d\n", contains(&map, "Patrick Dust"));
+ printf("found Dennis Kay: %d\n", contains(&map, "Dennis Kay"));
+ printf("found Serena Bath: %d\n", contains(&map, "Serena Bath"));
+ puts("Done");
+
+ Departments_drop(&map);
+}
diff --git a/misc/examples/sortedmaps/multimap.c b/misc/examples/sortedmaps/multimap.c
new file mode 100644
index 00000000..a4490f91
--- /dev/null
+++ b/misc/examples/sortedmaps/multimap.c
@@ -0,0 +1,103 @@
+#define i_implement
+#include <stc/cstr.h>
+
+// Olympics multimap example
+
+struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = {
+ {2026, "Milan and Cortina d'Ampezzo", "Italy", "February 6-22"},
+ {2022, "Beijing", "China", "February 4-20"},
+ {2018, "PyeongChang", "South Korea", "February 9-25"},
+ {2014, "Sochi", "Russia", "February 7-23"},
+ {2010, "Vancouver", "Canada", "February 12-28"},
+ {2006, "Torino", "Italy", "February 10-26"},
+ {2002, "Salt Lake City", "United States", "February 8-24"},
+ {1998, "Nagano", "Japan", "February 7-22"},
+ {1994, "Lillehammer", "Norway", "February 12-27"},
+ {1992, "Albertville", "France", "February 8-23"},
+ {1988, "Calgary", "Canada", "February 13-28"},
+ {1984, "Sarajevo", "Yugoslavia", "February 8-19"},
+ {1980, "Lake Placid", "United States", "February 13-24"},
+ {1976, "Innsbruck", "Austria", "February 4-15"},
+ {1972, "Sapporo", "Japan", "February 3-13"},
+ {1968, "Grenoble", "France", "February 6-18"},
+ {1964, "Innsbruck", "Austria", "January 29-February 9"},
+ {1960, "Squaw Valley", "United States", "February 18-28"},
+ {1956, "Cortina d'Ampezzo", "Italy", "January 26 - February 5"},
+ {1952, "Oslo", "Norway", "February 14 - 25"},
+ {1948, "St. Moritz", "Switzerland", "January 30 - February 8"},
+ {1944, "canceled", "canceled", "canceled"},
+ {1940, "canceled", "canceled", "canceled"},
+ {1936, "Garmisch-Partenkirchen", "Germany", "February 6 - 16"},
+ {1932, "Lake Placid", "United States", "February 4 - 15"},
+ {1928, "St. Moritz", "Switzerland", "February 11 - 19"},
+ {1924, "Chamonix", "France", "January 25 - February 5"},
+};
+
+typedef struct { int year; cstr city, date; } OlympicLoc;
+
+int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b);
+OlympicLoc OlympicLoc_clone(OlympicLoc loc);
+void OlympicLoc_drop(OlympicLoc* self);
+
+// Create a clist<OlympicLoc>, can be sorted by year.
+#define i_keyclass OlympicLoc // binds _cmp, _clone and _drop.
+#define i_use_cmp
+#define i_tag OL
+#include <stc/clist.h>
+
+// Create a csmap<cstr, clist_OL> where key is country name
+#define i_key_str // binds cstr_equ, cstr_hash, cstr_clone, ++
+#define i_valclass clist_OL // binds clist_OL_clone, clist_OL_drop
+#define i_tag OL
+#include <stc/csmap.h>
+
+int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b) {
+ return a->year - b->year;
+}
+
+OlympicLoc OlympicLoc_clone(OlympicLoc loc) {
+ loc.city = cstr_clone(loc.city);
+ loc.date = cstr_clone(loc.date);
+ return loc;
+}
+
+void OlympicLoc_drop(OlympicLoc* self) {
+ cstr_drop(&self->city);
+ cstr_drop(&self->date);
+}
+
+
+int main(void)
+{
+ // Define the multimap with destructor defered to when block is completed.
+ csmap_OL multimap = {0};
+ const clist_OL empty = clist_OL_init();
+
+ for (size_t i = 0; i < c_arraylen(ol_data); ++i)
+ {
+ struct OlympicsData* d = &ol_data[i];
+ OlympicLoc loc = {.year = d->year,
+ .city = cstr_from(d->city),
+ .date = cstr_from(d->date)};
+ // Insert an empty list for each new country, and append the entry to the list.
+ // If country already exist in map, its list is returned from the insert function.
+ clist_OL* list = &csmap_OL_emplace(&multimap, d->country, empty).ref->second;
+ clist_OL_push_back(list, loc);
+ }
+
+ // Sort locations by year for each country.
+ c_foreach (country, csmap_OL, multimap)
+ clist_OL_sort(&country.ref->second);
+
+ // Print the multimap:
+ c_foreach (country, csmap_OL, multimap)
+ {
+ // Loop the locations for a country sorted by year
+ c_foreach (loc, clist_OL, country.ref->second)
+ printf("%s: %d, %s, %s\n", cstr_str(&country.ref->first),
+ loc.ref->year,
+ cstr_str(&loc.ref->city),
+ cstr_str(&loc.ref->date));
+ }
+ csmap_OL_drop(&multimap);
+}
diff --git a/misc/examples/sortedmaps/new_smap.c b/misc/examples/sortedmaps/new_smap.c
new file mode 100644
index 00000000..ee946c9a
--- /dev/null
+++ b/misc/examples/sortedmaps/new_smap.c
@@ -0,0 +1,67 @@
+#define i_implement
+#include <stc/cstr.h>
+#include <stc/forward.h>
+
+forward_csmap(PMap, struct Point, int);
+
+// Use forward declared PMap in struct
+typedef struct {
+ PMap pntmap;
+ cstr name;
+} MyStruct;
+
+// Point => int map
+typedef struct Point { int x, y; } Point;
+int point_cmp(const Point* a, const Point* b) {
+ int c = a->x - b->x;
+ return c ? c : a->y - b->y;
+}
+
+#define i_type PMap
+#define i_key Point
+#define i_val int
+#define i_cmp point_cmp
+#define i_is_forward
+#include <stc/csmap.h>
+
+// cstr => cstr map
+#define i_type SMap
+#define i_key_str
+#define i_val_str
+#include <stc/csmap.h>
+
+// cstr set
+#define i_type SSet
+#define i_key_str
+#include <stc/csset.h>
+
+
+int main(void)
+{
+ PMap pmap = c_init(PMap, {
+ {{42, 14}, 1},
+ {{32, 94}, 2},
+ {{62, 81}, 3},
+ });
+ SMap smap = c_init(SMap, {
+ {"Hello, friend", "this is the mapped value"},
+ {"The brown fox", "jumped"},
+ {"This is the time", "for all good things"},
+ });
+ SSet sset = {0};
+
+ c_forpair (p, i, PMap, pmap)
+ printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i);
+ puts("");
+
+ c_forpair (i, j, SMap, smap)
+ printf(" (%s: %s)\n", cstr_str(_.i), cstr_str(_.j));
+
+ SSet_emplace(&sset, "Hello, friend");
+ SSet_emplace(&sset, "Goodbye, foe");
+ printf("Found? %s\n", SSet_contains(&sset, "Hello, friend") ? "true" : "false");
+
+ PMap_drop(&pmap);
+ SMap_drop(&smap);
+ SSet_drop(&sset);
+}
diff --git a/misc/examples/sortedmaps/sorted_map.c b/misc/examples/sortedmaps/sorted_map.c
new file mode 100644
index 00000000..89381554
--- /dev/null
+++ b/misc/examples/sortedmaps/sorted_map.c
@@ -0,0 +1,67 @@
+// https://iq.opengenus.org/containers-cpp-stl/
+
+#include <stdio.h>
+#define i_key int
+#define i_val int
+#include <stc/csmap.h>
+
+int main(void)
+{
+
+ // empty map containers
+ csmap_int gquiz1 = {0}, gquiz2 = {0};
+ c_defer(
+ csmap_int_drop(&gquiz1),
+ csmap_int_drop(&gquiz2)
+ ){
+ // insert elements in random order
+ csmap_int_insert(&gquiz1, 2, 30);
+ csmap_int_insert(&gquiz1, 4, 20);
+ csmap_int_insert(&gquiz1, 7, 10);
+ csmap_int_insert(&gquiz1, 5, 50);
+ csmap_int_insert(&gquiz1, 3, 60);
+ csmap_int_insert(&gquiz1, 1, 40);
+ csmap_int_insert(&gquiz1, 6, 50);
+
+ // printing map gquiz1
+ printf("\nThe map gquiz1 is :\n\tKEY\tELEMENT\n");
+ c_foreach (itr, csmap_int, gquiz1)
+ printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
+ printf("\n");
+
+ // assigning the elements from gquiz1 to gquiz2
+ c_foreach (i, csmap_int, gquiz1)
+ csmap_int_insert(&gquiz2, i.ref->first, i.ref->second);
+
+ // print all elements of the map gquiz2
+ printf("\nThe map gquiz2 is :\n\tKEY\tELEMENT\n");
+ c_foreach (itr, csmap_int, gquiz2)
+ printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
+ printf("\n");
+
+ // remove all elements up to element with key=3 in gquiz2
+ printf("\ngquiz2 after removal of elements less than key=3 :\n");
+ printf("\tKEY\tELEMENT\n");
+ csmap_int_erase_range(&gquiz2, csmap_int_begin(&gquiz2),
+ csmap_int_find(&gquiz2, 3));
+ c_foreach (itr, csmap_int, gquiz2)
+ printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
+ printf("\n");
+
+ // remove all elements with key = 4
+ int num = csmap_int_erase(&gquiz2, 4);
+ printf("\ngquiz2.erase(4) : %d removed\n", num);
+ printf("\tKEY\tELEMENT\n");
+ c_foreach (itr, csmap_int, gquiz2)
+ printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
+ printf("\n");
+
+ // lower bound and upper bound for map gquiz1 key = 5
+ printf("gquiz1.lower_bound(5) : ");
+ printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5).ref->first);
+ printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5).ref->second);
+ printf("gquiz1.upper_bound(5) : ");
+ printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5+1).ref->first);
+ printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5+1).ref->second);
+ }
+}