How do I defeat the gratuitous qualification of alias members?
Chad Joan
chadjoan at gmail.com
Thu Apr 4 20:50:59 PDT 2013
I'm writing a C wrapper and I have an enum:
enum SANE_Status
{
SANE_STATUS_GOOD = 0, /* everything A-OK */
SANE_STATUS_UNSUPPORTED, /* operation is not supported */
SANE_STATUS_CANCELLED, /* operation was cancelled */
...
}
Now, what I really hate to see is this:
if ( status == SANE_Status.SANE_STATUS_GOOD )
doSomething();
This is incompatible with how the C code would be written. Even worse:
so much repetitive noise! It gets worse yet when the enum members are
arguments to functions and there are more than one of them.
I understand that I could also write code this way:
alias int SANE_Status;
enum : SANE_Status
{
SANE_STATUS_GOOD = 0, /* everything A-OK */
SANE_STATUS_UNSUPPORTED, /* operation is not supported */
SANE_STATUS_CANCELLED, /* operation was cancelled */
...
}
This gives a more C-like behavior. However, I no longer have an enum
type that is distinct from 'int' and, more importantly, I can't use
"final switch(status) {...}" on this because typeof(status) isn't an
enum. It still allows me to write the final switch without compiler
errors, but it won't enforce exhaustiveness.
I am having some luck with this:
--------------------------
enum SANE_Status
{
SANE_STATUS_GOOD = 0, /* everything A-OK */
SANE_STATUS_UNSUPPORTED, /* operation is not supported */
SANE_STATUS_CANCELLED, /* operation was cancelled */
SANE_STATUS_DEVICE_BUSY, /* device is busy; try again later */
SANE_STATUS_INVAL, /* data is invalid (includes no dev at
open) */
SANE_STATUS_EOF, /* no more data available (end-of-file) */
SANE_STATUS_JAMMED, /* document feeder jammed */
SANE_STATUS_NO_DOCS, /* document feeder out of documents */
SANE_STATUS_COVER_OPEN, /* scanner cover is open */
SANE_STATUS_IO_ERROR, /* error during device I/O */
SANE_STATUS_NO_MEM, /* out of memory */
SANE_STATUS_ACCESS_DENIED /* access to resource has been denied */
}
alias SANE_Status.SANE_STATUS_GOOD SANE_STATUS_GOOD;
alias SANE_Status.SANE_STATUS_UNSUPPORTED SANE_STATUS_UNSUPPORTED;
alias SANE_Status.SANE_STATUS_CANCELLED SANE_STATUS_CANCELLED;
alias SANE_Status.SANE_STATUS_DEVICE_BUSY SANE_STATUS_DEVICE_BUSY;
alias SANE_Status.SANE_STATUS_INVAL SANE_STATUS_INVAL;
alias SANE_Status.SANE_STATUS_EOF SANE_STATUS_EOF;
alias SANE_Status.SANE_STATUS_JAMMED SANE_STATUS_JAMMED;
alias SANE_Status.SANE_STATUS_NO_DOCS SANE_STATUS_NO_DOCS;
alias SANE_Status.SANE_STATUS_COVER_OPEN SANE_STATUS_COVER_OPEN;
alias SANE_Status.SANE_STATUS_IO_ERROR SANE_STATUS_IO_ERROR;
alias SANE_Status.SANE_STATUS_NO_MEM SANE_STATUS_NO_MEM;
alias SANE_Status.SANE_STATUS_ACCESS_DENIED SANE_STATUS_ACCESS_DENIED;
void foo(SANE_Status s)
{
final switch(s)
{
case SANE_STATUS_GOOD: writeln("Good!"); break;
case SANE_STATUS_UNSUPPORTED: writeln("operation is not
supported"); break;
case SANE_STATUS_CANCELLED: writeln("operation was cancelled");
break;
case SANE_STATUS_DEVICE_BUSY: writeln("device is busy; try
again later"); break;
case SANE_STATUS_INVAL: writeln("data is invalid (includes no
dev at open)"); break;
case SANE_STATUS_EOF: writeln("no more data available
(end-of-file)"); break;
case SANE_STATUS_JAMMED: writeln("document feeder jammed"); break;
case SANE_STATUS_NO_DOCS: writeln("document feeder out of
documents"); break;
case SANE_STATUS_COVER_OPEN: writeln("scanner cover is open");
break;
case SANE_STATUS_IO_ERROR: writeln("error during device I/O");
break;
case SANE_STATUS_NO_MEM: writeln("out of memory"); break;
case SANE_STATUS_ACCESS_DENIED: writeln("access to resource has
been denied"); break;
}
writeln("foo works.");
}
int main(string[] args)
{
SANE_Status s = SANE_STATUS_GOOD;
if ( s == SANE_STATUS_GOOD )
writeln("hi!");
foo(SANE_STATUS_GOOD);
return 0;
}
--------------------------
But I would probably need some nontrivial CTFE to generate the aliases.
There has to be a better way!
Please help.
More information about the Digitalmars-d-learn
mailing list