472,989 Members | 2,919 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,989 software developers and data experts.

How to avoid runtime switch/case code based on data type?

Hi Group, I've got a problem I couldn't find a good solution. I am
working with scientific data files in netCDF format. One of the
properties of netCDF data is that the actual type of data is only known
at run time. Therefore a lot of template based trick isn't too useful.
Considering

datafile
float x(3) 3.5, 2.5, 8.9
double y(3) 2.7, -2.3, 1.2
int z(3) 5, 2, 3

Suppose in my code, I need to write a summation function and return the
result, I could do

template <class T>
T sum(T * data, size_t n);

This is all good and dandy, but in the calling subroutine I am stuck
because at compile I have no priori knowledge of actual data type
contained in the data file, thus I must rely on switch/case code based
on what may be contained in the data file during run time. Consider:

void sum_caller(){
mytype type = datafile.getline(i).type
switch(type){
case float_type:
float ret = sum(datafile.getline(i).data);
do_something(ret);
case double_type:
float ret = sum(datafile.getline(i).data);
...
....
}

I cannot declare 'template <class T> void sum_caller();' because only
within sum_caller, the type information is available. (you could argue
I can declare sum_caller template based, but that's not the point. At
some point, the type information becomes available and appropriate
action can be taken). Is there a design pattern or implementation
strategy that can help me with this dilemma and thus avoid switch/case
based code altogether? Thanks!

Mar 3 '06 #1
13 4459
Fei Liu wrote:
Hi Group, I've got a problem I couldn't find a good solution. I am
working with scientific data files in netCDF format. One of the
properties of netCDF data is that the actual type of data is only known
at run time. Therefore a lot of template based trick isn't too useful.
Considering

datafile
float x(3) 3.5, 2.5, 8.9
double y(3) 2.7, -2.3, 1.2
int z(3) 5, 2, 3

Suppose in my code, I need to write a summation function and return the
result, I could do

template <class T>
T sum(T * data, size_t n);

This is all good and dandy, but in the calling subroutine I am stuck
because at compile I have no priori knowledge of actual data type
contained in the data file, thus I must rely on switch/case code based
on what may be contained in the data file during run time. Consider:

void sum_caller(){
mytype type = datafile.getline(i).type
switch(type){
case float_type:
float ret = sum(datafile.getline(i).data);
do_something(ret);
case double_type:
float ret = sum(datafile.getline(i).data);
...
...
}

I cannot declare 'template <class T> void sum_caller();' because only
within sum_caller, the type information is available. (you could argue
I can declare sum_caller template based, but that's not the point. At
some point, the type information becomes available and appropriate
action can be taken). Is there a design pattern or implementation
strategy that can help me with this dilemma and thus avoid switch/case
based code altogether? Thanks!


Check out chapter 8 of _Modern C++ Design_ by Andrei Alexandrescu. A
Loki factory is intended to fill just such a gap and will likely do
what you need (well, with a little effort on your part). You can get
the latest source code for it from

http://sourceforge.net/projects/loki-lib/

Cheers! --M

Mar 3 '06 #2
On 2006-03-03, Fei Liu <fe*****@gmail.com> wrote:
Hi Group, I've got a problem I couldn't find a good solution. I am
working with scientific data files in netCDF format. One of the
properties of netCDF data is that the actual type of data is only
known at run time. Therefore a lot of template based trick isn't too
useful. Considering

datafile
float x(3) 3.5, 2.5, 8.9
double y(3) 2.7, -2.3, 1.2
int z(3) 5, 2, 3


It looks like you need a parser, rather, and it's already been
written. A visit to the CVS repository for NCO seems like the best
place to start.

--
Neil Cerutti
I pulled into a lay-by with smoke coming from under the bonnet.
I realized the car was on fire so took my dog and smothered it
with a blanket. --Insurance Claim Blooper
Mar 3 '06 #3

Neil Cerutti wrote:
On 2006-03-03, Fei Liu <fe*****@gmail.com> wrote:
Hi Group, I've got a problem I couldn't find a good solution. I am
working with scientific data files in netCDF format. One of the
properties of netCDF data is that the actual type of data is only
known at run time. Therefore a lot of template based trick isn't too
useful. Considering

datafile
float x(3) 3.5, 2.5, 8.9
double y(3) 2.7, -2.3, 1.2
int z(3) 5, 2, 3


It looks like you need a parser, rather, and it's already been
written. A visit to the CVS repository for NCO seems like the best
place to start.

--
Neil Cerutti
I pulled into a lay-by with smoke coming from under the bonnet.
I realized the car was on fire so took my dog and smothered it
with a blanket. --Insurance Claim Blooper


How does a parser solve my problem?

Mar 3 '06 #4
Fei Liu wrote:
Hi Group, I've got a problem I couldn't find a good solution. I am
working with scientific data files in netCDF format. One of the
properties of netCDF data is that the actual type of data is only
known at run time. Therefore a lot of template based trick isn't too
useful. Considering

datafile
float x(3) 3.5, 2.5, 8.9
double y(3) 2.7, -2.3, 1.2
int z(3) 5, 2, 3


mlimber's loki suggestion might work.

In general, faced with A> a boundary between the outside world and a
program, and B> a switch based on type codes, you need polymorphism. Create
a Class Factory that converts each typed object into a wrapper object with
virtual methods. Return a reference to an abstract base class declaring
those methods, and call them. Each one will convert the data in its own
special way, and the calling code can be very clean.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Mar 3 '06 #5
In general, faced with A> a boundary between the outside world and a
program, and B> a switch based on type codes, you need polymorphism. Create
a Class Factory that converts each typed object into a wrapper object with
virtual methods. Return a reference to an abstract base class declaring
those methods, and call them. Each one will convert the data in its own
special way, and the calling code can be very clean.


What would be the right 'search term' - if you will for this. I'd like
to look this up on the web (find an example or two), since I tend to go
the switch route on a continuum. In my heart of hearts I know there's
a polymorphic solution.

Mar 3 '06 #6
In general, faced with A> a boundary between the outside world and a
program, and B> a switch based on type codes, you need polymorphism. Create
a Class Factory that converts each typed object into a wrapper object with
virtual methods. Return a reference to an abstract base class declaring
those methods, and call them. Each one will convert the data in its own
special way, and the calling code can be very clean.


What would be the right 'search term' - if you will for this? I'd like
to look this up on the web (find an example or two), since I tend to go
the switch route on a continuum. In my heart of hearts I know there's
a polymorphic solution.

Mar 3 '06 #7
ma740988 wrote:
What would be the right 'search term' - if you will for this?


http://www.google.com/search?q=factory+pattern

http://www.google.com/search?q=repla...h+polymorphism

Some consider that last one the heart of OOP.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Mar 3 '06 #8
In article <11*********************@i40g2000cwc.googlegroups. com>,
"Fei Liu" <fe*****@gmail.com> wrote:
Hi Group, I've got a problem I couldn't find a good solution. I am
working with scientific data files in netCDF format. One of the
properties of netCDF data is that the actual type of data is only known
at run time. Therefore a lot of template based trick isn't too useful.
Considering

datafile
float x(3) 3.5, 2.5, 8.9
double y(3) 2.7, -2.3, 1.2
int z(3) 5, 2, 3

Suppose in my code, I need to write a summation function and return the
result, I could do

template <class T>
T sum(T * data, size_t n);

This is all good and dandy, but in the calling subroutine I am stuck
because at compile I have no priori knowledge of actual data type
contained in the data file, thus I must rely on switch/case code based
on what may be contained in the data file during run time. Consider:

void sum_caller(){
mytype type = datafile.getline(i).type
switch(type){
case float_type:
float ret = sum(datafile.getline(i).data);
do_something(ret);
case double_type:
float ret = sum(datafile.getline(i).data);
...
...
}

I cannot declare 'template <class T> void sum_caller();' because only
within sum_caller, the type information is available. (you could argue
I can declare sum_caller template based, but that's not the point. At
some point, the type information becomes available and appropriate
action can be taken). Is there a design pattern or implementation
strategy that can help me with this dilemma and thus avoid switch/case
based code altogether? Thanks!


Switch statements are not evil, what is evil is having multiple switch
statements in your code, all switching based on the same type
information. If you have that, then create an ABC, use one switch to
create the derived object and don't worry about it. KISS
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 3 '06 #9
Howdy Daniel,
Switch statements are not evil, what is evil is having multiple switch
statements in your code, all switching based on the same type
information. If you have that, then create an ABC, use one switch to
create the derived object and don't worry about it. KISS

"KISS". Indeed. I think though I mirror the multiple switch statement
based on same type information you alluded to. So now consider an
enumerated type with a list of algorithms'.

enum algorithm_type { BEM, IFFT, FFT, INVALID = -1 };

This type forms is part of a composite type such that:
struct algorithm_details {
// stuff
// later
algorithm_type pcp_type;
};

Upon receipt of the header (+ data) from an external source, I do:
switch ( algorithm_type )
{
case BEM : // perform field compuations on the data using
Maxwells equations.
break;
case IFFT: // do an inverse FFT
break;
case FFT: // do an FFT
};
etc.

Something tells me that a more viable solution would be as follows:
class algorithm {
public: algorithm() {}
virtual void do_bem( /*whatever */ ) = 0;
// and so on.
};

// later
class foo : public algorithm {
public:
foo () : algorithm() {}
void do_bem( /* whatever */ ) {}
~virtual foo { void cleanup(); }
void cleanup () { /* what goes up must come down - tear down */ }
};

Ultimately what it amounts to is the mathematics ( matrix mess ) is so
involved that your 'case statements ' becomes large. Of ocurse the
alternative is to call member functions based on the type. In any
event, I think you see where I'm going .. Your thoughts.

Mar 4 '06 #10
In article <11**********************@j33g2000cwa.googlegroups .com>,
"ma740988" <ma******@gmail.com> wrote:
Howdy Daniel,
Switch statements are not evil, what is evil is having multiple switch
statements in your code, all switching based on the same type
information. If you have that, then create an ABC, use one switch to
create the derived object and don't worry about it. KISS

"KISS". Indeed. I think though I mirror the multiple switch statement
based on same type information you alluded to. So now consider an
enumerated type with a list of algorithms'.

enum algorithm_type { BEM, IFFT, FFT, INVALID = -1 };

This type forms is part of a composite type such that:
struct algorithm_details {
// stuff
// later
algorithm_type pcp_type;
};

Upon receipt of the header (+ data) from an external source, I do:
switch ( algorithm_type )
{
case BEM : // perform field compuations on the data using
Maxwells equations.
break;
case IFFT: // do an inverse FFT
break;
case FFT: // do an FFT
};
etc.

Something tells me that a more viable solution would be as follows:
class algorithm {
public: algorithm() {}
virtual void do_bem( /*whatever */ ) = 0;
// and so on.
};

// later
class foo : public algorithm {
public:
foo () : algorithm() {}
void do_bem( /* whatever */ ) {}
~virtual foo { void cleanup(); }
void cleanup () { /* what goes up must come down - tear down */ }
};

Ultimately what it amounts to is the mathematics ( matrix mess ) is so
involved that your 'case statements ' becomes large. Of ocurse the
alternative is to call member functions based on the type. In any
event, I think you see where I'm going .. Your thoughts.


The problem is, you have the header (+data) from an external source. In
order to use a virtual method on a base class you first need to make an
object of some derived class. The type of object you need to make is
based on the very type your doing the switch on anyway.

In other words, you must do at least one switch on the type (either to
do the calculation or create the object.) It's having more than one
switch on type that could be a problem.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 4 '06 #11

Daniel T. wrote:
In article <11**********************@j33g2000cwa.googlegroups .com>,
"ma740988" <ma******@gmail.com> wrote:
Howdy Daniel,
Switch statements are not evil, what is evil is having multiple switch
statements in your code, all switching based on the same type
information. If you have that, then create an ABC, use one switch to
create the derived object and don't worry about it. KISS
"KISS". Indeed. I think though I mirror the multiple switch statement
based on same type information you alluded to. So now consider an
enumerated type with a list of algorithms'.

enum algorithm_type { BEM, IFFT, FFT, INVALID = -1 };

This type forms is part of a composite type such that:
struct algorithm_details {
// stuff
// later
algorithm_type pcp_type;
};

Upon receipt of the header (+ data) from an external source, I do:
switch ( algorithm_type )
{
case BEM : // perform field compuations on the data using
Maxwells equations.
break;
case IFFT: // do an inverse FFT
break;
case FFT: // do an FFT
};
etc.

Something tells me that a more viable solution would be as follows:
class algorithm {
public: algorithm() {}
virtual void do_bem( /*whatever */ ) = 0;
// and so on.
};

// later
class foo : public algorithm {
public:
foo () : algorithm() {}
void do_bem( /* whatever */ ) {}
~virtual foo { void cleanup(); }
void cleanup () { /* what goes up must come down - tear down */ }
};

Ultimately what it amounts to is the mathematics ( matrix mess ) is so
involved that your 'case statements ' becomes large. Of ocurse the
alternative is to call member functions based on the type. In any
event, I think you see where I'm going .. Your thoughts.


The problem is, you have the header (+data) from an external source. In
order to use a virtual method on a base class you first need to make an
object of some derived class. The type of object you need to make is
based on the very type your doing the switch on anyway.


This is the gist of the problem. Things are not known at compile time
and variables of proper type can only be declared at run time based on
external information... In other words, you must do at least one switch on the type (either to
do the calculation or create the object.) It's having more than one
switch on type that could be a problem.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.


Mar 4 '06 #12
>
The problem is, you have the header (+data) from an external source. In
order to use a virtual method on a base class you first need to make an
object of some derived class. The type of object you need to make is
based on the very type your doing the switch on anyway.


This is the gist of the problem. Things are not known at compile time
and variables of proper type can only be declared at run time based on
external information...
In other words, you must do at least one switch on the type (either to
do the calculation or create the object.) It's having more than one
switch on type that could be a problem.

Thanks. By the way Fei, I might have overstepped my bounds there. In
that Daniel wasn't responding to me but for some reason I didn't
realize that until after it's too late.

My apologies.

Mar 5 '06 #13
On 2006-03-03, Fei Liu <fe*****@gmail.com> wrote:

Neil Cerutti wrote:
On 2006-03-03, Fei Liu <fe*****@gmail.com> wrote:
> Hi Group, I've got a problem I couldn't find a good solution. I am
> working with scientific data files in netCDF format. One of the
> properties of netCDF data is that the actual type of data is only
> known at run time. Therefore a lot of template based trick isn't too
> useful. Considering
>
> datafile
> float x(3) 3.5, 2.5, 8.9
> double y(3) 2.7, -2.3, 1.2
> int z(3) 5, 2, 3


It looks like you need a parser, rather, and it's already been
written. A visit to the CVS repository for NCO seems like the best
place to start.

--
Neil Cerutti
I pulled into a lay-by with smoke coming from under the bonnet.
I realized the car was on fire so took my dog and smothered it
with a blanket. --Insurance Claim Blooper


How does a parser solve my problem?


Never mind me. I misunderestimated the problem. Sorry.

--
Neil Cerutti
Women's Luncheon: Each member bring a sandwich. Polly Phillips
will give the medication. --Church Bulletin Blooper
Mar 6 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Dave | last post by:
Hello all, I am creating a linked list implementation which will be used in a number of contexts. As a result, I am defining its value node as type (void *). I hope to pass something in to its...
9
by: Jon Rea | last post by:
I hav been looking for the last 2 hours on how to do this without much luck. Im going to give a simplifed model of the problem i have. I want a collection class that can holds a series or...
3
by: pgraeve | last post by:
I am a convert from VB to C# so bear with me on this "conversion" question C# switch statement seems to be the closest relative to VB's Select Case. I used VB's Select Case statement liberally. ...
19
by: rdavis7408 | last post by:
Hello, I have four textboxes that the user enters the price per gallon paid at the pump, the mileage per gallon and I would like to then calculate the cost per gallon and use a switch statement to...
12
by: leaf | last post by:
Hi, How to call function at runtime, based on a struct that contains the information for the function call: struct func_to_call { int function_id; // function id to call unsigned int nparams;...
18
by: John Friedland | last post by:
My problem: I need to call (from C code) an arbitrary C library function, but I don't know until runtime what the function name is, how many parameters are required, and what the parameters are. I...
2
by: Angel Of Death | last post by:
I have a method. It takes some XML as a parameter. Depending on the content of the XML it should create a specific object and call a KNOWN method. So: public void PersistXml(string XmlData){} ...
18
by: desktop | last post by:
I have 3 types of objects: bob1, bob2 and bob3. Each object is identified by a unique ID which gets returned by the function getId(). All bobs are descendants from class BaseBob which is an...
9
by: Dhiru1009 | last post by:
Hi guys, I am trying to build a user registration form using PHP and MYSQL but encountring a problem. When I click on submit with empty fields it adds records to database also it doesn't matter...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.