summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-12-15 10:45:22 +0100
committerTyge Løvset <[email protected]>2021-12-15 10:45:22 +0100
commit7f264be520123c71211967a56d2826d272694edf (patch)
tree6afcd2ccf5ffb24fcaa2ef0be46434721b567549
parenta2671650430bf12304bead0bc9f23903f03db8a6 (diff)
downloadSTC-modified-7f264be520123c71211967a56d2826d272694edf.tar.gz
STC-modified-7f264be520123c71211967a56d2826d272694edf.zip
Some improvements in cvec and cpque.
-rw-r--r--docs/cpque_api.md11
-rw-r--r--docs/cvec_api.md4
-rw-r--r--examples/inits.c9
-rw-r--r--include/stc/cpque.h34
-rw-r--r--include/stc/cvec.h15
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;
}