diff options
| author | Tyge Løvset <[email protected]> | 2023-01-15 21:18:39 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-01-15 21:18:39 +0100 |
| commit | 770a39ff6ed39494569a411949f22edcdb7eb30c (patch) | |
| tree | ddc38f64ed90eceff9571c1c2753b4425947629e /include | |
| parent | c5e071c622d6f460aa1ad07b6543ceaaed5209fc (diff) | |
| download | STC-modified-770a39ff6ed39494569a411949f22edcdb7eb30c.tar.gz STC-modified-770a39ff6ed39494569a411949f22edcdb7eb30c.zip | |
Large commit:
- Moved stc/algo/cspan.h to stc/cspan.h - its a data view type similar to csview. +Many updates. Added docs/cspan_api.md page!
- Update c11/fmt.h to VER 2.0: NEW API, see test. NOTE: fmt.h is not officially part of STC, as it is C11, and STC is C99.
- Renamed crange_LITERAL() back to crange_literal(), and cspan_LITERAL() to cspan_literal(). These returns a compound literal (lvalue) that can be passed to a c_FOR*-iterator.
Diffstat (limited to 'include')
| -rw-r--r-- | include/c11/fmt.h | 90 | ||||
| -rw-r--r-- | include/stc/algo/crange.h | 4 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 5 | ||||
| -rw-r--r-- | include/stc/cspan.h (renamed from include/stc/algo/cspan.h) | 84 |
4 files changed, 104 insertions, 79 deletions
diff --git a/include/c11/fmt.h b/include/c11/fmt.h index 6e2f8e55..b42bd9fc 100644 --- a/include/c11/fmt.h +++ b/include/c11/fmt.h @@ -1,16 +1,19 @@ #ifndef FMT_H_INCLUDED
#define FMT_H_INCLUDED
-/*
-void fmt_print(dst, fmt, ...);
-void fmt_drop_buffer(fmt_buffer* buf);
+/*
+VER 2.0: NEW API:
- dst - destination, one of:
- int fd 1=stdout, 2=stderr
+void fmt_print(fmt, ...);
+void fmt_println(fmt, ...); // see remark below
+void fmt_printd(dest, fmt, ...);
+void fmt_freebuffer(fmt_buffer* buf);
+
+ dest - destination, one of:
FILE* fp Write to a file
char* strbuf Write to a pre-allocated string buffer
fmt_buffer* buf Auto realloc the needed memory (safe).
Set buf->stream=1 for stream-mode.
- Call fmt_drop_buffer(buf) after usage.
+ Call fmt_freebuffer(buf) after usage.
fmt - format string
{} Auto-detected format. If :MOD is not specified,
@@ -22,10 +25,11 @@ void fmt_drop_buffer(fmt_buffer* buf); * C11 or higher required.
* MAX 255 chars fmt string by default. MAX 12 arguments after fmt string.
+* fmt_println(): a) fmt must be a const char* literal. b) at least one argument after fmt required by ISO C99.
* Static linking by default, shared symbols by defining FMT_HEADER / FMT_IMPLEMENT.
* (c) operamint, 2022, MIT License.
-----------------------------------------------------------------------------------
-#include "fmt.h"
+#include "c11/fmt.h"
int main() {
const double pi = 3.141592653589793;
@@ -37,22 +41,22 @@ int main() { unsigned char r = 123, g = 214, b = 90, w = 110;
char buffer[64];
- fmt_print(1, "Color: ({} {} {}), {}\n", r, g, b, flag);
- fmt_print(1, "Wide: {}, {}\n", wstr, L"wide world");
- fmt_print(1, "{:10} {:10} {:10.2f}\n", 42ull, 43, pi);
- fmt_print(stdout, "{:>10} {:>10} {:>10}\n", z, z, w);
- fmt_print(stdout, "{:10} {:10} {:10}\n", "Hello", "Mad", "World");
- fmt_print(stderr, "100%: {:<20} {:.*} {}\n", string, 4, pi, x);
- fmt_print(buffer, "Precision: {} {:.10} {}", string, pi, x);
- fmt_print(1, "{}\n", buffer);
- fmt_print(1, "Vector: ({}, {}, {})\n", 3.2, 3.3, pi);
+ fmt_print("Color: ({} {} {}), {}\n", r, g, b, flag);
+ fmt_println("Wide: {}, {}", wstr, L"wide world");
+ fmt_println("{:10} {:10} {:10.2f}", 42ull, 43, pi);
+ fmt_println("{:>10} {:>10} {:>10}", z, z, w);
+ fmt_printd(stdout, "{:10} {:10} {:10}\n", "Hello", "Mad", "World");
+ fmt_printd(stderr, "100%: {:<20} {:.*} {}\n", string, 4, pi, x);
+ fmt_printd(buffer, "Precision: {} {:.10} {}", string, pi, x);
+ fmt_println("{}", buffer);
+ fmt_println("Vector: ({}, {}, {})", 3.2, 3.3, pi);
fmt_buffer out[1] = {{.stream=1}};
- fmt_print(out, "{} {}", "Pi is:", pi);
- fmt_print(1, "{}, len={}, cap={}\n", out->data, out->len, out->cap);
- fmt_print(out, "{} {}", ", Pi squared is:", pi*pi);
- fmt_print(1, "{}, len={}, cap={}\n", out->data, out->len, out->cap);
- fmt_drop_buffer(out);
+ fmt_printd(out, "{} {}", "Pi is:", pi);
+ fmt_print("{}, len={}, cap={}\n", out->data, out->len, out->cap);
+ fmt_printd(out, "{} {}", ", Pi squared is:", pi*pi);
+ fmt_print("{}, len={}, cap={}\n", out->data, out->len, out->cap);
+ fmt_freebuffer(out);
}
*/
#include <stdio.h>
@@ -87,58 +91,60 @@ typedef struct { _Bool stream;
} fmt_buffer;
-FMT_API void fmt_drop_buffer(fmt_buffer* buf);
+FMT_API void fmt_freebuffer(fmt_buffer* buf);
FMT_API int _fmt_parse(char* p, int nargs, const char *fmt, ...);
-FMT_API void _fmt_iprint(int fd, const char* fmt, ...);
FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...);
#ifndef FMT_MAX
#define FMT_MAX 256
#endif
+#define fmt_print(...) fmt_printd(stdout, __VA_ARGS__)
+#define fmt_println(fmt, ...) fmt_printd(stdout, fmt "\n", __VA_ARGS__)
+
/* Primary function. */
-#define fmt_print(...) fmt_OVERLOAD(fmt_print, __VA_ARGS__)
-#define fmt_print2(to, fmt) \
+#define fmt_printd(...) fmt_OVERLOAD(fmt_printd, __VA_ARGS__)
+#define fmt_printd2(to, fmt) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 0, fmt); \
fmt_OK(_n == 0); _fmt_fn(to)(to, fmt); } while (0)
-#define fmt_print3(to, fmt, c) \
+#define fmt_printd3(to, fmt, c) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 1, fmt, _fc(c)); \
fmt_OK(_n == 1); _fmt_fn(to)(to, _fs, c); } while (0)
-#define fmt_print4(to, fmt, c, d) \
+#define fmt_printd4(to, fmt, c, d) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 2, fmt, _fc(c), _fc(d)); \
fmt_OK(_n == 2); _fmt_fn(to)(to, _fs, c, d); } while (0)
-#define fmt_print5(to, fmt, c, d, e) \
+#define fmt_printd5(to, fmt, c, d, e) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 3, fmt, _fc(c), _fc(d), _fc(e)); \
fmt_OK(_n == 3); _fmt_fn(to)(to, _fs, c, d, e); } while (0)
-#define fmt_print6(to, fmt, c, d, e, f) \
+#define fmt_printd6(to, fmt, c, d, e, f) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 4, fmt, _fc(c), _fc(d), _fc(e), _fc(f)); \
fmt_OK(_n == 4); _fmt_fn(to)(to, _fs, c, d, e, f); } while (0)
-#define fmt_print7(to, fmt, c, d, e, f, g) \
+#define fmt_printd7(to, fmt, c, d, e, f, g) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 5, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g)); \
fmt_OK(_n == 5); _fmt_fn(to)(to, _fs, c, d, e, f, g); } while (0)
-#define fmt_print8(to, fmt, c, d, e, f, g, h) \
+#define fmt_printd8(to, fmt, c, d, e, f, g, h) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 6, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h)); \
fmt_OK(_n == 6); _fmt_fn(to)(to, _fs, c, d, e, f, g, h); } while (0)
-#define fmt_print9(to, fmt, c, d, e, f, g, h, i) \
+#define fmt_printd9(to, fmt, c, d, e, f, g, h, i) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 7, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), _fc(i)); \
fmt_OK(_n == 7); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i); } while (0)
-#define fmt_print10(to, fmt, c, d, e, f, g, h, i, j) \
+#define fmt_printd10(to, fmt, c, d, e, f, g, h, i, j) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 8, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \
_fc(i), _fc(j)); \
fmt_OK(_n == 8); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j); } while (0)
-#define fmt_print11(to, fmt, c, d, e, f, g, h, i, j, k) \
+#define fmt_printd11(to, fmt, c, d, e, f, g, h, i, j, k) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 9, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \
_fc(i), _fc(j), _fc(k)); \
fmt_OK(_n == 9); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k); } while (0)
-#define fmt_print12(to, fmt, c, d, e, f, g, h, i, j, k, m) \
+#define fmt_printd12(to, fmt, c, d, e, f, g, h, i, j, k, m) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 10, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \
_fc(i), _fc(j), _fc(k), _fc(m)); \
fmt_OK(_n == 10); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m); } while (0)
-#define fmt_print13(to, fmt, c, d, e, f, g, h, i, j, k, m, n) \
+#define fmt_printd13(to, fmt, c, d, e, f, g, h, i, j, k, m, n) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 11, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \
_fc(i), _fc(j), _fc(k), _fc(m), _fc(n)); \
fmt_OK(_n == 11); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m, n); } while (0)
-#define fmt_print14(to, fmt, c, d, e, f, g, h, i, j, k, m, n, o) \
+#define fmt_printd14(to, fmt, c, d, e, f, g, h, i, j, k, m, n, o) \
do { char _fs[FMT_MAX]; int _n = _fmt_parse(_fs, 12, fmt, _fc(c), _fc(d), _fc(e), _fc(f), _fc(g), _fc(h), \
_fc(i), _fc(j), _fc(k), _fc(m), _fc(n), _fc(o)); \
fmt_OK(_n == 12); _fmt_fn(to)(to, _fs, c, d, e, f, g, h, i, j, k, m, n, o); } while (0)
@@ -146,7 +152,6 @@ FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); #define _fmt_fn(x) _Generic ((x), \
FILE*: fprintf, \
char*: sprintf, \
- int: _fmt_iprint, \
fmt_buffer*: _fmt_bprint)
#if defined(_MSC_VER) && !defined(__clang__)
@@ -184,17 +189,10 @@ FMT_API void _fmt_bprint(fmt_buffer*, const char* fmt, ...); #include <stdarg.h>
#include <string.h>
-FMT_API void fmt_drop_buffer(fmt_buffer* buf) {
+FMT_API void fmt_freebuffer(fmt_buffer* buf) {
free(buf->data);
}
-FMT_API void _fmt_iprint(int fd, const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vfprintf(fd == 1 ? stdout : stderr, fmt, args);
- va_end(args);
-}
-
FMT_API void _fmt_bprint(fmt_buffer* buf, const char* fmt, ...) {
va_list args, args2;
va_start(args, fmt);
diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h index 518320b5..63242a54 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -34,7 +34,7 @@ int main() // use a temporary crange object. int a = 100, b = INT32_MAX; - c_FORFILTER (i, crange, crange_object(a, b, 8) + c_FORFILTER (i, crange, crange_literal(a, b, 8) , i.index > 10 , c_FLT_TAKE(i, 3)) printf(" %lld", *i.ref); @@ -46,7 +46,7 @@ int main() #include <stc/ccommon.h> -#define crange_object(...) \ +#define crange_literal(...) \ (*(crange[]){crange_make(__VA_ARGS__)}) typedef long long crange_value; diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index a2c529a7..edf4b2cb 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -38,6 +38,11 @@ #define c_ZU PRIu64 #define c_NPOS INT64_MAX #endif +#if defined STC_NDEBUG || defined NDEBUG + #define c_ASSERT(expr) (void)(expr) +#else + #define c_ASSERT(expr) assert(expr) +#endif #if defined(_MSC_VER) #pragma warning(disable: 4116 4996) // unnamed type definition in parentheses diff --git a/include/stc/algo/cspan.h b/include/stc/cspan.h index 03cb8622..f5114a11 100644 --- a/include/stc/algo/cspan.h +++ b/include/stc/cspan.h @@ -22,19 +22,21 @@ */ /* #include <stdio.h> -#include <stc/algo/cspan.h> - -using_cspan(Span3f, float, 3); +#include <stc/cspan.h> +#include <stc/algo/filter.h> +using_cspan(Span2f, float, 2); +using_cspan(Intspan, int, 1); int demo1() { - float raw[3*4*5]; - Span3f span = cspan_make(raw, 3, 4, 5); - *cspan_at(&span, 2, 3, 4) = 100; + float raw[4*5]; + Span2f ms = cspan_make(raw, 4, 5); - printf("%f\n", *cspan_at(&span, 2, 3, 4)); -} + for (size_t i=0; i<ms.dim[0]; i++) + for (size_t j=0; j<ms.dim[1]; j++) + *cspan_at(&ms, i, j) = i*1000 + j; -using_cspan(Intspan, int, 1); + printf("%f\n", *cspan_at(&span, 3, 4)); +} int demo2() { int array[] = {1, 2, 3, 4, 5}; @@ -44,8 +46,8 @@ int demo2() { printf(" %d", *i.ref); puts(""); - // use a temporary IntSpan object. - c_FORFILTER (i, Intspan, cspan_object(Intspan, {10, 20, 30, 23, 22, 21}) + // use a temporary Intspan object. + c_FORFILTER (i, Intspan, cspan_literal(Intspan, {10, 20, 30, 23, 22, 21}) , c_FLT_SKIPWHILE(i, *i.ref < 25) && (*i.ref & 1) == 0 // even only , c_FLT_TAKE(i, 2)) // break after 2 @@ -56,12 +58,12 @@ int demo2() { #ifndef STC_CSPAN_H_INCLUDED #define STC_CSPAN_H_INCLUDED -#include "../ccommon.h" +#include "ccommon.h" #define using_cspan(Self, T, RANK) \ typedef T Self##_value, Self##_raw; \ - typedef struct { Self##_value *data; uint32_t dim[RANK]; } Self; \ typedef struct { Self##_value *ref, *end; } Self##_iter; \ + typedef struct { Self##_value *data; uint32_t dim[RANK]; } Self; \ \ STC_INLINE Self##_iter Self##_begin(const Self* self) { \ Self##_iter it = {self->data, self->data + cspan_size(self)}; \ @@ -75,26 +77,46 @@ int demo2() { { if (++it->ref == it->end) it->ref = NULL; } \ struct stc_nostruct -#define cspan_assert(self, rank) c_STATIC_ASSERT(cspan_rank(self) == rank) +#define using_cspan2(Self, T) using_cspan(Self##1, T, 1); using_cspan(Self##2, T, 2) +#define using_cspan3(Self, T) using_cspan2(Self, T); using_cspan(Self##3, T, 3) +#define using_cspan4(Self, T) using_cspan3(Self, T); using_cspan(Self##4, T, 4) + +#define cspan_check_rank(self, rank) c_STATIC_ASSERT(cspan_rank(self) == rank) -#define cspan_object(S, ...) \ +#define cspan_literal(S, ...) \ ((S){.data = (S##_value[])__VA_ARGS__, \ .dim = {sizeof((S##_value[])__VA_ARGS__)/sizeof(S##_value)}}) -#define cspan_make(data, ...) {data, {__VA_ARGS__}} -#define cspan_from(data) \ - {data + c_STATIC_ASSERT(sizeof(data) != sizeof(void*)), {c_ARRAYLEN(data)}} +#define cspan_make(data, ...) \ + {data, {__VA_ARGS__}} + +/* create a cspan from a cvec, cstack, cdeq, cqueue, or cpque (heap) */ +#define cspan_from(container) \ + {(container)->data, {(container)->_len}} + +#define cspan_from_array(array) \ + {(array) + c_STATIC_ASSERT(sizeof(array) != sizeof(void*)), {c_ARRAYLEN(array)}} #define cspan_size(self) _cspan_size((self)->dim, cspan_rank(self)) #define cspan_rank(self) c_ARRAYLEN((self)->dim) +#define cspan_index(self, ...) \ + c_PASTE(_cspan_i, c_NUMARGS(__VA_ARGS__))((self)->dim, __VA_ARGS__) + \ + cspan_check_rank(self, c_NUMARGS(__VA_ARGS__)) #define cspan_reshape(self, ...) \ - memcpy((self)->dim, (uint32_t[]){__VA_ARGS__}, \ - sizeof((self)->dim) + cspan_assert(self, c_NUMARGS(__VA_ARGS__))) + (void)memcpy((self)->dim, (uint32_t[]){__VA_ARGS__}, \ + sizeof((self)->dim) + cspan_check_rank(self, c_NUMARGS(__VA_ARGS__))) + +#define cspan_at(self, ...) ((self)->data + cspan_index(self, __VA_ARGS__)) -#define cspan_at(self, ...) \ - ((self)->data + c_PASTE(_cspan_i, c_NUMARGS(__VA_ARGS__))((self)->dim, __VA_ARGS__) \ - + cspan_assert(self, c_NUMARGS(__VA_ARGS__))) +#define cspan_slice4(self, x0, width) \ + {cspan_at(self, x0, 0, 0, 0), {width, (self)->dim[1], (self)->dim[2], (self)->dim[3]}} +#define cspan_slice3(self, x0, width) \ + {cspan_at(self, x0, 0, 0), {width, (self)->dim[1], (self)->dim[2]}} +#define cspan_slice2(self, x0, width) \ + {cspan_at(self, x0, 0), {width, (self)->dim[1]}} +#define cspan_slice1(self, x0, width) \ + {cspan_at(self, x0), {width}} #define cspan_4to3(self, x) \ {cspan_at(self, x, 0, 0, 0), {(self)->dim[1], (self)->dim[2], (self)->dim[3]}} @@ -109,18 +131,18 @@ int demo2() { #define cspan_2to1(self, x) \ {cspan_at(self, x, 0), {(self)->dim[1]}} -STC_INLINE uint32_t _cspan_i1(const uint32_t dim[1], uint32_t x) - { assert(x < dim[0]); return x; } +STC_INLINE size_t _cspan_i1(const uint32_t dim[1], uint32_t x) + { c_ASSERT(x < dim[0]); return x; } -STC_INLINE uint32_t _cspan_i2(const uint32_t dim[2], uint32_t x, uint32_t y) - { assert(x < dim[0] && y < dim[1]); return dim[1]*x + y; } +STC_INLINE size_t _cspan_i2(const uint32_t dim[2], uint32_t x, uint32_t y) + { c_ASSERT(x < dim[0] && y < dim[1]); return dim[1]*x + y; } -STC_INLINE uint32_t _cspan_i3(const uint32_t dim[3], uint32_t x, uint32_t y, uint32_t z) { - assert(x < dim[0] && y < dim[1] && z < dim[2]); +STC_INLINE size_t _cspan_i3(const uint32_t dim[3], uint32_t x, uint32_t y, uint32_t z) { + c_ASSERT(x < dim[0] && y < dim[1] && z < dim[2]); return dim[2]*(dim[1]*x + y) + z; } -STC_INLINE uint32_t _cspan_i4(const uint32_t dim[4], uint32_t x, uint32_t y, uint32_t z, uint32_t w) { - assert(x < dim[0] && y < dim[1] && z < dim[3] && w < dim[3]); +STC_INLINE size_t _cspan_i4(const uint32_t dim[4], uint32_t x, uint32_t y, uint32_t z, uint32_t w) { + c_ASSERT(x < dim[0] && y < dim[1] && z < dim[3] && w < dim[3]); return dim[3]*(dim[2]*(dim[1]*x + y) + z) + w; } STC_INLINE size_t _cspan_size(const uint32_t dim[], unsigned rank) { |
