summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--examples/csmap_ex.c2
-rw-r--r--examples/ex_gauss1.c (renamed from examples/ex_gaussian.c)0
-rw-r--r--examples/ex_gauss2.c42
-rw-r--r--stc/csmap.h28
4 files changed, 56 insertions, 16 deletions
diff --git a/examples/csmap_ex.c b/examples/csmap_ex.c
index cd623b06..14d21b67 100644
--- a/examples/csmap_ex.c
+++ b/examples/csmap_ex.c
@@ -3,7 +3,7 @@
#include <stc/crand.h>
#include <stdio.h>
-using_csmap(i, int, int);
+using_csmap(i, int, size_t);
using_csset_str();
#include <time.h>
diff --git a/examples/ex_gaussian.c b/examples/ex_gauss1.c
index b9228aa5..b9228aa5 100644
--- a/examples/ex_gaussian.c
+++ b/examples/ex_gauss1.c
diff --git a/examples/ex_gauss2.c b/examples/ex_gauss2.c
new file mode 100644
index 00000000..7352d6a8
--- /dev/null
+++ b/examples/ex_gauss2.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+#include "stc/crand.h"
+#include "stc/cstr.h"
+#include "stc/csmap.h"
+
+// Declare int -> int sorted map. Uses typetag 'i' for ints.
+using_csmap(i, int, size_t);
+
+int main()
+{
+ enum {N = 10000000};
+ const double Mean = -12.0, StdDev = 6.0, Scale = 74;
+
+ printf("Demo of gaussian / normal distribution of %d random samples\n", N);
+
+ // Setup random engine with normal distribution.
+ uint64_t seed = time(NULL);
+ stc64_t rng = stc64_init(seed);
+ stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev);
+
+ // Create histogram map
+ csmap_i mhist = csmap_i_init();
+ for (size_t i = 0; i < N; ++i) {
+ int index = (int) round( stc64_normalf(&rng, &dist) );
+ ++ csmap_i_emplace(&mhist, index, 0).first->second;
+ }
+
+ // Print the gaussian bar chart
+ cstr_t bar = cstr_init();
+ c_foreach (i, csmap_i, mhist) {
+ size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N);
+ if (n > 0) {
+ cstr_resize(&bar, n, '*');
+ printf("%4d %s\n", i.ref->first, bar.str);
+ }
+ }
+ // Cleanup
+ cstr_del(&bar);
+ csmap_i_del(&mhist);
+}
diff --git a/stc/csmap.h b/stc/csmap.h
index ae4c862a..e64d1204 100644
--- a/stc/csmap.h
+++ b/stc/csmap.h
@@ -189,11 +189,10 @@ int main(void) {
keyDel(KEY_REF_##C(val)); \
MAP_ONLY_##C( mappedDel(&val->second); ) \
} \
- STC_INLINE C##_##X##_value_t \
- C##_##X##_value_clone(C##_##X##_value_t val) { \
- *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \
- MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \
- return val; \
+ STC_INLINE void \
+ C##_##X##_value_copy(const C##_##X##_value_t* src, C##_##X##_value_t* dst) { \
+ *KEY_REF_##C(dst) = keyFromRaw(keyToRaw(KEY_REF_##C(src))); \
+ MAP_ONLY_##C( dst->second = mappedFromRaw(mappedToRaw(&src->second)); ) \
} \
\
STC_API C##_##X##_node_t* C##_##X##_clone_r_(C##_##X##_node_t *tn); \
@@ -268,12 +267,12 @@ int main(void) {
\
STC_INLINE void \
C##_##X##_next(C##_##X##_iter_t* it) { \
- cbst_next((csmap___iter_t*) it); \
+ cbst_next((csmap___iter_t*) it, offsetof(C##_##X##_node_t, value)); \
} \
STC_INLINE C##_##X##_iter_t \
C##_##X##_begin(C##_##X* self) { \
C##_##X##_iter_t it = {NULL, 0, self->root}; \
- cbst_next((csmap___iter_t*) &it); \
+ cbst_next((csmap___iter_t*) &it, offsetof(C##_##X##_node_t, value)); \
return it; \
} \
STC_INLINE C##_##X##_iter_t \
@@ -307,7 +306,7 @@ static csmap___node_t cbst_nil = {&cbst_nil, &cbst_nil, 0};
STC_API csmap___node_t* cbst_skew(csmap___node_t *tn);
STC_API csmap___node_t* cbst_split(csmap___node_t *tn);
-STC_API void cbst_next(csmap___iter_t *it);
+STC_API void cbst_next(csmap___iter_t *it, size_t offset);
/* -------------------------- IMPLEMENTATION ------------------------- */
@@ -410,7 +409,7 @@ STC_API void cbst_next(csmap___iter_t *it);
cn->link[0] = C##_##X##_clone_r_(tn->link[0]); \
cn->link[1] = C##_##X##_clone_r_(tn->link[1]); \
cn->level = tn->level; \
- cn->value = C##_##X##_value_clone(tn->value); \
+ C##_##X##_value_copy(&tn->value, &cn->value); \
return cn; \
}
@@ -438,19 +437,18 @@ cbst_split(csmap___node_t *tn) {
}
STC_DEF void
-cbst_next(csmap___iter_t *it) {
+cbst_next(csmap___iter_t *it, size_t offset) {
csmap___node_t *tn = it->_tn;
- if (tn->level == 0 && it->_top == 0)
- it->ref = NULL;
- else {
+ if (tn->level || it->_top) {
while (tn->level) {
it->_st[it->_top++] = tn;
tn = tn->link[0];
}
tn = it->_st[--it->_top];
- it->ref = &tn->value;
it->_tn = tn->link[1];
- }
+ it->ref = (csmap___value_t *) ((uint8_t *)tn + offset);
+ } else
+ it->ref = NULL;
}
#else