[fusion] Accessing sequence elements at runtime

Hi there, is it somehow possible to access a sequence element at runtime? Just image you're reading some name value pairs from file and you would like them to assign them to a fusion sequences. This way I don't know they order the values are supplied. Is that possible? For example take the following code: #include <string> #include <algorithm> #include <functional> #include <vector> #include <boost/any.hpp> #include <boost/bind.hpp> #include <boost/fusion/sequence.hpp> using namespace std; using namespace boost; struct A {}; struct B {}; struct info { string name; any value_type; }; static info info_table[] = { { "A_Value", any( A() ) }, { "B_Value", any( B() ) } }; string& get_name( info& i ) { return i.name; } typedef fusion::map< fusion::pair< A , int > , fusion::pair< B , double > > seq_type; int _tmain(int argc, _TCHAR* argv[]) { // Image a file read has delivered the following name value pair. string name = "A_Value"; int a_value = 12; // Find the type of the supplied name info* p = find_if( &info_table[0] , &info_table[0] + 2 , bind( equal_to<string>() , bind( &get_name, _1 ) , name )); seq_type seq; // How to add the value to the supplied name?? } Christian

On 26/03/07, Christian Henning <chhenning@gmail.com> wrote:
Hi there, is it somehow possible to access a sequence element at runtime? Just image you're reading some name value pairs from file and you would like them to assign them to a fusion sequences. This way I don't know they order the values are supplied. Is that possible?
Christian
I'm not a Fusion expert...but looking at the documentation, I think you'll find that operations on sequences are non-mutating - i.e. you have to construct a new sequence from the old sequence, but inserting a replacement value for the type specifier you've just found - for example, if you've just found an A() and you're inserting a_value: seq = seq_type(make_pair<A>(a_value), at<B>(seq)); similarly, altering the B value would be seq = seq_type(at<A>(seq), make_pair<B>(b_value)); You'd obviously also need some sort of run-time dispatching to call the appropriate seq updating function. Stuart Dootson

Christian Henning wrote:
Hi there, is it somehow possible to access a sequence element at runtime?
You sure can. The 'at' function yields an L-value.
Just image you're reading some name value pairs from file and you would like them to assign them to a fusion sequences.
You must know the number of pairs you expect in advance (at compile time) to use the built-in Sequences that come with Fusion. Almost philosophical stuff: We have some (still undocumented) weaker Sequence Concepts that would (theoretically - not that I could see that this use case would make a lot of sense) allow you to turn an STL container into a Fusion sequence. Note however that Fusion-style iteration is terminated at compile time, so the sequence would be infinite and thus only work if evaluated lazily until the last element in the STL container.
This way I don't know they order the values are supplied. Is that possible?
For example take the following code:
<code> Sidenote: You might get into trouble calling constructors in static aggregate initialization (construction of 'any' objects in your code) if your code is compiled into a shared library. You might know already... Given an 'any' with the appropriate type and a Fusion 'map', you have to iterate the map (hand-coded on top of Fusion iterators, if you want to stop once you found what you're looking for) and check for typeid(typename first<elem>::type) == an_any.type() The other (possibly more efficient) alternative is to use 'switch' & 'case' but that isn't very flexible, unless you can automatically generate a 'switch' cascade, see http://article.gmane.org/gmane.comp.lib.boost.devel/153870 for further reading. Regards, Tobias
participants (3)
-
Christian Henning
-
Stuart Dootson
-
Tobias Schwinger