From c542a17addd954ef0c5c9c9a80c368773a3d98b7 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 28 Apr 2022 10:51:59 +0200 Subject: Finalized template.h logic. --- examples/arc_demo.c | 2 +- examples/complex.c | 2 ++ examples/make.sh | 4 ++-- examples/mapmap.c | 16 ++++++++-------- examples/new_sptr.c | 3 +-- examples/rawptr_elements.c | 16 ++++++++++------ include/stc/ccommon.h | 2 ++ include/stc/template.h | 14 +++++++------- 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/examples/arc_demo.c b/examples/arc_demo.c index 132e940a..0ba5bf0a 100644 --- a/examples/arc_demo.c +++ b/examples/arc_demo.c @@ -10,7 +10,7 @@ void int_drop(int* x) { #define i_type Arc // set type name to be defined (instead of 'carc_int') #define i_val int -//#define i_valdrop int_drop // optional, just to display the elements destroyed +#define i_valdrop int_drop // optional, just to display the elements destroyed #include // Arc #define i_key_arcbox Arc // note: use i_key_bind instead of i_key for carc/cbox elements diff --git a/examples/complex.c b/examples/complex.c index 12b665c8..584343be 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -5,6 +5,8 @@ void check_drop(float* v) {printf("destroy %g\n", *v);} #define i_type FloatStack #define i_val float #define i_valdrop check_drop +#define i_valclone(x) x // required to allow cloning when i_valdrop is defined + // (not for carc as it does not use i_valclone to clone). #include #define i_type StackList diff --git a/examples/make.sh b/examples/make.sh index af7eace9..4a4fdbcf 100644 --- a/examples/make.sh +++ b/examples/make.sh @@ -1,6 +1,6 @@ #!/bin/bash -cc='clang -s -O2 -Wall -std=c99 -pedantic' -#cc='gcc -s -O2 -Wall -std=c99 -pedantic' +cc='gcc -s -O2 -Wall -std=c99 -pedantic' +#cc='clang -s -O2 -Wall -std=c99 -pedantic' #cc='gcc -x c++ -s -O2 -Wall -std=c++20' #cc='g++ -x c++ -s -O2 -Wall' #cc='clang -s -O2 -Wall -std=c99 -pedantic -DSTC_OLD_CSTR' diff --git a/examples/mapmap.c b/examples/mapmap.c index a8f0069c..668ec9e8 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -10,19 +10,19 @@ #define i_key_str #define i_val_bind People // Shorthand for: -//#define i_val People -//#define i_cmp People_cmp -//#define i_valfrom People_clone -//#define i_valdrop People_drop +// #define i_val People +// #define i_cmp People_cmp +// #define i_valclone People_clone +// #define i_valdrop People_drop #include #define i_type Stack #define i_val_bind People_value // Shorthand for: -//#define i_val People_value -//#define i_cmp People_value_cmp -//#define i_valfrom People_value_clone -//#define i_valdrop People_value_drop +// #define i_val People_value (pair of cstr) +// #define i_cmp People_value_cmp +// #define i_valclone People_value_clone +// #define i_valdrop People_value_drop #include void add(Departments* deps, const char* name, const char* email, const char* dep) diff --git a/examples/new_sptr.c b/examples/new_sptr.c index 57c67f94..84f7e075 100644 --- a/examples/new_sptr.c +++ b/examples/new_sptr.c @@ -15,7 +15,7 @@ void Person_drop(Person* p) { } #define i_val_bind Person -#define i_opt c_no_cmp +#define i_opt c_no_cmp // makes cmp and hash not required when using _bind #define i_tag person #include @@ -23,7 +23,6 @@ void Person_drop(Person* p) { #define i_type SPtr #define i_val int #define i_valdrop(x) printf("drop: %d\n", *x) -#define i_valfrom(i) i #include #define i_val_arcbox SPtr diff --git a/examples/rawptr_elements.c b/examples/rawptr_elements.c index a1344ea7..a6e195a9 100644 --- a/examples/rawptr_elements.c +++ b/examples/rawptr_elements.c @@ -7,20 +7,21 @@ struct { double x, y; } typedef Point; // Note it may be simpler to use a cbox for this. #define i_key Point* #define i_keydrop(x) c_free(*(x)) -#define i_keyfrom(x) c_new(Point, *(x)) +#define i_keyclone(x) c_new(Point, *(x)) #define i_hash(x) c_default_hash(*(x)) #define i_cmp(x, y) memcmp(*(x), *(y), sizeof **(x)) // not good! #define i_tag pnt #include -// Map of int64 pointers: For fun, define valraw as int64_t for easy emplace call! +// Map of int64 pointers: Define i_valraw as int64_t for easy emplace calls! typedef int64_t inttype; #define i_key_str #define i_val inttype* #define i_valraw inttype +#define i_valfrom(raw) (puts("from"), c_new(inttype, raw)) +#define i_valto(x) (puts("to"), **(x)) +#define i_valclone c_derived_valclone // enables clone via valto+valfrom #define i_valdrop(x) c_free(*(x)) -#define i_valfrom(raw) c_new(inttype, raw) -#define i_valto(x) **(x) #include int main() @@ -46,7 +47,7 @@ int main() puts(""); } - c_auto (cmap_str, map) + c_auto (cmap_str, map, m2) { printf("\nMap with pointer elements:\n"); cmap_str_insert(&map, cstr_new("testing"), c_new(inttype, 999)); @@ -56,7 +57,10 @@ int main() cmap_str_emplace(&map, "hello", 200); cmap_str_emplace(&map, "goodbye", 400); - c_forpair (name, number, cmap_str, map) + // default uses i_valfrom+i_valto when no i_valclone defined: + m2 = cmap_str_clone(map); + + c_forpair (name, number, cmap_str, m2) printf("%s: %" PRIdMAX "\n", cstr_str(&_.name), *_.number); } } diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index f4961c17..2b40557a 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -92,6 +92,8 @@ #define c_default_from(x) (x) #define c_default_toraw(ptr) (*(ptr)) #define c_default_drop(ptr) ((void) (ptr)) +#define c_derived_keyclone(x) i_keyfrom((i_keyto((&(x))))) +#define c_derived_valclone(x) i_valfrom((i_valto((&(x))))) #define c_option(flag) ((i_opt) & (flag)) #define c_is_fwd (1<<0) diff --git a/include/stc/template.h b/include/stc/template.h index b0a98d1e..a0cec3a8 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -146,16 +146,16 @@ #if !defined i_key #error "no i_key or i_val provided" -#elif defined i_keyraw && !defined i_keyfrom - #error "if i_keyraw is defined, i_keyfrom (and normally i_keyto) must be defined" +#elif defined i_keyraw ^ (defined i_keyfrom || defined i_keyto) + #error "if i_keyraw is defined, i_keyfrom and i_keyto must be defined, and vice versa" #elif defined i_from || defined i_drop #error "i_from / i_drop are not supported. Define i_keyfrom/i_valfrom and-or i_keydrop/i_valdrop instead." #endif #ifndef i_tag - #define i_tag i_key + #define i_tag i_key #endif -#if c_option(c_no_clone) +#if c_option(c_no_clone) || (!defined i_keyclone && (defined i_keydrop || defined i_keyraw)) #define _i_no_clone #endif #ifndef i_keyfrom @@ -223,11 +223,11 @@ #endif #endif -#if defined i_valraw && !defined i_valfrom - #error "if i_valraw is defined, i_valfrom (and normally i_valto) must be defined" +#if defined i_valraw ^ (defined i_valfrom || defined i_valto) + #error "if i_valraw is defined, i_valfrom and i_valto must be defined, and vice versa" #endif -#if !defined i_valfrom && defined i_valdrop +#if !defined i_valclone && (defined i_valdrop || defined i_valraw) #define _i_no_clone #endif #ifndef i_valfrom -- cgit v1.2.3