
Hi, I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example: given the tuple boost::tuple<type1, type2, type3> get<type1> returns the first element of the tuple of that type. This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example 'get<3>(get<5>(get<0>(my_tuple)))' looks more like line noise than real code :). I use type wrappers to wrap built-in types and give them unique names (a typedef that creates unique objects instead of aliases would be really useful here!). Anyway, here is my code. It is really a quick hack, i probably did get returns type wrong (probably works only for value type elements), and I'm sure metaprogramming experts here can do much better. namespace detail { namespace mpl = boost::mpl; template <typename Tuple, typename Type, int Index> struct traverse { typedef typename ::boost::tuples::element<Index, Tuple>::type this_type; typedef typename mpl::if_ <boost::is_same <this_type, Type>, mpl::int_<Index>, typename traverse<Tuple, Type, Index-1>::type >::type type; }; template<typename Tuple, typename Type> struct traverse <Tuple, Type, -1> { typedef boost::mpl::int_ <boost::tuples::length<Tuple>::value> type; }; template <typename Tuple, typename Type> class index_of_type { public: typedef typename traverse<Tuple, Type, boost::tuples::length<Tuple>::value-1>::type type; }; } template <typename Type, typename Tuple> Type& get(Tuple& tp) { typedef typename detail::index_of_type<Tuple, Type>::type index; return boost::tuples::get<index::value>(tp); } template <typename Type, typename Tuple> const Type& get(const Tuple& tp) { typedef typename detail::index_of_type<Tuple, Type>::type index; return boost::tuples::get<index::value>(tp); } }

On 04/26/2005 04:18 AM, Giovanni P. Deretta wrote:
Hi,
I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example:
given the tuple boost::tuple<type1, type2, type3>
get<type1> returns the first element of the tuple of that type.
This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example 'get<3>(get<5>(get<0>(my_tuple)))' looks more like line noise than real code :).
Of course this wouldn't work for this tuple: tuple<type1, type1, type3> Maybe if there were some way of associating an enumeration with the tuple, you could: get<f_i>(my_tuple) where fi is some enumerator in, e.g.: enum my_tuple_fields { f_0 , f_1 ... , f_n }; but even then, with nested tuples, there's a possible name conflict amoung the enumerators. Possibly the enumerator names could contain a prefix indicating to which type they belong: enum type0_fields { t0_f_0 , t0_f_1 ... , t0_f_n0 }; enum type1_fields { t1_f_0 , t1_f_1 ... , t1_f_n1 }; Obviously more verbose than I think you want, but it would solve the problem of duplicate types. BTW, I haven't tried it; hence, there may be some flaws in the idea ;)

On 4/26/05, Larry Evans <cppljevans@cox-internet.com> wrote:
On 04/26/2005 04:18 AM, Giovanni P. Deretta wrote:
Hi,
I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example:
given the tuple boost::tuple<type1, type2, type3>
get<type1> returns the first element of the tuple of that type.
This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example looks more like line noise than real code :).
Of course this wouldn't work for this tuple:
tuple<type1, type1, type3>
Well, get<type1>(my_tuple) would return the first element of that type (actually my code will return the *last* element, but as I said, it was just a quick hack). Anyway, the get<type> form is most useful with tuples containing elements of different type. In practice you overload the meaning of the type to also be a an element tag. This way tuples become as powerful as structures: you can access element by "name". They are more powerful actually, as they have introspection capability: elements can be enumerated. Also the possibility of accessing tuple elements indipendently of the exact tuple type and element position can be very handy in generic programming. The get<type> form that i proposed can be easily added with zero changes to the existing tuple code/interface. A more complex addition would allow the association of a tag to each tuple element i.e.: tuple<mpl::list<element1_type, element1_tag>, mpl::list<element2_type, element2_tag>,.....> a get<elementn_tag> would return the nth element. This would make the tag unique and maybe open new possibilities. BTW, tuples containing many objects of the same type are better seen as containers, thus the indexed get is fine.
Maybe if there were some way of associating an enumeration with the tuple, you could:
get<f_i>(my_tuple)
where fi is some enumerator in, e.g.:
enum my_tuple_fields { f_0 , f_1 ... , f_n };
but even then, with nested tuples, there's a possible name conflict amoung the enumerators. Possibly the enumerator names could contain a prefix indicating to which type they belong:
enum type0_fields { t0_f_0 , t0_f_1 ... , t0_f_n0 };
enum type1_fields { t1_f_0 , t1_f_1 ... , t1_f_n1 };
In a theoretical extended_tuple, the enum could be part of the tuple itself, so you could do 'get<my_tuple.element1> (my_tuple)' and there would not be no name conflict. The problem with enums is that you have to maintain them separately: this is information duplication that could easily go out of sync. -- Giovanni P. Deretta

On 04/26/2005 10:30 AM, Giovanni Piero Deretta wrote:
On 4/26/05, Larry Evans <cppljevans@cox-internet.com> wrote:
[snip]
Anyway, the get<type> form is most useful with tuples containing elements of different type. In practice you overload the meaning of the type to also be a an element tag. This way tuples become as
But isn't an enumerator in some enumeration the equivalent of an "element tag"?
powerful as structures: you can access element by "name". They are
The enumerator can also be thought of as a name.
more powerful actually, as they have introspection capability: elements can be enumerated. Also the possibility of accessing tuple elements indipendently of the exact tuple type and element position can be very handy in generic programming.
Which can be done with enumerators also.
The get<type> form that i proposed can be easily added with zero changes to the existing tuple code/interface. A more complex addition would allow the association of a tag to each tuple element i.e.: tuple<mpl::list<element1_type, element1_tag>, mpl::list<element2_type, element2_tag>,.....> a get<elementn_tag> would return the nth element. This would make the tag unique and maybe open new possibilities.
But again, I don't see why adding a tag is any better than using an enumerator. The only difference between an array (all elements of the same type) and a tuple, is that the type of the value as well as the value depends on the index. And if the types are indexed by the same enumeration, then you've solve the problem. In addition, a similar scheme can be used for variants (or disjoint sum). See http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/libs/index...
BTW, tuples containing many objects of the same type are better seen as containers, thus the indexed get is fine.
Agreed, but the indexed get works just as well when the argument is an enumerator instead of a literal unsigned, and when it's an enumerator, the meaning is clearer: t.get<0>(); t.get<1>(); is obviously not as clear as: t.get<first_field>(); t.get<second_field>(); [snip]
In a theoretical extended_tuple, the enum could be part of the tuple itself, so you could do 'get<my_tuple.element1> (my_tuple)' and there would not be no name conflict. The problem with enums is that you have to maintain them separately: this is information duplication that could easily go out of sync.
Not if you use either something like mpl's map: <-------------------- cut here --------------------- struct enum_map_0 { enum field_names { f_0 , f_1 , f_2 }; template<field_names FieldName> struct field_name {}; typedef mpl::map < mpl::pair<field_name<f_0>, type_i<0> > , mpl::pair<field_name<f_1>, type_i<0> > , mpl::pair<field_name<f_2>, type_i<1> > > field_map ; }; void test(void) { mpl::tuple_enum<enum_map_0> tuple_0; type_i<0>& f0=tuple_0.get<enum_map_0::f_0>(); }
-------------------- cut here --------------------- or use a specialization of a template indexed by the enumeration, as shown in the boost-sandbox sum.cpp file mentioned above or in another test file, product.cpp, in the same location.
I'm not sure which is better.

Larry Evans wrote:
On 04/26/2005 10:30 AM, Giovanni Piero Deretta wrote:
On 4/26/05, Larry Evans <cppljevans@cox-internet.com> wrote:
[snip]
Anyway, the get<type> form is most useful with tuples containing elements of different type. In practice you overload the meaning of the type to also be a an element tag. This way tuples become as
But isn't an enumerator in some enumeration the equivalent of an "element tag"?
powerful as structures: you can access element by "name". They are
The enumerator can also be thought of as a name.
more powerful actually, as they have introspection capability: elements can be enumerated. Also the possibility of accessing tuple elements indipendently of the exact tuple type and element position can be very handy in generic programming.
Which can be done with enumerators also.
The get<type> form that i proposed can be easily added with zero changes to the existing tuple code/interface. A more complex addition would allow the association of a tag to each tuple element i.e.: tuple<mpl::list<element1_type, element1_tag>, mpl::list<element2_type, element2_tag>,.....> a get<elementn_tag> would return the nth element. This would make the tag unique and maybe open new possibilities.
But again, I don't see why adding a tag is any better than using an enumerator. The only difference between an array (all elements of the same type) and a tuple, is that the type of the value as well as the value depends on the index. And if the types are indexed by the same enumeration, then you've solve the problem. In addition, a similar scheme can be used for variants (or disjoint sum). See
http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/libs/index...
BTW, tuples containing many objects of the same type are better seen as containers, thus the indexed get is fine.
Agreed, but the indexed get works just as well when the argument is an enumerator instead of a literal unsigned, and when it's an enumerator, the meaning is clearer:
t.get<0>(); t.get<1>();
is obviously not as clear as:
t.get<first_field>(); t.get<second_field>();
[snip]
In a theoretical extended_tuple, the enum could be part of the tuple itself, so you could do 'get<my_tuple.element1> (my_tuple)' and there would not be no name conflict. The problem with enums is that you have to maintain them separately: this is information duplication that could easily go out of sync.
Not if you use either something like mpl's map:
[...]
-------------------- cut here --------------------- or use a specialization of a template indexed by the enumeration, as shown in the boost-sandbox sum.cpp file mentioned above or in another test file, product.cpp, in the same location.
I'm not sure which is better.
Gentlemen, these are all variations of the associative tuple. An implementation of fusion's set and map will be available as soon as I formalize the interface. I already have an implementation handy, ready to be deployed. Yes, associative tuples are powerful structures. They could potentially simplify code such as those in phoenix lambda, let scopes and the named parameters. As to which is better: a (type) tag or an enumerator; a (type) tag is definitely better because 1) an enumerator fails to address common idioms like named parameters which uses type tags. And, 2) a type tag can handle enumerators as well if you place them in some sort of enum_<enum> template akin to mpl::int_: template <my_enum e> struct my_enum_ {}; IOTW, you can easily convert an enum to a type. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

On 04/26/2005 05:21 PM, Joel wrote:
Larry Evans wrote: [snip]
Not if you use either something like mpl's map:
[...]
-------------------- cut here --------------------- [snip]
Gentlemen, these are all variations of the associative tuple. An implementation of fusion's set and map will be available as soon as I formalize the interface. I already have an implementation handy, ready to be deployed.
[snip]
As to which is better: a (type) tag or an enumerator; a (type) tag is definitely better because 1) an enumerator fails to address common idioms like named parameters which uses type
OK. I hadn't thought of that. I'd also been wondering why there couldn't be a boost::map_c similar to boost::vector_c whose first argument would be the integral type. This would avoid the need for the field_name nested template in my previous post.
tags. And, 2) a type tag can handle enumerators as well if you place them in some sort of enum_<enum> template akin to mpl::int_:
template <my_enum e> struct my_enum_ {};
IOTW, you can easily convert an enum to a type.
As was demonstrated with the template<enum_map_0::field_names FieldName> struct field_name{}; in the snipped part of my post which was quoted above ;) BTW, changing: [-------- cut here --------- template < class FieldTypes , class Indices
struct tuple_indexed : factor < FieldTypes , size<FieldTypes>::value > { ]-------- cut here --------- to the following: [-------- cut here --------- template < class FieldTypes , class Indices=unsigned
struct tuple_indexed : tuple < FieldTypes > { ]-------- cut here --------- in the vault code mentioned in my previous posts would work just as well and reuse boost::mpl::tuple or, I assume, fusion's tuple, and achieve what OP desires, AFAICT. If OP doesn't want to be bothered with the enum_map arg to tuple_mapped (see vault code), he could just use tuple_indexed<FieldTypes> (using the default Indices=unsigned). I haven't tried it yet.

Larry Evans wrote:
But isn't an enumerator in some enumeration the equivalent of an "element tag"?
Yes,
The enumerator can also be thought of as a name.
yes,
Which can be done with enumerators also.
and also yes.
But again, I don't see why adding a tag is any better than using an enumerator. The only difference between an array (all elements of the same type) and a tuple, is that the type of the value as well as the value depends on the index. And if the types are indexed by the same enumeration, then you've solve the problem. In addition, a similar scheme can be used for variants (or disjoint sum). See
http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/libs/index...
As your code demonstrates, enumerators can be used without duplicating information, but an enum and map enum->type is required for each tuple. This is verbose and should be wrapped in a macro. Then again, I don't like macros a lot :) In the end, getting 'by type' has the same expressive power of using enumerators, i simply think that it would have a better syntax and it would work out of the box with all tuples without the need of a map.
BTW, tuples containing many objects of the same type are better seen as containers, thus the indexed get is fine.
Agreed, but the indexed get works just as well when the argument is an enumerator instead of a literal unsigned, and when it's an enumerator, the meaning is clearer:
t.get<0>(); t.get<1>();
is obviously not as clear as:
t.get<first_field>(); t.get<second_field>();
[snip]
Well, i actually believe the first to be clearer. It is a matter of taste though. -- Giovanni P. Deretta

On 04/26/2005 05:22 PM, Giovanni P. Deretta wrote: [snip]
Agreed, but the indexed get works just as well when the argument is an enumerator instead of a literal unsigned, and when it's an enumerator, the meaning is clearer:
t.get<0>(); t.get<1>();
is obviously not as clear as:
t.get<first_field>(); t.get<second_field>();
[snip]
Well, i actually believe the first to be clearer. It is a matter of taste though.
I hope you didn't misinterpret what I was saying. I used 'first_field' and 'second_field' to emphasize the use of names instead of numbers. In a real application, the names would, of course, indicate the type of relationship. E.g. in an employee record, the enumerators would be: enum employee_fields { name , salary , title }; which, I hope you'll agree would make the meaning of: a_employee.get<name>(); a_employee.get<salary>(); clearer than: a_employee.get<0>(); a_employee.get<1>();

Larry Evans wrote:
On 04/26/2005 05:22 PM, Giovanni P. Deretta wrote: [snip]
Agreed, but the indexed get works just as well when the argument is an enumerator instead of a literal unsigned, and when it's an enumerator, the meaning is clearer:
t.get<0>(); t.get<1>();
is obviously not as clear as:
t.get<first_field>(); t.get<second_field>();
[snip]
Well, i actually believe the first to be clearer. It is a matter of taste though.
I hope you didn't misinterpret what I was saying. I used 'first_field' and 'second_field' to emphasize the use of names instead of numbers. In a real application, the names would, of course, indicate the type of relationship. E.g. in an employee record, the enumerators would be:
enum employee_fields { name , salary , title };
Actually I did :-) In that paragraph i was talking about homogeneous tuples and i thought you were too in your answer. It is much more clearer now.
which, I hope you'll agree would make the meaning of:
a_employee.get<name>(); a_employee.get<salary>();
clearer than:
a_employee.get<0>(); a_employee.get<1>();
Yes, certanly. -- Giovanni P. Deretta

On 04/26/2005 05:22 PM, Giovanni P. Deretta wrote: [snip]
As your code demonstrates, enumerators can be used without duplicating information, but an enum and map enum->type is required for each tuple. This is verbose and should be wrapped in a macro. Then again, I don't
Agreed.
like macros a lot :)
But mpl and fusion are profuse with macros, or at least boost/preprocessor.
In the end, getting 'by type' has the same expressive power of using enumerators, i simply think that it would have a better syntax and it would work out of the box with all tuples without the need of a map.
But it wouldn't work for repeated types, unless, as you noted previously, some sort of "tag" were "associated" with the type, which is what an mpl::map does, only it assures there's only one type associated with each tag; whereas the example: tuple<mpl::list<element1_type, element1_tag>, mpl::list<element2_type, element2_tag>,.....> in one of your previous messages: http://article.gmane.org/gmane.comp.lib.boost.devel/122595 doesn't assure this, AFAICT. Also, I'd think mpl::pair would be more succinct. So, the tuple version of the following: struct employ { string name; float salary; int ssn; }; could be: struct name{}; struct salary{}; struct ssn{}; tuple < mpl::pair<string,name> , mpl::pair<float,salary> , mpl::pair<int,ssn>
::type;
which is not that much shorter than the enum_map_0 shown in my previous post: http://article.gmane.org/gmane.comp.lib.boost.devel/122661 After all, for each enum_map_0::f_i, for i=0..2, there's got to be a tag with your method: struct name{}; struct salary{}; struct ssn{}; and there's also got to be a pairing of tags to types, just as in the enum_map_0::field_map. Am I missing something?

Larry Evans wrote:
On 04/26/2005 05:22 PM, Giovanni P. Deretta wrote: [snip]
As your code demonstrates, enumerators can be used without duplicating information, but an enum and map enum->type is required for each tuple. This is verbose and should be wrapped in a macro. Then again, I don't
Agreed.
like macros a lot :)
But mpl and fusion are profuse with macros, or at least boost/preprocessor.
Sure, I write macros myself, but i try to avoid them if i can.
In the end, getting 'by type' has the same expressive power of using enumerators, i simply think that it would have a better syntax and it would work out of the box with all tuples without the need of a map.
But it wouldn't work for repeated types, unless, as you noted previously, some sort of "tag" were "associated" with the type, which is what an mpl::map does, only it assures there's only one type associated with each tag; whereas the example:
tuple<mpl::list<element1_type, element1_tag>, mpl::list<element2_type, element2_tag>,.....>
in one of your previous messages:
http://article.gmane.org/gmane.comp.lib.boost.devel/122595
doesn't assure this, AFAICT. Also, I'd think mpl::pair would be more succinct.
Why not? You would get by 'tag' i.e. get<element1_tag>(tuple). An extended_tuple<mpl::pair<type1, tag1>, mpl::pair<type2, tag2>...>; is almost exactly the same of a TR1 tuple<type1, type2 ...>; the extra tags are only used to accessing the tuple. I think i failed to expain this, from your next example i think you thought that my extended_tuple where some sort of mpl-like container. The extended_tuple probably requires modification to tuple code, so it is not really viable. And yes, mpl::pair would be better, but i couldn't find it in the mpl documentation :)
So, the tuple version of the following: struct employ { string name; float salary; int ssn; };
could be:
struct name{}; struct salary{}; struct ssn{};
tuple < mpl::pair<string,name> , mpl::pair<float,salary> , mpl::pair<int,ssn>
::type;
which is not that much shorter than the enum_map_0 shown in my previous post:
http://article.gmane.org/gmane.comp.lib.boost.devel/122661
After all, for each enum_map_0::f_i, for i=0..2, there's got to be a tag with your method:
struct name{}; struct salary{}; struct ssn{};
and there's also got to be a pairing of tags to types, just as in the enum_map_0::field_map.
Am I missing something?
Well, in my extended tuple example tags are _not_ associated with a tuple. Different tuples can reuse the same tag set or part of it. This is very useful for generic programming, for example, i may have a function that accept a tuple having a some_tag slot. Doing this with enum is clumsy and not type safe. I.e. a tuple might not map the whole enum set enum {a, b, c}, but get<a>(tuple_foo) would still compile even if 'a' is not logically part of tuple_foo. Also you are forced to use the enum ordering. Anyway, i don't think you proposed to reuse the same enums, only the names, but then you are forced to write enums for every tuple. Anyway, I think i will try fusion now :) -- Giovanni P. Deretta

... replying to myself Giovanni P. Deretta wrote:
Larry Evans wrote:
But it wouldn't work for repeated types, unless, as you noted previously, some sort of "tag" were "associated" with the type, which is what an mpl::map does, only it assures there's only one type associated with each tag; whereas the example:
I couldn't parse this paragraph correctly the first time, the second time i *thought* i did get it. The third time i *did* get it, but i had already sent my reply... :)
I think i failed to expain this, from your next example i think you thought that my extended_tuple where some sort of mpl-like container.
It was me that didn't understand. You are right, a map is better.
Well, in my extended tuple example tags are _not_ associated with a tuple. Different tuples can reuse the same tag set or part of it. This is very useful for generic programming, for example, i may have a function that accept a tuple having a some_tag slot. Doing this with enum is clumsy and not type safe. I.e. a tuple might not map the whole enum set enum {a, b, c}, but get<a>(tuple_foo) would still compile even if 'a' is not logically part of tuple_foo. Also you are forced to use the enum ordering. Anyway, i don't think you proposed to reuse the same enums, only the names, but then you are forced to write enums for every tuple. Anyway, I think i will try fusion now :)
This still stand. -- Giovanni P. Deretta

On 04/27/2005 11:16 AM, Giovanni P. Deretta wrote:
... replying to myself
Giovanni P. Deretta wrote:
Larry Evans wrote:
But it wouldn't work for repeated types, unless, as you noted previously, some sort of "tag" were "associated" with
[snip] I couldn't parse this paragraph correctly the first time, the second time i *thought* i did get it. The third time i *did* get it, but i had already sent my reply... :)
OK. Sorry for not being clearer :( Other's in this list have stumbled over my wording also.
I think i failed to expain this, from your next example i think you thought that my extended_tuple where some sort of mpl-like container.
It was me that didn't understand. You are right, a map is better.
OK.
Well, in my extended tuple example tags are _not_ associated with a tuple. Different tuples can reuse the same tag set or part of it.
True, but that's not type safe. For example: enum indices{i0,i1}; int ivec1[1]; int ivec2[2]; ivec2[i1];//OK ivec1[i1];//BAD Although c vectors are used, I think you can see the analogy. the same "tag set" is used for both "tuple"'s ivec1 and ivec2; yet, one element of the tag set, i.e. i1, is not valid for the "tuple" ivec1.
This is very useful for generic programming, for example, i may have a function that accept a tuple having a some_tag slot. Doing this with enum is clumsy and not type safe. I.e. a tuple might not map the whole enum set enum {a, b, c}, but get<a>(tuple_foo) would still compile even if 'a' is not logically part of tuple_foo. Also you are
If you've defined the enum and map together, e.g. in the enum_map<i> structure, and used them together in enum_mapped, as shown here: http://boost-sandbox.sourceforge.net/vault/index.php?&direction=0&order=&directory=cppljevans in tuple_nested_enum_test.cpp, then 'a' (or 'f_0' in the vault file), is logically part of the tuple in the same way that 'a' is logically part of: struct abc { int a; float b; char c;}; and the: tuple_mapped<enum_map<i> >::get<index> for some i in 0..2, will only compile for some index in enum_map<i>::field_names, just as: abc::index will only compile for some index in a,b,c.
forced to use the enum ordering. Anyway, i don't think you proposed to reuse the same enums, only the names, but then you are forced to write enums for every tuple.
True, just as, for every c or c++ struct the programmer is forced to write names for every member variable.
Anyway, I think i will try fusion now :)
This still stand.
I'd be curious to see how it turns out.

Larry Evans wrote:
On 04/27/2005 11:16 AM, Giovanni P. Deretta wrote:
... replying to myself
Giovanni P. Deretta wrote:
Larry Evans wrote:
But it wouldn't work for repeated types, unless, as you noted previously, some sort of "tag" were "associated" with
[snip]
I couldn't parse this paragraph correctly the first time, the second time i *thought* i did get it. The third time i *did* get it, but i had already sent my reply... :)
OK. Sorry for not being clearer :( Other's in this list have stumbled over my wording also.
I think i failed to expain this, from your next example i think you thought that my extended_tuple where some sort of mpl-like container.
It was me that didn't understand. You are right, a map is better.
OK.
Well, in my extended tuple example tags are _not_ associated with a tuple. Different tuples can reuse the same tag set or part of it.
True, but that's not type safe. For example:
enum indices{i0,i1}; int ivec1[1]; int ivec2[2]; ivec2[i1];//OK ivec1[i1];//BAD
Although c vectors are used, I think you can see the analogy. the same "tag set" is used for both "tuple"'s ivec1 and ivec2; yet, one element of the tag set, i.e. i1, is not valid for the "tuple" ivec1.
This is very useful for generic programming, for example, i may have a function that accept a tuple having a some_tag slot. Doing this with enum is clumsy and not type safe. I.e. a tuple might not map the whole enum set enum {a, b, c}, but get<a>(tuple_foo) would still compile even if 'a' is not logically part of tuple_foo. Also you are
If you've defined the enum and map together, e.g. in the enum_map<i> structure, and used them together in enum_mapped, as shown here:
http://boost-sandbox.sourceforge.net/vault/index.php?&direction=0&order=&directory=cppljevans
in tuple_nested_enum_test.cpp, then 'a' (or 'f_0' in the vault file), is logically part of the tuple in the same way that 'a' is logically part of:
struct abc { int a; float b; char c;};
and the:
tuple_mapped<enum_map<i> >::get<index>
for some i in 0..2, will only compile for some index in enum_map<i>::field_names, just as:
abc::index
will only compile for some index in a,b,c.
forced to use the enum ordering. Anyway, i don't think you proposed to reuse the same enums, only the names, but then you are forced to write enums for every tuple.
True, just as, for every c or c++ struct the programmer is forced to write names for every member variable.
Anyway, I think i will try fusion now :)
This still stand.
I'd be curious to see how it turns out.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 04/27/2005 12:40 PM, Giovanni P. Deretta wrote: Giovanni, I guess this was an "OOPS" since there was nothing added. Anyway, I should say, w.r.t. redundancy, that the following code: enum_map<0>::field_names const index=enum_map<0>::f_0; from the vault file mentioned here:
Larry Evans wrote: [snip]
http://boost-sandbox.sourceforge.net/vault/index.php?&direction=0&order=&directory=cppljevans
does contain some redundancy since the field_name, f_0, has to be qualified with the struct, enum_map<0>, where it's defined. Also, in enum_map, there's redundancy in that the enumeration has to be defined first before it's used in the mpl::map. This is in contrast to the corresponding struct: struct enum_map_0 { type_i<0> f_0; type_i<1> f_1; type_i<2> f_2; }; where the field names only occur once.

On 04/27/2005 01:06 PM, Larry Evans wrote: [snip]
Anyway, I should say, w.r.t. redundancy, that the following code: However, with respect to your desire for using a template member function:
template<class FieldType> FieldType& get() ; to get some field in the tuple of type, FieldType, this can easily be done with a slight modification of the code for tuple_indexed in the vault: template<class FieldType> FieldType& get() { typedef find<Values,FieldType>::type pos; typedef distance<pos,front<Values> >::type offset; Indices const index=Indices(offset::value); return get<index>(); }

Replying to self: On 04/27/2005 11:54 AM, Larry Evans wrote: [snip]
with enum is clumsy and not type safe. I.e. a tuple might not map the whole enum set enum {a, b, c}, but get<a>(tuple_foo) would still compile even if 'a' is not logically part of tuple_foo. Also you are
If you've defined the enum and map together, e.g. in the enum_map<i> structure, and used them together in enum_mapped, as shown here:
http://boost-sandbox.sourceforge.net/vault/index.php?&direction=0&order=&directory=cppljevans
OOPS. Maybe you meant that although there were, e.g. 3 enumerators in the enumeration, the map was only defined for 2 or 1 or none. To be concrete, an example would be where enum_map<0> in the above vault code were: template <
struct enum_map < 0
{ enum field_names { f_0 , f_1 , f_2 }; template<field_names FieldName> struct field_name {}; typedef mpl::map < mpl::pair<field_name<f_0>, type_i<0> > > field_map ; }; then I can see your point about "tuple might not map the whole enum set".

Sorry for the no-op email, I don't know how it did get sent. Larry Evans wrote:
OOPS. Maybe you meant that although there were, e.g. 3 enumerators in the enumeration, the map was only defined for 2 or 1 or none. To be concrete, an example would be where enum_map<0> in the above vault code were:
template <
struct enum_map < 0
{ enum field_names { f_0 , f_1 , f_2 };
template<field_names FieldName> struct field_name {};
typedef mpl::map < mpl::pair<field_name<f_0>, type_i<0> > > field_map ; };
then I can see your point about "tuple might not map the whole enum set".
Exactly, and this is something i need (and probably is the only reason to use some kind of tag instead of indexes). In code that i wrote there were a set of functions that had similar effects and had multiple return values (as tuples). The return values weren't the same, but all of them had a common types. Some generic code had to work with this functions and needed to extract this common types from the tuples. A typed get was exactly what i needed. Fusion 'find' would probably have done the job as well, but i did not know it untill now. -- Giovanni P. Deretta Giovanni P. Deretta

On 04/27/2005 05:33 PM, Giovanni P. Deretta wrote: [snip]
to use some kind of tag instead of indexes). In code that i wrote there were a set of functions that had similar effects and had multiple return values (as tuples). The return values weren't the same, but all of them had a common types. Some generic code had to work with this functions and needed to extract this common types from the tuples. A typed get was exactly what i needed. Fusion 'find' would probably have done the job as well, but i did not know it untill now.
I amended the code in vault: http://boost-sandbox.sourceforge.net/vault/index.php?&direction=0&order=&directory=cppljevans by adding templated member function: template<class FieldType> FieldType& find_type(void) ; to template tuple_indexed. Would this satisfy your needs?

Giovanni P. Deretta wrote:
Hi,
I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example:
given the tuple boost::tuple<type1, type2, type3>
get<type1> returns the first element of the tuple of that type.
This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example 'get<3>(get<5>(get<0>(my_tuple)))' looks more like line noise than real code :).
Fusion's *find* algorithm already does this. What is Fusion? Fusion is the next generation tuples lib. This is a re- implementation of the TR tuples with iterators, views and algorithms. The structure is somewhat modeled after MPL. It is code-named "fusion" because the library is the "fusion" of compile time metaprogramming with runtime programming. Eric (Niebler) recently added a cons-list implementation. After the 1.33 release, I'm making it a point to implement the rest of the structures. Right now there's a vector (flat tuple) and list (cons-list tuple). I already have a rough implementation of a set and map (associative tuples). Overall structure: The library is composed of three sub-modules. Iterators, Sequences and Views and Algorithms. Iterators: Generic iteration for heterogeneous types. The library is based on iterators. filter_view_iterator filtering iterator. Given an MPL predicate, skips elements to present only the items that passes the predicate. See filter_view below. joint_view_iterator Holds four iterators (two begin/end pairs). Iterates over the first pair then switches over to the next pair to present a contiguous whole. See joint_view below. single_view_iterator A single element iterator. See single_view below. cons_iterator An iterator into a cons list. See cons below. transform_view_iterator Given a transform-function, transforms the elements being iterated. See transform_view below. Sequences and Views: Holds a begin/end iterator. Sequences and views may be composed to form more complex sequences and views. View/sequence composition is a very nice concept. These are extremely lighweight classes and can be passed around by value quite inexpensively. For instance, rather than working directly on tuples, the algorithms work on sequences and return sequences. tuple The basic tuple structure tupleN Fixed sized tuples (where N = 0 to a predefined limit) filter_view Given an MPL predicate, filters the view to present only the items that passes the predicate. single_view A single element view joint_view A two-sequence view (concatenates two sequences) cons A cons-cell that can be used to build a singly-linked list. range Holds an iterator pair that represents a begin/end range. transform_view Transforms a sequence given a transform-function MPL sequences are also, automatically, fusion sequences. All algorithms and fusion functions that work on fusion sequences can also take in MPL seqneces. Basic functions and meta_functions on sequences: I/O : TR1-tuples compatible I/O routines operator : tuple operators ==, !=, <, >, <=, >= begin : start of sequence end : end of sequence make_tuple : make a tuple tie : make a tuple of references generate : given a fusion sequence, generate a tuple get<N> : get the nth element of a tuple is_sequence : checks if a type is a fusion sequence tuple_element : get the nth type in a tuple tuple_size : get the number of elements in a tuple Algorithms: With very complex composition of algorithms, it is not desirable to work directly on tuples. Like MPL, and unlike STL, the algorithms take in sequences/views and *return* the result by value; the algorithms are purely functional and do not (cannot) have side effects. We cannot have an out parameter that is passed by reference where the result is placed. The algorithms, instead, work on sequences and views and generate views. This strategy is very efficient. You can think of the algorithms as "lazy". The values are generated only wnen it is needed -for example when generating a tuple. When you are sure that you need a tuple, you can "generate" it from the sequence: generate(sequence); erase filter find find_if fold for_each insert push_back push_front remove remove_if replace transform any Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Fusion's *find* algorithm already does this. What is Fusion? Fusion is the next generation tuples lib. This is a re- implementation of the TR tuples with iterators, views and algorithms. The structure is somewhat modeled after MPL. It is code-named "fusion" because the library is the "fusion" of compile time metaprogramming with runtime programming.
This is *very* interesting! Will it be available in boost-1.33? Is it already available somewhere? I'm certanly interested in trying it. -- Giovanni P. Deretta

Giovanni Piero Deretta wrote:
Fusion's *find* algorithm already does this. What is Fusion? Fusion is the next generation tuples lib. This is a re- implementation of the TR tuples with iterators, views and algorithms. The structure is somewhat modeled after MPL. It is code-named "fusion" because the library is the "fusion" of compile time metaprogramming with runtime programming.
This is *very* interesting! Will it be available in boost-1.33? Is it already available somewhere? I'm certanly interested in trying it.
It is a part of spirit, for now. It's been proven to be quite stable for almost 3 years now. We're using it as a base infrastructure for at least 3 libraries (spirit2, phoenix2, and now, Eric Niebler's xpressive). See boost/spirit/fusion. Sorry, no docs yet. However, if you know MPL, you already know fusion. I suggest looking at the test cpp files. There's a test for each feature. The tests should be immediately understandable. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

"Giovanni P. Deretta" <lordshoo@gmail.com> writes:
Hi,
I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example:
given the tuple boost::tuple<type1, type2, type3>
get<type1> returns the first element of the tuple of that type.
This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example 'get<3>(get<5>(get<0>(my_tuple)))' looks more like line noise than real code :).
You might look at c:/boost/boost/python/detail/tuple_extract.hpp HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Giovanni P. Deretta" <lordshoo@gmail.com> writes:
Hi,
I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example:
given the tuple boost::tuple<type1, type2, type3>
get<type1> returns the first element of the tuple of that type.
This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example 'get<3>(get<5>(get<0>(my_tuple)))' looks more like line noise than real code :).
You might look at c:/boost/boost/python/detail/tuple_extract.hpp
HTH,
Hum, I can't find it in boost-1.32 nor in the CVS... link? -- Giovanni P. Deretta
participants (6)
-
Caleb Epstein
-
David Abrahams
-
Giovanni P. Deretta
-
Giovanni Piero Deretta
-
Joel
-
Larry Evans