
Hi, The default implementation of boost::fusion::pair<first,second> only stores an instance of second. I might need a fusion::pair which does not store that instance either, maybe that will cause trouble in several parts of fusion. At first I would like to explain what I am doing right now. At the moment I do work on an expression template framework, similiar to Eric Nieblers boost::proto, which was used to build boost::xpressive. I do extend that library by adding a rule system which enables the user to define the allowed operations of a certain domain. To simplify and generalize the rule writing process, every node in the expression tree has a fusion::map<> which is supposed to hold some meta information. E.g. in the matrix vector domain, that attribute container of a binary node returned by binary plus, might look like that: map< pair<domain_tag, linear_algebra_domain> , pair<operator_tag, plus_tag> , pair<category_tag, column_vector_tag> , pair<dimension_tag, dynamic::dimension> , pair<element_type_tag, float>
There are entries in the map that do not require runtime data at all, for these entries all information is coverd by the second template parameter of pair. And others like the dimension_tag which require an instance of the second type stored in the container. How can I acchieve that with fusion? I thougt about a rather ugly solution: template <typename T> struct ct{ typedef T type }; map< pair<domain_tag, ct<linear_algebra_domain> > , pair<operator_tag, ct<plus_tag> > , pair<category_tag, ct<column_vector_tag> > , pair<dimension_tag, dynamic::dimension> , pair<element_type_tag, ct<float> >
Then only an empty ct is stored. The main reason for all this is the element_type_tag. It should be possible to define a matrix with some matrix type as element_type. Regards, Andreas Pokorny

Andreas Pokorny wrote:
Hi, The default implementation of boost::fusion::pair<first,second> only stores an instance of second. I might need a fusion::pair which does not store that instance either,
If you want a map with *no* runtime data, then you should use mpl::map<>, not fusion::map<>. mpl::map<> uses mpl::pair<>, which has no runtime data. (Caveat: mpl::map is broken in more than one respect at the moment. Hopefully, it'll be fixed soon.)
At first I would like to explain what I am doing right now. At the moment I do work on an expression template framework, similiar to Eric Nieblers boost::proto, which was used to build boost::xpressive.
I do extend that library by adding a rule system which enables the user to define the allowed operations of a certain domain.
Yes, proto needs this. If you're extending proto, I'd gladly accept a patch. -- Eric Niebler Boost Consulting www.boost-consulting.com

On Fri, Dec 02, 2005 at 12:11:32PM -0800, Eric Niebler <eric@boost-consulting.com> wrote:
Andreas Pokorny wrote:
Hi, The default implementation of boost::fusion::pair<first,second> only stores an instance of second. I might need a fusion::pair which does not store that instance either,
If you want a map with *no* runtime data, then you should use mpl::map<>, not fusion::map<>. mpl::map<> uses mpl::pair<>, which has no runtime data. (Caveat: mpl::map is broken in more than one respect at the moment. Hopefully, it'll be fixed soon.)
Ah, I could write an interleaved map that splits the pair sequence into runtime and compile time info holders. How is mpl::map broken? Regards, Andreas Pokorny

Andreas Pokorny wrote:
On Fri, Dec 02, 2005 at 12:11:32PM -0800, Eric Niebler <eric@boost-consulting.com> wrote:
Andreas Pokorny wrote:
Hi, The default implementation of boost::fusion::pair<first,second> only stores an instance of second. I might need a fusion::pair which does not store that instance either,
If you want a map with *no* runtime data, then you should use mpl::map<>, not fusion::map<>. mpl::map<> uses mpl::pair<>, which has no runtime data. (Caveat: mpl::map is broken in more than one respect at the moment. Hopefully, it'll be fixed soon.)
Ah, I could write an interleaved map that splits the pair sequence into runtime and compile time info holders.
I'm not sure I follow, but if my suggestion led you to a solution, I'm happy to take the credit. ;-)
How is mpl::map broken?
mpl::map doesn't guarantee unique keys at the moment. For instance, this doesn't work. typedef mpl::insert<mpl::map0<>, mpl::pair<int, float> >::type t1; typedef mpl::insert<t1, mpl::pair<int, double> >::type t2; // Oops, this assertion fails BOOST_MPL_ASSERT_RELATION(mpl::size<t2>::value, ==, 1); After the two insertions, the map contains pair<int,float> and pair<int,double>, but AFAICT it should only contain mpl::pair<int, float>. Also, mpl::insert_range does not work with mpl::map<> even though the docs say it should. Also, I have found places where using an mpl::map<> fails where using mpl::map0<> works. Ditto for mpl::set<> and mpl::set0<>. If you decide to go this route, be aware, or else wait for the fixes. -- Eric Niebler Boost Consulting www.boost-consulting.com

Andreas Pokorny wrote:
Hi, The default implementation of boost::fusion::pair<first,second> only stores an instance of second. I might need a fusion::pair which does not store that instance either, maybe that will cause trouble in several parts of fusion. At first I would like to explain what I am doing right now. At the moment I do work on an expression template framework, similiar to Eric Nieblers boost::proto, which was used to build boost::xpressive.
I do extend that library by adding a rule system which enables the user to define the allowed operations of a certain domain. To simplify and generalize the rule writing process, every node in the expression tree has a fusion::map<> which is supposed to hold some meta information. E.g. in the matrix vector domain, that attribute container of a binary node returned by binary plus, might look like that: map< pair<domain_tag, linear_algebra_domain> , pair<operator_tag, plus_tag> , pair<category_tag, column_vector_tag> , pair<dimension_tag, dynamic::dimension> , pair<element_type_tag, float>
There are entries in the map that do not require runtime data at all, for these entries all information is coverd by the second template parameter of pair. And others like the dimension_tag which require an instance of the second type stored in the container.
How can I acchieve that with fusion?
If both the key and the data need to be just types, then what immediately comes to my mind is an mpl::map. What am I missing? Pure types == MPL. Half type/data == Fusion. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

On Sat, Dec 03, 2005 at 08:21:04AM +0800, Joel de Guzman <joel@boost-consulting.com> wrote:
There are entries in the map that do not require runtime data at all, for these entries all information is coverd by the second template parameter of pair. And others like the dimension_tag which require an instance of the second type stored in the container.
How can I acchieve that with fusion?
If both the key and the data need to be just types, then what immediately comes to my mind is an mpl::map. What am I missing? Pure types == MPL. Half type/data == Fusion.
But I need both in the same associative container. What changes are required to make fusion deal with: template<typename F,typename S> struct ct_pair { typedef F first_type; typedef S second_type; }; It would be acceptable if fusion::at<key>(seq), or deref on a ct_pair causes compile errors, provided that the pair entries in the same container still work. Regards, Andreas Pokorny

On Sat, Dec 03, 2005 at 03:56:09PM +0100, Andreas Pokorny <andreas.pokorny@gmx.de> wrote:
On Sat, Dec 03, 2005 at 08:21:04AM +0800, Joel de Guzman <joel@boost-consulting.com> wrote:
There are entries in the map that do not require runtime data at all, for these entries all information is coverd by the second template parameter of pair. And others like the dimension_tag which require an instance of the second type stored in the container.
How can I acchieve that with fusion?
If both the key and the data need to be just types, then what immediately comes to my mind is an mpl::map. What am I missing? Pure types == MPL. Half type/data == Fusion.
But I need both in the same associative container. What changes are required to make fusion deal with: template<typename F,typename S> struct ct_pair { typedef F first_type; typedef S second_type; };
It would be acceptable if fusion::at<key>(seq), or deref on a ct_pair causes compile errors, provided that the pair entries in the same container still work.
Oh, simpler than I thought. Kudos to you two, Dan and Joel. Fusion-2 is great, looking forward to write a review. I now use some ct_pairs next to fusion::pairs in fusion::map. The meta stuff seems to work, only the runtime access functions deref and at fail to compile if they get applied on a ct_pair. Regards Andreas Pokorny

Andreas Pokorny wrote:
On Sat, Dec 03, 2005 at 03:56:09PM +0100, Andreas Pokorny <andreas.pokorny@gmx.de> wrote:
On Sat, Dec 03, 2005 at 08:21:04AM +0800, Joel de Guzman <joel@boost-consulting.com> wrote:
There are entries in the map that do not require runtime data at all, for these entries all information is coverd by the second template parameter of pair. And others like the dimension_tag which require an instance of the second type stored in the container.
How can I acchieve that with fusion?
If both the key and the data need to be just types, then what immediately comes to my mind is an mpl::map. What am I missing? Pure types == MPL. Half type/data == Fusion.
But I need both in the same associative container. What changes are required to make fusion deal with: template<typename F,typename S> struct ct_pair { typedef F first_type; typedef S second_type; };
It would be acceptable if fusion::at<key>(seq), or deref on a ct_pair causes compile errors, provided that the pair entries in the same container still work.
Oh, simpler than I thought. Kudos to you two, Dan and Joel. Fusion-2 is great, looking forward to write a review. I now use some ct_pairs next to fusion::pairs in fusion::map. The meta stuff seems to work, only the runtime access functions deref and at fail to compile if they get applied on a ct_pair.
Ah yes :) That's because fusion::map is not tied to a specific pair implementation. In fact it is ignorant of the fusion::pair. "boost/fusion/core/pair.hpp" is included in map only as a convenience to users. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
participants (3)
-
Andreas Pokorny
-
Eric Niebler
-
Joel de Guzman