A good advertisement for 'static if'

FreeSlave freeslave93 at gmail.com
Thu Dec 12 09:34:12 PST 2013


On Thursday, 12 December 2013 at 14:55:28 UTC, Craig Dillabaugh 
wrote:
> 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

In C++ you can use partial specialization to achieve what you 
want.

class Storage
{
public:
     union {
         float* fdata;
         int* idata;
     } data;
};

template<typename T>
T* get(Storage& stor)
{
     return 0; //or throw exception
}

template<>
float* get<float>(Storage& stor)
{
     return stor.data.fdata;
}

template<>
int* get<int>(Storage& stor)
{
     return stor.data.idata;
}

int main()
{
     Storage stor;
     float* fdata = get<float>(stor);
     return 0;
}


More information about the Digitalmars-d-learn mailing list