Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Loki Typelists help 1

Status
Not open for further replies.

fcouderc

Programmer
Dec 2, 2003
9
0
0
CA
Hi to all.

I'm trying to use typelists of the Loki Library. It works fine but I need an additional feature and I don't know if it is feasable.

You can access typelist's elements with an index like the following.

Field<0>(myTypelist);

Unfortunately the index has to be known at compile-time. Is there a way to use an index not know at compile-time.
ie,
int index = 5;
Field<index>(myTypelist);

Can someone help me out please? :eek:)

Thanks for your help.

Frank
 
No.

The whole purpose of Loki's typelists is to be used as a compile-time tool. It wouldn't make sense to get a type at run time. What could you do with it? You can no longer declare anything at run time. In a sense, types don't even exist anymore at that point.

What do you need this feature for?
 
Hi,

Ok, here's the context. The main purpose is to optimize our processing in an observer pattern. We wanted to have a mechanism to avoid doing costly searches in a map of observers. As you know, searching in a map costs O(n). Upon modification of a variable we need to look in the map to see if there is observers for this variable and then notify them. Since we can afford space but need to achieve high performance, we thought we could put a boolean field for each of our variables. Also do macros that would automatically create this boolean field, check and set its value without the developer coding it. But to do it automatically you need to know where it is. So writing the following:

struct myStruct
{
int DEFVAR(iField1);
double DEFVAR(dField2);
int DEFVAR(iField3);
};
would create:
struct myStruct
{
bool b_iField1;
int iField1;
bool b_iField2;
double dField2;
bool b_iField3;
int iField3;
};

So with a macro SET(var, value) I can check automatically if the bool is true and then call inform other observers. That way, I managed to save processing time because the majority of the time, there will be no observers.

The problem is that you can`t only do &iField1 - sizeof(bool) to automatically reference the boolean field because of alignment issues. You cannot be sure if it will be just beside. And using the PACKED keyword is very unefficient since the processor needs more instructions to load the data. And the keyword here is performance...

So this takes us to the typelists. Using typelists we could define something like...
// Create a holder
template <class T>
struct Holder
{
T value;
bool b_observed;
};

// Create a typelist.
typedef GenScatterHierarchy<
TYPELIST_4(int,double,int),
Holder>
VariablesList;

VariableList myList;

So when we modify the value of a variable we automatically have the bool associated with it. So the SET macro would create something like

Field<0>(l_myList).value = 4;
if (Field<0>(l_myList).b_observed == true)
{
inform(.....);
}

This actually works until you want to have variable indexes like
void foo(int variableNumberToModify)
{
Field<variableNumberToModify>(l_myList).value = 4;
if (Field<variableNumberToModify>(l_myList).b_observed == true)
{
inform(.....);
}
}

So that`s why we would need to have the possibility to have variable indexes. In fact, we only want to create a container for values of different types.

I thought it could be possible. I've looked into loki`s code but I have limited capability with template programming. :eek:( And besides, if someone knows somebody of code provide an advance templated/meta-programming course I would like to know. Are currently seeking a C++ template specialist to give my team a training.

If you have an idea, feel free to send it, I'd be more than glad to discuss it. ;o)

Have a nice day.

Frank
 
Why not:

Code:
  template< class T >
class Observed
{
  public:
    const Observer& operator=( const T& rhs )
    {
        value_ = rhs;
        if ( observed_ ) inform(...);
    }

    //Maybe...
    operator T() { return value_; }

  private:
    T value_;
    bool observed_;
};

Then:

Code:
struct myStruct
{
    Observed<int>    iField1;
    Observed<double> dField2;
    Observed<int>    iField3;
};

myStruct foo;

foo.iField1 = 7;
foo.dField2 = 55.83;
etc...

Is that bad performance-wise?


Also, why not create a hash code for your observers and store them in a hash map instead?
 
Hi,

Why make it simple when it can be complicated! :eek:)

I am a bit ashamed that I did'nt think about this before. It's simple and efficient.

After looking at it and making some tests we have managed to make it work. One thing that I had not mentionned is that the variable struct will be instanciated in a shared memory region. This means that the template class has to be POD. But we can manage to fit with the ISO standard to make it POD. (Basically, no copy constructor, no user-defined constructor, etc.)

For the hash map, it does perform well in a context where your map's index keys are not very grouped togheter... ie, 1, 5000, 45, ... In our case, we would have key indexes like 1 to 20. So It won`t give us much more performance I think.

Thanks for your help. You have provided me with very helpful hints over the last few days. You seem very knowledgable. Out of curiosity, what do you do, who do you work for if that`s not to much to ask?

Frank
 
> Assuming that your implementation obeys the complexity rules of the STL... it should only take O(log(N)) time shouldn't it?

Yup.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top