views:

76

answers:

1

I'm looking for a hybrid meta-container/container class. I want a class that maps a compile-time type to a runtime value. A code snippit is worth 1024 words so:

struct Foo { /* ... */ };
struct Bar { /* ... */ };

int main()
{
   meta_container<Foo,float,int> mc;
   mc.get<float>() = 1.0f;
   mc.get<Foo>().method(blah);
   mc.get<Bar>(); //compiler error
}

This is really boring stuff. An implementation using variadic templates would be interesting enough but the interface is very simple.

The part that makes this more difficult is this last feature I want.

void foo( const meta_constainer<Foo,Bar,Baz>& mc );

//make_mc is sorta like make_pair or make_tuple.

int main()
{
   foo( make_mc(Foo(), Bar(), Baz()) );  // not really interesting
   foo( make_mc(Bar(), Foo(), Baz()) );  // this is more challenging
   foo( make_mc(Foo()) );  // this might be difficult as well.
}

I could write such a container, but I'd like to find one that's already written/debugged. My biggest stumbling block has been lack of good keywords to search for (heterogeneous container is not what I want).

Is there a Boost library that has this or a similar interface?

What is this thing called, so I can google it more effectively?


update:

I am not looking for:

  • boost::mpl::map
    This maps a compile-time value to a compile-time value
  • std::map<*,boost::any>
    This maps a static type runtime value to a dynamic type runtime value
  • std::map<*,boost::variadic<*>>
    This maps a static typed runtime value to a variable type runtime value
  • std::map<typeid,boost::variadic<*>>
    This is close to what I want except that it uses RTTI and it is not a compile error if accessed with the wrong type.
+1  A: 

boost::fusion : http://www.boost.org/doc/libs/1_44_0/libs/fusion/doc/html/index.html

Nim
`boost::fusion::set` does more than I want and less, but it is the best I've seen so far. It requires ordering of parameters, so my unordered list example won't work.
caspin
hmm, I would have thought fusion::vector is what you're looking for? you could combine that with an enum to achieve what you require?
Nim
`fusion::set` allows me to map `int` to an integer value, and `float` to a float value. `fusion::vector` maps compile-time `0` to an integer value and compile-time `1` to a float value. I could make an auxiliary mapping between the `0`,`1` constants and `int`,`float`, but `fusion::set` does that for me already.
caspin
I guess the only downside is that, you cant have the same type occurring multiple times, but if you don't need that, then set is fine...
Nim