From b079520f421a787b51965456518b5e97e2a569f6 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 23 Feb 2021 07:23:36 +0100 Subject: Added emplace-method table to README, and fixed a regression in cdeq. --- README.md | 37 +++++++++++++++++++++++-------------- stc/cdeq.h | 6 +++--- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 41e9be3c..41b4a488 100644 --- a/README.md +++ b/README.md @@ -191,16 +191,25 @@ using_cvec(i, int); using_clist(pt, struct Point); ``` -*emplace* versus non-emplace container methods ------------------------------------------------- -STC, like c++ STL, has two sets of methods for adding elements to containers. One set begins with -**emplace**, -e.g. **cvec_X_emplace_back()**. This is a convenient alternative to **cvec_X_push_back()** when dealing -non-trivial container elements, e.g. smart pointers or elements using dynamic memory. - -***Note***: For integral or trivial element types, **emplace** and corresponding non-emplace methods are identical, -and the following does not apply for maps of these types. - -The **emplace** methods ***constructs*** or ***clones*** their own copy of the elements to be added. +The *emplace* versus non-emplace container methods +-------------------------------------------------- +STC, like c++ STL, has two sets of methods for adding elements to containers. One set begins +with -**emplace**, e.g. **cvec_X_emplace_back()**. This is a convenient alternative to +**cvec_X_push_back()** when dealing non-trivial container elements, e.g. smart pointers or +elements using dynamic memory. + +| Move input into container | Construct element from input | Containers | +|:--------------------------|:-----------------------------|:-------------------------| +| insert() | emplace() | cmap, cset, csmap, csset | +| insert_or_assign(), put() | emplace_or_assign() | cmap, csmap | +| push_back() | emplace_back() | cvec, cdeq, clist | +| push_front() | emplace_front() | cvec, cdeq, clist | +| insert_after() | emplace_after() | clist | + +***Note***: For integral or trivial element types, **emplace** and corresponding non-emplace methods are +identical, and the following does not apply for maps and sets of those types. + +The **emplace** methods ***constructs*** or ***clones*** their own copy of the element to be added. In contrast, the non-emplace methods requires elements to be explicitly constructed or cloned before adding them. Strings are the most commonly used non-trivial data type. STC containers have proper pre-defined @@ -216,8 +225,8 @@ cvec_str_push_back(&vec, cstr_from("Hello")); // construct and add string cvec_str_push_back(&vec, cstr_clone(s)); // clone and add an existing string cvec_str_emplace_back(&vec, "Yay, literal"); // internally constructs cstr from string-literal -cvec_str_emplace_back(&vec, cstr_clone(s)); // Logical and compile ERROR! wrong input type -cvec_str_emplace_back(&vec, s.str); // Ok: const char* type (= rawvalue). +cvec_str_emplace_back(&vec, cstr_clone(s)); // <-- COMPILE ERROR: wrong input type +cvec_str_emplace_back(&vec, s.str); // Ok: const char* input type (= rawvalue). cstr_del(&s); cvec_del(&vec); @@ -245,8 +254,8 @@ cmap_str_insert(&map, cstr_from("Hello"), cstr_from("you")); it = cmap_str_find(&map, "Hello"); // No cstr constructed for lookup, although keys are cstr-type. ``` -Map and set are normally used with trivial value types, except for strings. The last -example on the **cmap** page demonstrates how to specify a map with non-trivial keys. +Apart from strings, maps and sets are normally used with trivial value types. However, the +last example on the **cmap** page demonstrates how to specify a map with non-trivial keys. Memory efficiency ----------------- diff --git a/stc/cdeq.h b/stc/cdeq.h index b964de2c..a7d6fe03 100644 --- a/stc/cdeq.h +++ b/stc/cdeq.h @@ -31,9 +31,9 @@ #define using_cdeq_2(X, Value) \ using_cdeq_3(X, Value, c_default_compare) #define using_cdeq_3(X, Value, valueCompare) \ - using_cdeq_7(X, Value, valueCompare, c_trivial_del, c_trivial_fromraw, c_trivial_toraw, Value) + using_cdeq_7(X, Value, valueCompare, c_plain_del, c_plain_fromraw, c_plain_toraw, Value) #define using_cdeq_5(X, Value, valueCompare, valueDel, valueFromRaw) \ - using_cdeq_7(X, Value, valueCompare, valueDel, valueFromRaw, c_trivial_toraw, Value) + using_cdeq_7(X, Value, valueCompare, valueDel, valueFromRaw, c_plain_toraw, Value) #define using_cdeq_str() \ using_cdeq_7(str, cstr_t, cstr_compare_raw, cstr_del, cstr_from, cstr_c_str, const char*) @@ -74,7 +74,7 @@ typedef int (*c_cmp_fn)(const void*, const void*); cdeq_##X##_resize(cdeq_##X* self, size_t size, Value fill_val); \ STC_INLINE void \ cdeq_##X##_reserve(cdeq_##X* self, size_t n) { \ - _cdeq_##X##_expand(self, (n - cdeq_rep_(self)->size)*1.5, false); \ + _cdeq_##X##_expand(self, (n - cdeq_rep_(self)->size)*0.65, false); \ } \ STC_INLINE void \ cdeq_##X##_swap(cdeq_##X* a, cdeq_##X* b) {c_swap(cdeq_##X, *a, *b);} \ -- cgit v1.2.3