On Thu, Jun 14, 2012 at 7:28 PM, Mike Pall <mike-1206@xxxxxxxxxx> wrote: > Justin Cormack wrote: > > On Tue, Jun 12, 2012 at 3:27 PM, Mike Pall <mike-1206@xxxxxxxxxx> wrote: > > > Well, it's not that difficult to do for the pointer case. But I'd > > > rather go for parameterized types, e.g. > > > > > > ffi.typeof("$ *", foo_t) > > > ffi.typeof("struct { $ k; $ v; }[?]", foo_t, bar_t) > > > > > > But I'm not sure whether the complexity is really worth it. > > > > > Not sure about that either - never really needed anything like that in a > C > > context. > > That's because C is statically typed. C++ added templates to > overcome this limitation (somewhat). We can certainly do better in > Lua. ;-) > > Actually, it wasn't that difficult to add parameterized types to > the FFI. The feature is now in git HEAD. No docs, yet, but you can > already play with it: > > The '$' character is the marker to be replaced with parameters in > a C type declaration: > > * A ctype or a cdata parameter is interpreted like an anonymous > typedef. You can use that to construct derived types, e.g. > ffi.typeof("$*", ct) is a pointer to ct, or "$[10]" is a 10 > element array. Unlike simplistic string concatenation, this > works for all cases (e.g. pointers to function pointers). > > * A string parameter is treated like an identifier or keyword, > except the string is _not_ parsed again or split into words > (this isn't simple textual substitution). You can use that for > field names, function names, argument names etc. > > [I'm pondering whether I should drop the keyword and type lookup > on the string. That would allow you to use arbitrary names for > fields, even when they collide with keywords or typedefs. I may > change that before writing the docs.] > > * A number parameter is treated as an integer. You can use that > to construct fixed size arrays. In some contexts you may prefer > this over VLAs. It works for multi-dimensional types, too. E.g.: > > local matrix_t = ffi.typeof("uint8_t[$][$]", width, height) > ... > local m = matrix_t() > > Only ffi.typeof() and ffi.cdef() parse parameterized types. The > other functions, e.g. ffi.new(), don't do that, because they > already take other arguments (e.g. initializers). I guess it would > be too confusing to mix two kinds of arguments. > > Anyway, parameterized types are a nice tool, but you'll want to > use it sparingly! > > The typical scenarios where you'd use templates in C++ come to > mind: e.g. construct a stack or a queue of an arbitrary type. > These need to create an array of the element type, which is now > really easy to do. [Justin's use case] > > Another example are derived types of anonymous structs. This > avoids pollution of the struct namespace. [Henk's use case] > > I'm sure you'll come up with a lot more use cases. > > Excellent. Certainly covers my use cases, will experiment with how to use it best, and I am sure some other uses will come up... Thanks Justin