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