Possible bug with mpl::joint_view working on two mpl::maps

Hi all, I have two mpl maps like this: typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
I try to join them using "joint_view" as follows: typedef joint_view<Map1, Map2>::type JointMap; which works fine. Then I do std::cout << at<JointMap, int_<2> >::type::value << "\n"; which gives the following compiler error: error: 'value' is not a member of 'boost::mpl::pair<mpl_::int_<3>, mpl_::int_<44> >' I tried this with gcc 3.4.6 and 4.2 under Linux, Boost version is 1.34.0. It seems "at" returns the entry after the searched entry, and not only the right half, but the complete pair. Has anybody got any hints on this? To me it looks like a bug in MPL, but I might be wrong. Best Regards, Martin ____________ Virus checked: AVKB 17.336 from 12.08.2007

AMDG Martin Apel <martin.apel <at> simpack.de> writes:
Hi all,
I have two mpl maps like this:
typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
I try to join them using "joint_view" as follows:
typedef joint_view<Map1, Map2>::type JointMap;
which works fine. Then I do
std::cout << at<JointMap, int_<2> >::type::value << "\n";
which gives the following compiler error:
error: 'value' is not a member of 'boost::mpl::pair<mpl_::int_<3>, mpl_::int_<44> >'
I tried this with gcc 3.4.6 and 4.2 under Linux, Boost version is 1.34.0. It seems "at" returns the entry after the searched entry, and not only the right half, but the complete pair.
Has anybody got any hints on this? To me it looks like a bug in MPL, but I might be wrong.
joint_veiw is not intended to work that way for maps. It just takes the two sequences and sticks them together. The default implementation of at which is used for joint_view returns the Nth element of the sequence. Since you had the keys in order starting at 1 it appeared that it was adding one. The value of the key is irrelevant in determining the result. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Martin Apel <martin.apel <at> simpack.de> writes:
Hi all,
I have two mpl maps like this:
typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
I try to join them using "joint_view" as follows:
typedef joint_view<Map1, Map2>::type JointMap;
which works fine. Then I do
std::cout << at<JointMap, int_<2> >::type::value << "\n";
which gives the following compiler error:
error: 'value' is not a member of 'boost::mpl::pair<mpl_::int_<3>, mpl_::int_<44> >'
I tried this with gcc 3.4.6 and 4.2 under Linux, Boost version is 1.34.0. It seems "at" returns the entry after the searched entry, and not only the right half, but the complete pair.
Has anybody got any hints on this? To me it looks like a bug in MPL, but I might be wrong.
joint_veiw is not intended to work that way for maps. It just takes the two sequences and sticks them together. The default implementation of at which is used for joint_view returns the Nth element of the sequence. Since you had the keys in order starting at 1 it appeared that it was adding one. The value of the key is irrelevant in determining the result.
Thanks for the information, Steve. I didn't understand this from the available docs. So is there another way of joining two maps, so they create a single map, that can be used with mpl::at? Regards, Martin ____________ Virus checked: AVKB 17.336 from 12.08.2007

Hi Martin,
I have two mpl maps like this:
typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
I try to join them using "joint_view" as follows:
typedef joint_view<Map1, Map2>::type JointMap;
which works fine. Then I do
std::cout << at<JointMap, int_<2> >::type::value << "\n";
which gives the following compiler error:
error: 'value' is not a member of 'boost::mpl::pair<mpl_::int_<3>, mpl_::int_<44> >'
I tried this with gcc 3.4.6 and 4.2 under Linux, Boost version is 1.34.0. It seems "at" returns the entry after the searched entry, and not only the right half, but the complete pair.
Has anybody got any hints on this? To me it looks like a bug in MPL, but I might be wrong.
Both sides of this behavior steam from nongenericity of the 'at' metafunction, which treats Associated Sequences differently from "plain" Forward Sequences [1]. 'joint_view' of two maps is simply a Forward Sequence [2], which changes the 'at' semantics from a value lookup in the associative sequence to an equivalent of 'deref< advance< begin<s>::type,n >::type
::type'. Thus the result you observed: 'at<JointMap, int_<2> >::type' simply returns JointMap's third element.
This can be definitely argued to be a design bug. However, suppose that requesting the map's value by key was spelled differently, say, 'get'. Well, even in this case, unless the 'joint_view' of two Associated Sequences becomes in an Associated Sequence as well, applying 'get' to JointMap still won't work -- although you'd most likely get an error instead of a puzzling result. All in all, to get the behavior you want with the current library you need to actually merge two maps into a third one. [1] http://boost.org/libs/mpl/doc/refmanual/at.html [2] http://boost.org/libs/mpl/doc/refmanual/joint-view.html HTH, -- Aleksey Gurtovoy MetaCommunications Engineering

Aleksey Gurtovoy wrote:
Both sides of this behavior steam from nongenericity of the 'at' metafunction, which treats Associated Sequences differently from "plain" Forward Sequences [1].
'joint_view' of two maps is simply a Forward Sequence [2], which changes the 'at' semantics from a value lookup in the associative sequence to an equivalent of 'deref< advance< begin<s>::type,n >::type
::type'. Thus the result you observed: 'at<JointMap, int_<2> >::type' simply returns JointMap's third element.
This can be definitely argued to be a design bug.
However, suppose that requesting the map's value by key was spelled differently, say, 'get'. Well, even in this case, unless the 'joint_view' of two Associated Sequences becomes in an Associated Sequence as well, applying 'get' to JointMap still won't work -- although you'd most likely get an error instead of a puzzling result.
All in all, to get the behavior you want with the current library you need to actually merge two maps into a third one.
[1] http://boost.org/libs/mpl/doc/refmanual/at.html [2] http://boost.org/libs/mpl/doc/refmanual/joint-view.html
This is also one of the reasons why Fusion deviates a bit from MPL. In Fusion, we have both at<N> and at_key<K>. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Aleksey Gurtovoy wrote:
Hi Martin,
I have two mpl maps like this:
typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
I try to join them using "joint_view" as follows:
typedef joint_view<Map1, Map2>::type JointMap;
which works fine. Then I do
std::cout << at<JointMap, int_<2> >::type::value << "\n";
which gives the following compiler error:
error: 'value' is not a member of 'boost::mpl::pair<mpl_::int_<3>, mpl_::int_<44> >'
I tried this with gcc 3.4.6 and 4.2 under Linux, Boost version is 1.34.0. It seems "at" returns the entry after the searched entry, and not only the right half, but the complete pair.
Has anybody got any hints on this? To me it looks like a bug in MPL, but I might be wrong.
Both sides of this behavior steam from nongenericity of the 'at' metafunction, which treats Associated Sequences differently from "plain" Forward Sequences [1].
'joint_view' of two maps is simply a Forward Sequence [2], which changes the 'at' semantics from a value lookup in the associative sequence to an equivalent of 'deref< advance< begin<s>::type,n >::type
::type'. Thus the result you observed: 'at<JointMap, int_<2> >::type'
simply returns JointMap's third element.
This can be definitely argued to be a design bug.
However, suppose that requesting the map's value by key was spelled differently, say, 'get'. Well, even in this case, unless the 'joint_view' of two Associated Sequences becomes in an Associated Sequence as well, applying 'get' to JointMap still won't work -- although you'd most likely get an error instead of a puzzling result.
All in all, to get the behavior you want with the current library you need to actually merge two maps into a third one.
[1] http://boost.org/libs/mpl/doc/refmanual/at.html [2] http://boost.org/libs/mpl/doc/refmanual/joint-view.html
HTH,
I'm not sure, if I understand this correctly. What is the recommended way of merging two maps into a third one? Is it possible with the current MPL implementation? I only found an map::insert metafunction to insert a single element, but not a whole range of pairs. Martin ____________ Virus checked: AVKA 17.383 from 13.08.2007

Martin Apel wrote in message news:46C19A4F.9080505@simpack.de...
Aleksey Gurtovoy wrote:
All in all, to get the behavior you want with the current library you need to actually merge two maps into a third one. [...]
I'm not sure, if I understand this correctly. What is the recommended way of merging two maps into a third one? Is it possible with the current MPL implementation?
Sure.
I only found an map::insert metafunction to insert a single element, but not a whole range of pairs.
You can actually to do something along these lines (untested): typedef copy< joint_view<Map1,Map2> , inserter< map0<>, insert<_1,_2> > >::type JointMap; -- Aleksey Gurtovoy MetaCommunications Engineering

Aleksey Gurtovoy wrote:
Martin Apel wrote in message news:46C19A4F.9080505@simpack.de...
Aleksey Gurtovoy wrote:
All in all, to get the behavior you want with the current library you need to actually merge two maps into a third one.
[...]
I'm not sure, if I understand this correctly. What is the recommended way of merging two maps into a third one? Is it possible with the current MPL implementation?
Sure.
I only found an map::insert metafunction to insert a single element, but not a whole range of pairs.
You can actually to do something along these lines (untested):
typedef copy< joint_view<Map1,Map2> , inserter< map0<>, insert<_1,_2> > >::type JointMap;
-- Aleksey Gurtovoy MetaCommunications Engineering
I still had no luck getting this to work. It seems that the typedef for the joint map is OK (I had to change the insert to use a third parameter as follows: typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>::type, _2> >
::type JointMap;
otherwise it wouldn't compile). However as soon as I try to access the result using std::cout << at<JointMap, int_<2> >::type::value << "\n"; I got tons of compile errors, from at_impl.hpp like the following: error: no type named `type' in `struct boost::mpl::advance<mpl_::void_, mpl_::int_<2> >' and advance_forward.hpp:42: error: no type named `type' in `struct boost::mpl::next<mpl_::void_>' It seems that at still is not happy with the type it is given. Regards, Martin ____________ Virus checked: AVKA 17.383 from 13.08.2007

AMDG Martin Apel <martin.apel <at> simpack.de> writes:
I still had no luck getting this to work. It seems that the typedef for the joint map is OK (I had to change the insert to use a third parameter as follows:
typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>::type, _2> >
::type JointMap;
otherwise it wouldn't compile). However as soon as I try to access the result using
std::cout << at<JointMap, int_<2> >::type::value << "\n";
I got tons of compile errors, from at_impl.hpp like the following: <snip>
try typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>, _2> >
::type JointMap;
In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Martin Apel <martin.apel <at> simpack.de> writes:
I still had no luck getting this to work. It seems that the typedef for the joint map is OK (I had to change the insert to use a third parameter as follows:
typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>::type, _2> >
::type JointMap;
otherwise it wouldn't compile). However as soon as I try to access the result using
std::cout << at<JointMap, int_<2> >::type::value << "\n";
I got tons of compile errors, from at_impl.hpp like the following: <snip>
try
typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>, _2> >
::type JointMap;
In Christ, Steven Watanabe
Sorry for the long delay. I was lucky to have a bank holiday yesterday here in southern Germany :-) I tried your minor correction. However it still gives me the same compile errors when instantiating "at": /usr/include/boost/mpl/next_prior.hpp:31: error: no type named `next' in `struct mpl_::void_' /usr/include/boost/mpl/aux_/at_impl.hpp:35: error: no type named `type' in `struct boost::mpl::advance<mpl_::void_, mpl_::int_<2> >' The line causing this looks as follows: std::cout << at<JointMap, int_<2> >::type::value << "\n"; Best Regards, Martin ____________ Virus checked: AVKA 17.384 from 14.08.2007

AMDG Martin Apel <martin.apel <at> simpack.de> writes:
Sorry for the long delay. I was lucky to have a bank holiday yesterday here in southern Germany I tried your minor correction. However it still gives me the same compile errors when instantiating "at":
/usr/include/boost/mpl/next_prior.hpp:31: error: no type named `next' in `struct mpl_::void_' /usr/include/boost/mpl/aux_/at_impl.hpp:35: error: no type named `type' in `struct boost::mpl::advance<mpl_::void_, mpl_::int_<2> >'
The line causing this looks as follows: std::cout << at<JointMap, int_<2> >::type::value << "\n";
Really weird. Try qualifying all the names. I was able to compile this with 1.34.1: #include <boost/mpl/map.hpp> #include <boost/mpl/joint_view.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/insert.hpp> #include <boost/mpl/end.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/copy.hpp> #include <iostream> using namespace boost::mpl; typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>, _2> >
::type JointMap;
int main() { std::cout << at<JointMap, int_<2> >::type::value << "\n"; } In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Martin Apel <martin.apel <at> simpack.de> writes:
Sorry for the long delay. I was lucky to have a bank holiday yesterday here in southern Germany I tried your minor correction. However it still gives me the same compile errors when instantiating "at":
/usr/include/boost/mpl/next_prior.hpp:31: error: no type named `next' in `struct mpl_::void_' /usr/include/boost/mpl/aux_/at_impl.hpp:35: error: no type named `type' in `struct boost::mpl::advance<mpl_::void_, mpl_::int_<2> >'
The line causing this looks as follows: std::cout << at<JointMap, int_<2> >::type::value << "\n";
Really weird. Try qualifying all the names. I was able to compile this with 1.34.1:
#include <boost/mpl/map.hpp> #include <boost/mpl/joint_view.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/insert.hpp> #include <boost/mpl/end.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/copy.hpp> #include <iostream>
using namespace boost::mpl;
typedef map<pair<int_<1>, int_<42> >, pair<int_<2>, int_<43> >, pair<int_<3>, int_<44> >
Map1;
typedef map<pair<int_<4>, int_<44> >, pair<int_<5>, int_<45> >, pair<int_<6>, int_<46> >
Map2;
typedef copy< joint_view<Map1,Map2>, inserter <map0<>, insert<_1, end<_1>, _2> >
::type JointMap;
int main() { std::cout << at<JointMap, int_<2> >::type::value << "\n"; }
In Christ, Steven Watanabe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Hi Steven, I finally found the problem. Instead of boost/mpl/insert.hpp I had included boost/mpl/insert_range.hpp, which led to the strange compilation errors. I had tried out a couple of variations including using insert_range, so this is where it came from. Thanks a lot for your help. Best Regards, Martin ____________ Virus checked: AVKA 17.384 from 14.08.2007

on Fri Aug 17 2007, Martin Apel <martin.apel-AT-simpack.de> wrote: <snip entire foregoing thread>
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Hi Steven,
I finally found the problem. Instead of boost/mpl/insert.hpp I had included boost/mpl/insert_range.hpp, which led to the strange compilation errors. I had tried out a couple of variations including using insert_range, so this is where it came from. Thanks a lot for your help.
Everyone, please remember to edit the quotations included in your posts so they include only the necessary parts. http://www.boost.org/more/discussion_policy.htm#effective Thank you, -- Dave Abrahams Boost Moderator
participants (5)
-
Aleksey Gurtovoy
-
David Abrahams
-
Joel de Guzman
-
Martin Apel
-
Steven Watanabe