3 ms·
This is a nice concrete example of a situation where inheritance is useful for program design. I think i'd go for the "object oriented" approach, but with conv
by twic 4y ago
This is a nice concrete example of a situation where inheritance is useful for program design.
I think i'd go for the "object oriented" approach, but with convenience functions to avoid explicit upcasts. Start with three types:
cairo_t /* a generic context, could be a page or a pattern */
cairo_page_t
cairo_pattern_t
Functions only defined on pages take a page:
void pdf_page_cmd_bob(cairo_page_t* ctx);
Functions defined on both take a generic context:
void pdf_ctx_cmd_l(cairo_t* ctx, int x, int y);
Then you need some way to upcast from the child types to the parent (which would be implicit in C++ etc):
cairo_t* pdf_page_to_ctx(cairo_page_t* ctx);
cairo_t* pdf_pattern_to_ctx(cairo_pattern_t* ctx);
So a call looks like:
pdf_ctx_cmd_l(pdf_page_to_ctx(page), 10, 20);
But we can generate this:
void pdf_page_cmd_l(cairo_page_t* ctx, int x, int y) {
pdf_ctx_cmd_l(pdf_page_to_ctx(ctx), x, y);
}
Which lets users write this:
pdf_page_cmd_l(page, 10, 20);
The convenience functions could even be macros. There would be no loss of type safety from using macros that way. There would need to be a lot of convenience functions or macros, but they are trivial, and so could be generated by a script (or another macro!).
- fanf2 4y agoI have implemented this using the gcc/clang “transparent union” extension, which eliminates the need for explicit casting or helpers. https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#transparent_union https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.ht...