discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: data type polymorphism


From: David Chisnall
Subject: Re: data type polymorphism
Date: Sat, 21 Mar 2015 11:09:28 +0000

On 20 Mar 2015, at 19:39, Scott Christley <schristley@mac.com> wrote:
> 
> Hello,
> 
> This is more a generic Objective-C question versus GNUstep but maybe some 
> experts here have a suggestion.
> 
> I have a bunch of code that looks l like this:
> 
> 
>   if ([encode isEqual: [BioSwarmModel floatEncode]]) {
>     // interpret as float matrix
>     float (*grid)[height][width] = matrix;
>     for (i = 0;i < height; ++i)
>         for (j = 0;j < width; ++j)
>             (*grid)[i][j] = 0.0;
> 
>   } else if ([encode isEqual: [BioSwarmModel doubleEncode]]) {
>     // interpret as double matrix
>     double (*grid)[height][width] = matrix;
>     for (i = 0;i < height; ++i)
>       for (j = 0;j < width; ++j)
>           (*grid)[i][j] = 0.0;
>    }
> 
> 
> where I have a generic pointer void *matrix to some data, that I need to 
> interpret as a specific data type, generally either int, float or double.  
> The part I don’t like is that the operation is essentially identical 
> regardless of the data type, but I have to duplicate code in order to handle 
> it.  In this example, the code is just zero’ing out the data.  This can be a 
> pain for more complicated operations as I have to make sure I do the correct 
> changes to each code piece.  What I would like is just to write the code once 
> and have the compiler or whatever handle the data type for me:
> 
>     for (i = 0;i < height; ++i)
>       for (j = 0;j < width; ++j)
>           (*grid)[i][j] = 0.0;
> 
> So is there some new Objective-C feature that I’m unaware of which can do 
> this for me?

This sounds like a job for Objective-C++.  You'd write something like:

template<typename T>
void zero(T *grid, size_t width, size_t height)
{
    for (i = 0;i < height; ++i)
      for (j = 0;j < width; ++j)
          (*grid)[i][j] = (T)0;
}

And then:

  if ([encode isEqual: [BioSwarmModel floatEncode]]) {
     zero((float*)matrix, width, height);
  } else if ([encode isEqual: [BioSwarmModel doubleEncode]]) {
     zero((double*)matrix, width, height);
  }

Although, in this specific case, you'd actually just want to do 
bzero(height*width*sizeof(T)).  Use Objective-C for the introspection and C++ 
for the generic code.  Oh, and it appears that you're reimplementing part of 
the core Objective-C language here.  You might look at @encode().  For 
primitive types, all of the type encodings are single chars, so you can do a 
simple switch, like this:

switch(encoding)
{
        case @encode(double)[0]:
                zero((double*)matrix, width, height);
        case @encode(float)[0]:
                zero((float*)matrix, width, height);
}

When doing this kind of thing a lot, I generally wrap it in a macro.  Take a 
look at type_encoding_cases in libobjc2.  You'd simplify this code to:

switch(encoding)
{
#define APPLY_TYPE(type, name, capitalizedName, encodingChar) \
        case encodingChar:
                zero((type*)matrix, width, height);
#include "type_encoding_cases.h"
}

David




-- Sent from my STANTEC-ZEBRA




reply via email to

[Prev in Thread] Current Thread [Next in Thread]