A good advertisement for 'static if'

Craig Dillabaugh craig.dillabaugh at gmail.com
Thu Dec 12 06:55:27 PST 2013


I am not sure if this belongs in D.learn, but it might be of 
interest.  I was writing some C++ code for a project at work and 
have a class that stores image data from a file.  The image data 
can be in just about any numeric (int/float/complex) type, so I 
wanted a 'wrapper' class/struct that could hold any type of data 
without being 'parameterized' (we use templates for image access).

My class contains a union ( called 'data') with every possible 
type of pointer and parameter for indicating the data type. 
However, at some point code eventually needs to get at the data, 
so I have the following beauty of a template method, (calling the 
image structure RAWImageDataStore was a bad design decision on my 
part, need to change that soon, its very Java-esque):

template< class T >
RAWImageDataStore<T>* getBandData( )
{
    T t;
	
    //Check struct data type vs template type.
    if( datatype == TYPE_8u && typeid(t) == typeid(uint8_t) ) {
       return reinterpret_cast< RAWImageDataStore<T>* >( data.t8u 
);
    }
    else if ( datatype == TYPE_16s && typeid(t) == typeid(int16_t) 
) {
       return reinterpret_cast< RAWImageDataStore<T>* >( data.t16s 
);
    }
    //a number of types left out, I am sure you get the idea.
    //but you need to see the complex types, they are beautiful.
    else if ( datatype == TYPE_C16s &&
              typeid(t) ==  typeid(std::complex<int16_t>) )
    {
        return reinterpret_cast< RAWImageDataStore<T>* >( 
data.tC16s );
    }	
    \\OK, you only really needed to see one of the complex types 
:o)	
    else if( datatype == TYPE_UNKNOWN ) {
	    std::cerr << "Cannot access band with unknown data type."
                       << std::endl;
	   return 0;
    } //+ a bit more error handling code.

Initially this didn't compile because I was missing the 
"reinterpret_cast" statements.  They effectively do nothing. If 
the template type is int8_t then I return the data.t8u pointer, 
which is a RAWImageDataStore<int8_t>*, but have to cast it to  
RAWImageDataStore<int8_t>*.  I must do this because when I call 
the method type int16_t my "return data.t8u" returns the wrong 
type of pointer for the method, even though I know that if the 
type is int16_t this statement can never be reached.

I know there was some debate in the C++ community about whether 
they should adopt D-like "static if", which would have solved 
this problem, since it would compile the illegal code right out 
of existence.

Maybe there is a better way to do this in C++, but I thought I 
would post here as a case-study in the usefulness of 'static if'.

Craig


More information about the Digitalmars-d-learn mailing list