[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
Re: data type polymorphism,
David Chisnall <=