Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > design - class to represent a variable

Reply
Thread Tools

design - class to represent a variable

 
 
bartek
Guest
Posts: n/a
 
      05-20-2004
Hello,

I've been pondering with this for quite some time now, and finally
decided to ask here for suggestions. I'm kind of confused, actually...
Maybe I'm thinking too much...

Brain dump follows...

I need a class to represent a variable, with an associated data type
and/or value. Though, I don't want it to be a variant type, and not a
'convenience' class either.

The variable objects will be used in variable lists (a'la symbol tables),
so they are going to be polymorphic.

Now to the point...

The variable type is determined by the following factors:
1. raw data type (int, float, string, etc...)
2. array width (if it's an array of p.1)
3. storage class modifier

My dilemma concerns the actual design of the way how to access those
variables in different parts of the system.

The lists of variables are used in quite different situations.
For example, in generating function prototypes (type declarations),
carrying actual data around the system, translating data coming from
external sources.

The above requirements are pushing me towards a consequent use of the
visitor pattern. Though, I'm completely puzzled on how to apply visitor
to a type which is determined by 3 factors (as shown above).

It all seems as a total maintenance disaster at the moment...

THE Question:
Is there a simple way (or a way to simplify) such a case of three-way-
visitation?

Should I go for explicit definition of each type?

E.g.

Given types Int and Float, and storage classes Uniform and Varying,
define every possible combination of data type, array specifier, and
storage class modifier. ouch!

class Variable ... // the root

class UniformInt : public Variable ...
class UniformIntArray : public Variable ...
class VaryingInt : public Variable ...
class VaryingIntArray : public Variable ...
class UniformFloat : public Variable ...
etc...

Maybe I could nest it in some way?

E.g.

class StorageSpec ... // root

class Uniform : public StorageSpec ...
class Varying : public StorageSpec ...

class Variable ... // root

class Float : public Variable {
StorageSpec* m_storage_spec;
};
etc...

Or maybe the other way around, that is - embed data type in a storage
class?

I'm aware that it's impossible to help me with so small amount of
information given. Though I hope you can give me some references to
whatever medium, where a remotely similar problem is solved.

Thanks for your time.

Cheers.
 
Reply With Quote
 
 
 
 
Derek
Guest
Posts: n/a
 
      05-20-2004
What exactly are you writing? I'm curious because I'm
working on a very similar problem.
 
Reply With Quote
 
 
 
 
bartek
Guest
Posts: n/a
 
      05-20-2004
Derek <(E-Mail Removed)> wrote in news:(E-Mail Removed):

> What exactly are you writing? I'm curious because I'm
> working on a very similar problem.


Actually it's going to be a part of an application utilizing Renderman
interface. I'd like to represent RI variable specifications in C++ classes
following consequent OO practices. *cough* *cough*

 
Reply With Quote
 
Derek
Guest
Posts: n/a
 
      05-20-2004
> > What exactly are you writing? I'm curious because I'm
> > working on a very similar problem.

>
> Actually it's going to be a part of an application
> utilizing Renderman interface. I'd like to represent
> RI variable specifications in C++ classes following
> consequent OO practices. *cough* *cough*


That's what I thought. I just started a little RenderMan
project myself (yet another RenderMan-compliant renderer).
It's very new and I can barely render a sphere at this
point, but I've been thinking ahead about how to implement
RI variables.

I've started peeking at open-source renderers to see how
they handle variables (Aqsis and Pixe are both C++), but I
haven't come up with a definitive design yet.

Let me know if you come up with a cool design. My email
address is "derek AT networld DOT com" if you want to
compare notes sometime.
 
Reply With Quote
 
Derek
Guest
Posts: n/a
 
      05-20-2004
I'm not sure you want to deal with the combinatorial
explosion of using the visitor pattern. After all,
there are 5 storage classes (constant, uniform,
varying, facevarying, and vertex) and 10 types
(float, integer, vector, color, normal, point, matrix,
double, hpoint, and string). And each combination
can be a scalar or an array. Yikes!

I propose a very simple strucutre (off the top of my
head):

class Variable
{
public:
//...
private:
std::string m_varName;
StorageType m_storageType;
DataType m_dataType;
int m_arrayLength;
int m_elementLength;
std::vector<float> m_data;
};

Now your algorithms can 'switch' based on type type if
they have to. I think you will find that many operations
(e.g., linear interpolation) don't care about the type
at all.

Perhaps the only wrinkle is that string variables can't
be stored very efficiently in a vector<float> and should
probably be treated separately.
 
Reply With Quote
 
bartek
Guest
Posts: n/a
 
      05-20-2004
Derek <(E-Mail Removed)> wrote in news:(E-Mail Removed):

> I'm not sure you want to deal with the combinatorial
> explosion of using the visitor pattern. After all,
> there are 5 storage classes (constant, uniform,
> varying, facevarying, and vertex) and 10 types
> (float, integer, vector, color, normal, point, matrix,
> double, hpoint, and string). And each combination
> can be a scalar or an array. Yikes!


That's exactly the point.
Having such huge visitors seemed like a bad idea.
On the other hand, visitor guarantees that every subtype will be serviced
individually in the code.

> I propose a very simple strucutre (off the top of my
> head):
>
> class Variable
> {
> public:
> //...
> private:
> std::string m_varName;
> StorageType m_storageType;
> DataType m_dataType;
> int m_arrayLength;
> int m_elementLength;
> std::vector<float> m_data;
> };
>
> Now your algorithms can 'switch' based on type type if
> they have to. I think you will find that many operations
> (e.g., linear interpolation) don't care about the type
> at all.


I've been considering a similar design, except that the main data was
separated into respective derived classes.

That is:

class Variable {
std::string m_name;
StorageType m_storage_type;
int m_size; // ==0 : scalar, >0 - array
public:
virtual void AcceptVisitor(Visitor&) const = 0;
// ... accessors, etc.
};

class FloatVariable : public Variable {
std::vector<float> m_data;
public:
//...
};

class StringVariable : public Variable {
std::vector<std::string> m_data;
public:
//...
};

// etc...

This way, I could dispatch based on the actual data type, and use
conditionals for the storage type and/or array specification.

But then ... I'd probably end up with such conditionals in every visitor,
which is kind of contradictory to the whole design. Why bother with
visitor at all when there will be switches everywhere, anyway?

On the other hand, considering the fact that the storage specifier is
only giving a new meaning for array dimensions, I thought about turning
it into a kind of templated policy class, which would only determine the
algorithms for operations on the data regardless of the type...

E.g.

// only one element to copy
struct UniformStorage {
template <class IterT>
static void Copy(IterT to, IterT from)
{ *to = *from; } // just one value to copy here
// ...
};

// nvertices elements to copy
class VaryingStorage {
int m_nvertices;
public:
VaryingStorage(int nvertices) : m_nvertices(nvertices) { }
template <class IterT>
static void Copy(IterT to, IterT from) {
for (int i=0; i!=m_nvertices; ++i) {
*to = *from;
++to; ++from;
}
}
};

And then use those policies as template arguments for FloatVariable et
al.

This technique, however, rules out the GOF style visitation, because
virtual functions cannot be templates.
Unless all templates are given explicitly...

// in visitor
virtual void Visit(FloatVariable<UniformStorage> const&)
//...

So here we go back to the huge-visitor maintenance problem, because every
possible combination of variable with storage class must be given
explicitly...

Uhh too much coffee I guess...

Cheers
 
Reply With Quote
 
Derek
Guest
Posts: n/a
 
      05-21-2004
Your logic is all too familiar; I've gone 'round and
'round with the same thoughts. The biggest problem is
that I'm not really sure what operations I will need
to perform on RI variables. That is, I'm not convinced
that I will really have to switch based on type in all
THAT many places. I really think in many cases all
numerical data can be treated uniformly regardless of
type. In that case a simple one-class solution with a
few switch statements here and there is probably the
best way to go. If I'm wrong, however, and I need to
switch all over the place, I will revisit a polymorphic
solution with visituation. Either way, I'm still a few
weeks away from having to worry about it. Good luck.
 
Reply With Quote
 
bartek
Guest
Posts: n/a
 
      05-21-2004
Derek <(E-Mail Removed)> wrote in news:(E-Mail Removed):

> Your logic is all too familiar; I've gone 'round and
> 'round with the same thoughts. The biggest problem is
> that I'm not really sure what operations I will need
> to perform on RI variables. That is, I'm not convinced
> that I will really have to switch based on type in all
> THAT many places. (...)


You're right. I guess I'm just trying too hard.

But still, I'm curious how do others handle similar design issues.

Cheers.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to represent '&' as a variable in xslt file ofuuzo1@yahoo.no XML 3 04-18-2008 03:36 PM
Predefined variable to represent the ruby installation path? Olivia Dou Ruby 3 12-13-2006 01:19 PM
A design problem: how to represent resource id's Alf P. Steinbach C++ 9 05-01-2006 10:59 PM
using a variable to represent a textboxname TB ASP .Net 2 03-06-2006 10:33 AM
XML Document Design to represent a Heirarchy Trevor Andrew XML 0 07-21-2003 05:33 AM



Advertisments