diff options
| author | Tyge Løvset <[email protected]> | 2021-12-15 10:45:22 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-12-15 10:45:22 +0100 |
| commit | 7f264be520123c71211967a56d2826d272694edf (patch) | |
| tree | 6afcd2ccf5ffb24fcaa2ef0be46434721b567549 | |
| parent | a2671650430bf12304bead0bc9f23903f03db8a6 (diff) | |
| download | STC-modified-7f264be520123c71211967a56d2826d272694edf.tar.gz STC-modified-7f264be520123c71211967a56d2826d272694edf.zip | |
Some improvements in cvec and cpque.
| -rw-r--r-- | docs/cpque_api.md | 11 | ||||
| -rw-r--r-- | docs/cvec_api.md | 4 | ||||
| -rw-r--r-- | examples/inits.c | 9 | ||||
| -rw-r--r-- | include/stc/cpque.h | 34 | ||||
| -rw-r--r-- | include/stc/cvec.h | 15 |
5 files changed, 32 insertions, 41 deletions
diff --git a/docs/cpque_api.md b/docs/cpque_api.md index ddc0532c..5c0c9ec4 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -3,17 +3,17 @@ A priority queue is a container adaptor that provides constant time lookup of the largest (by default) element, at the expense of logarithmic insertion and extraction. A user-provided ***i_cmp*** may be defined to set the ordering, e.g. using ***-c_default_cmp*** would cause the smallest element to appear as the top() value. +Note that **cpque** does not support `i_valraw` and `i_valto`, so only cloning via `i_valfrom` is available. + See the c++ class [std::priority_queue](https://en.cppreference.com/w/cpp/container/priority_queue) for a functional reference. ## Header file and declaration ```c #define i_val // value: REQUIRED -#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_cmp // three-way compare two i_val* : REQUIRED IF i_val is a non-integral type #define i_del // destroy value func - defaults to empty destruct -#define i_valraw // convertion "raw" type - defaults to i_val -#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy -#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valfrom // convertion func i_val => i_val - defaults to plain copy #define i_tag // defaults to i_val #include <stc/cpque.h> ``` @@ -37,7 +37,7 @@ cpque_X_value* cpque_X_top(const cpque_X* self); void cpque_X_make_heap(cpque_X* self); // call after using push_back(). void cpque_X_push(cpque_X* self, cpque_X_value value); -void cpque_X_emplace(cpque_X* self, cpque_X_rawvalue raw); +void cpque_X_emplace(cpque_X* self, cpque_X_value val); // clones value void cpque_X_pop(cpque_X* self); void cpque_X_erase_at(cpque_X* self, size_t idx); @@ -52,7 +52,6 @@ cpque_X_value cpque_X_value_clone(cpque_X_value val); |:-------------------|:--------------------------------------|:------------------------| | `cpque_X` | `struct {cpque_X_value* data; ...}` | The cpque type | | `cpque_X_value` | `i_val` | The cpque element type | -| `cpque_X_rawvalue` | `i_valraw` | cpque raw value type | ## Example ```c diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 8053b108..00c0498c 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -29,14 +29,14 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ```c cvec_X cvec_X_init(void); -cvec_X cvec_X_with_size(size_t size, i_val fill); +cvec_X cvec_X_with_size(size_t size, i_val null); cvec_X cvec_X_with_capacity(size_t size); cvec_X cvec_X_clone(cvec_X vec); void cvec_X_clear(cvec_X* self); void cvec_X_copy(cvec_X* self, cvec_X other); bool cvec_X_reserve(cvec_X* self, size_t cap); -bool cvec_X_resize(cvec_X* self, size_t size, i_val fill); +bool cvec_X_resize(cvec_X* self, size_t size, i_val null); void cvec_X_shrink_to_fit(cvec_X* self); void cvec_X_swap(cvec_X* a, cvec_X* b); void cvec_X_del(cvec_X* self); // destructor diff --git a/examples/inits.c b/examples/inits.c index 43613198..386be86e 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -39,16 +39,9 @@ int main(void) c_auto (cpque_f, floats) {
float nums[] = {4.0f, 2.0f, 5.0f, 3.0f, 1.0f};
- c_forrange (i, c_arraylen(nums)) {
- cpque_f_push_back(&floats, nums[i]);
- printf("%.1f ", floats.data[i]);
- }
- puts("");
-
// PRIORITY QUEUE
- cpque_f_make_heap(&floats);
- c_apply(cpque_f, push, &floats, {40.0f, 20.0f, 50.0f, 30.0f, 10.0f});
+ c_apply_n(cpque_f, push, &floats, nums, c_arraylen(nums));
puts("\npop and show high priorites first:");
while (! cpque_f_empty(floats)) {
diff --git a/include/stc/cpque.h b/include/stc/cpque.h index 6b09e1d5..49aa2406 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -46,9 +46,19 @@ STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){0}; }
STC_INLINE bool _cx_memb(_reserve)(_cx_self* self, size_t n) {
- if (n != self->size && n < self->capacity) return true;
- _cx_value *t = (_cx_value *)c_realloc(self->data, n*sizeof *t);
- return t ? (self->data = t, self->capacity = n) : 0;
+ if (n != self->size && n <= self->capacity) return true;
+ _cx_value *d = (_cx_value *)c_realloc(self->data, n*sizeof *d);
+ return d ? (self->data = d, self->capacity = n, true) : false;
+}
+
+STC_INLINE bool
+_cx_memb(_resize)(_cx_self* self, const size_t len, i_val null) {
+ if (!_cx_memb(_reserve)(self, len)) return false;
+ const size_t n = self->size;
+ for (size_t i = len; i < n; ++i) i_valdel(&self->data[i]);
+ for (size_t i = n; i < len; ++i) self->data[i] = null;
+ self->size = len;
+ return true;
}
STC_INLINE void _cx_memb(_shrink_to_fit)(_cx_self* self)
@@ -90,23 +100,13 @@ STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
}
-STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_rawvalue raw)
- { _cx_memb(_push)(self, i_valfrom(raw)); }
+STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_value val)
+ { _cx_memb(_push)(self, i_valfrom(val)); }
STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val)
- { return i_valfrom(i_valto(&val)); }
+ { return i_valfrom(val); }
#endif
-STC_INLINE void
-_cx_memb(_push_back)(_cx_self* self, _cx_value value) {
- if (self->size == self->capacity) _cx_memb(_reserve)(self, self->size*3/2 + 4);
- self->data[ self->size++ ] = value;
-}
-
-STC_INLINE void
-_cx_memb(_pop_back)(_cx_self* self)
- { _cx_value* p = &self->data[--self->size]; i_valdel(p); }
-
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp)
@@ -132,7 +132,7 @@ _cx_memb(_make_heap)(_cx_self* self) { STC_DEF _cx_self _cx_memb(_clone)(_cx_self q) {
_cx_self out = _cx_memb(_with_capacity)(q.size);
for (; out.size < out.capacity; ++out.size, ++q.data)
- out.data[out.size] = i_valfrom(i_valto(q.data));
+ out.data[out.size] = i_valfrom(*q.data);
return out;
}
#endif
diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 626ddad5..f64f7840 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -82,7 +82,7 @@ STC_API _cx_self _cx_memb(_init)(void); STC_API void _cx_memb(_del)(_cx_self* self);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap);
-STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_val fill_val);
+STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_val null);
STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
@@ -147,9 +147,9 @@ STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs) STC_INLINE size_t _cx_memb(_index)(_cx_self cx, _cx_iter it) { return it.ref - cx.data; }
STC_INLINE _cx_self
-_cx_memb(_with_size)(const size_t size, i_val null_val) {
+_cx_memb(_with_size)(const size_t size, i_val null) {
_cx_self cx = _cx_memb(_init)();
- _cx_memb(_resize)(&cx, size, null_val);
+ _cx_memb(_resize)(&cx, size, null);
return cx;
}
@@ -263,7 +263,7 @@ STC_DEF bool _cx_memb(_reserve)(_cx_self* self, const size_t cap) {
struct cvec_rep* rep = cvec_rep_(self);
const size_t len = rep->size;
- if (cap >= len) {
+ if (cap > rep->cap || cap && cap == len) {
rep = (struct cvec_rep*) c_realloc(rep->cap ? rep : NULL,
offsetof(struct cvec_rep, data) + cap*sizeof(i_val));
if (!rep) return false;
@@ -275,13 +275,12 @@ _cx_memb(_reserve)(_cx_self* self, const size_t cap) { }
STC_DEF bool
-_cx_memb(_resize)(_cx_self* self, const size_t len, i_val fill) {
- if (len > _cx_memb(_capacity)(*self))
- if (!_cx_memb(_reserve)(self, len)) return false;
+_cx_memb(_resize)(_cx_self* self, const size_t len, i_val null) {
+ if (!_cx_memb(_reserve)(self, len)) return false;
struct cvec_rep *rep = cvec_rep_(self);
const size_t n = rep->size;
for (size_t i = len; i < n; ++i) i_valdel(&self->data[i]);
- for (size_t i = n; i < len; ++i) self->data[i] = fill;
+ for (size_t i = n; i < len; ++i) self->data[i] = null;
if (rep->cap) rep->size = len;
return true;
}
|
