Ann Huxtable said:
I'm writing a "Table" class which mimics a table returned in an SQL
query. The only difference is that in my table, I want to be able to
nest tables within tables - so some columns will contain other table.
To answer your question regarding whT i'm trying to achieve, the
templated functions above are retriving the values stored in a cell. The
cell is currently implemented as a union (although I may change to the
Boost variant type at a later stage). The cell can store one of the
following types:
char*
int,
double
void * //To allow nesting
Cells are referenced by (row,col) where each of the parameters could
either be a string (name) or int (index). This permutated with the large
number of possible return variables will result in 4*4 = 16 functions
just to get a value, and then another 16 to set a value - and this is
not easily extensible if I need to store other variable types. Hence my
post.
If you have any ideas as to how to solve this problem, I'd be willing to
hear them. Tks
Now, what you described is indeed three problems: input types, output types,
and extensibility. Let's take them apart:
You are looking for int-int, int-string, string-int, string-string pairs as
input type and are looking for extensibility, if I correctly understand your
post. The ideal way is to use the C++ type system to help you. What's in my
mind is a single concept for locating a cell, say, cell_entry:
class cell_entry_base
{
protected:
cell_entry_base();
// whatever you need to know to locate a cell
};
// map to col-row pair types
template <typename ColT, typename RowT>
class cell_entry;
// specialize for <int, int>
template <> class cell_entry<int, int>: public cell_entry_base
{
//...
};
// also specialize for <int, string>, <string, int> and <string, string>
//...
// also specialize for other types you wish, extending made easy...
Now the output type. You need to map a set of C++ type to the internal types
supported by the database, if I am still on the track. So I came up with
traits:
template <typename T>
class entry_type_trait;
template <> class entry_type_trait<char*>
{
public:
static char* get_value(cell_entry_base&) throw (bad_type)
{
// your database access code here,
// throw bad_type if type not matched
}
//... more ops up to you
};
// also specialize for <int> <double> and <void*>
// ...
Note that you only have to add a new specialization to extend the type
mapping. And finally the function getValue can be trivially implemented:
template <typename ReturnT, typename ColT, typename RowT>
ReturnT getValue(ColT col, RowT row) throw (bad_type)
{
cell_entry<ColT, RowT> entry(col, row); // enforce input types
return entry_type_trait<ReturnT>::get_value(entry); // output
types
}
Regards,
Ben