diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-11 20:19:55 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-11 20:19:55 -0700 |
commit | 082132f7d5d86068ab733f49fc4c43a9bd6157f1 (patch) | |
tree | 985bc3692395c4cedcdd98f84ea2349f03aab816 | |
parent | 9fca64292256f980e8cb15cea8c3e6cc7fd76374 (diff) | |
download | txr-082132f7d5d86068ab733f49fc4c43a9bd6157f1.tar.gz txr-082132f7d5d86068ab733f49fc4c43a9bd6157f1.tar.bz2 txr-082132f7d5d86068ab733f49fc4c43a9bd6157f1.zip |
ffi: new function, carray-pun.
* ffi.c (carray_pun): New function.
(ffi_init): Registered carray-pun intrinsic.
* ffi.h (carray_pun): Declared.
* txr.1: Documented.
-rw-r--r-- | ffi.c | 21 | ||||
-rw-r--r-- | ffi.h | 1 | ||||
-rw-r--r-- | txr.1 | 38 |
3 files changed, 60 insertions, 0 deletions
@@ -4672,6 +4672,26 @@ val carray_putz(val carray, val seq) return carray; } +val carray_pun(val carray, val type) +{ + val self = lit("carray-pun"); + struct carray *scry = carray_struct_checked(carray); + struct txr_ffi_type *tft = ffi_type_struct(type); + cnum len = scry->nelem; + cnum elsize = scry->eltft->size; + cnum size = (ucnum) len * (ucnum) elsize; + + if (tft->size == 0) + uw_throwf(error_s, + lit("~a: incomplete type ~s cannot be carray element"), + self, tft->syntax, nao); + + if (len != 0 && size / elsize != len) + uw_throwf(error_s, lit("~a: array size overflow"), self, nao); + + return make_carray(type, scry->data, size / tft->size, carray); +} + void ffi_init(void) { prot1(&ffi_typedef_hash); @@ -4777,6 +4797,7 @@ void ffi_init(void) reg_fun(intern(lit("carray-getz"), user_package), func_n1(carray_getz)); reg_fun(intern(lit("carray-put"), user_package), func_n2(carray_put)); reg_fun(intern(lit("carray-putz"), user_package), func_n2(carray_putz)); + reg_fun(intern(lit("carray-pun"), user_package), func_n2(carray_pun)); ffi_typedef_hash = make_hash(nil, nil, nil); ffi_init_types(); ffi_init_extra_types(); @@ -109,4 +109,5 @@ val carray_get(val carray); val carray_getz(val carray); val carray_put(val array, val seq); val carray_putz(val array, val seq); +val carray_pun(val carray, val type); void ffi_init(void); @@ -56861,6 +56861,44 @@ can be severed by invoking on the returned object, after which the two no longer share storage, and modifications in the original are not reflected in the subrange. +.coNP Function @ carray-pun +.synb +.mets (carray-sub < carray << type ) +.syne +.desc +The +.code carray-pun +creates a new +.code carray +object which provides an aliased view of the same data that is referenced by +the original +.meta carray +object. + +The +.meta type +argument specifies the element type used by the returned aliasing array. + +The +.code carray-pun +function considers the byte size of the array, which is a product of +the original length and element size. It then calculates how many elements of +.meta type +fit into this size. This value becomes the length of the aliasing array +which is returned. + +Since the returned aliasing array and the original refer to the same +storage, modifications performed in one view are reflected in the other. + +The aliasing array holds a reference to the original, so that as long as +it is reachable by the garbage collector, so is the original. +That relationship is severed if +.code carray-dup +is invoked on the aliasing array. + +The meaning of the aliasing depends entirely on the bitwise representations of +the types involved. + .SH* INTERACTIVE LISTENER .SS* Overview |