Robert Bradshaw wrote:
> If I understand correctly, the issue here is how to map cython/c
> types to the "format" string of the buffer. There are three things to
> match:
>
> Numeric type (int/float)--this can be detected at compile time by
> (<type>1)/(<type>2) == 0 vs the buffer format string
> Signed--this can be detected at compile time by (<type>-1) < 0 vs the
> buffer format string
> Size--this can be detected at compile time by sizeof() vs the
> "itemsize" field of the buffer, or calcsize from the struct module if
> you need.
Very nice!
Or simply sizof(type) vs sizeof(int).
> All other types are required to match exactly (or something like
> that, some thought would have to be put into how to handle objects).
> For hybrid types I think it would be enough to just look at the total
> size after comparing the structs for (int/float/other and signed/
> unsigned). Then you could use numpy.uint and numpy.unit32, etc.
OK, writeup for clarity in the discussion, this is what needs to happen:
- A format string is recieved run-time when acquiring a buffer
- We have a compile-time assumed type for the buffer
- They need to be compared for sanity-checking
And this is how I see it happen (which is quite different from what I
thought a day ago):
- For each type used in a buffer, Cython will output a string-validating
inline function for that type.
- For structs (and other complicated things) this essentially boils down
to checking if a string corresponds to a known structure and is
relatively straightforward if potentially messy/wordy. (These will not
even be supported until working buffers for simple types hits
cython-devel IMO, iterative programming and all that...)
- When the exact C type is used directly, something like this may be
used (if I bother to treat it specially):
int Pyx_typestring_matches_unsigned_int(char* s) {
/* skipping the one-char check for now*/
return *s == 'U';
}
- When a typedef-ed type is output, something like this is used:
int Pyx_typestring_matches_npy_uint8(char* s) {
/* skipping the one-char check for now*/
switch (*s) {
case 'i':
return (((npy_uint8)1)/(npy_uint8)2) == 0) &&
((npy_uint8)-1 < 0) && sizeof(npy_uint8) == sizeof(int);
...
}
}
This should translate to a switch statement where every branch but one
will return false, and I think it is reasonable to hope the compiler
will make it as efficient as the former case.
Thanks! :-)
--
Dag Sverre
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev