[mpl][fusion] Metafunction for extracting a type from a map
Hi there, next metaprogramming problem. Is it possible to extract a tagged type from a map? namespace fields { struct _id_; struct _name_; struct _birthday_; struct _address_id_; } namespace tags { struct _primary_key_; struct _foreign_key_; struct _value_; } typedef fusion::map< fusion::vector< fields::_id_ , std::string, tags::_primary_key_ > , fusion::vector< fields::_name_ , std::string, tags::_value_ > , fusion::vector< fields::_birthday_ , std::string, tags::_value_ > , fusion::vector< fields::_address_id_, std::string, tags::_foreign_key_ > > table_type; int main() { /// how to get the primary key type vector } I was looking at fusion's filter_view but that is only available for non-metaprogramming. Any ideas? Christian
Christian Henning wrote:
Hi there, next metaprogramming problem. Is it possible to extract a tagged type from a map?
namespace fields { struct _id_; struct _name_; struct _birthday_; struct _address_id_; }
namespace tags { struct _primary_key_; struct _foreign_key_; struct _value_; }
typedef fusion::map< fusion::vector< fields::_id_ , std::string, tags::_primary_key_ > , fusion::vector< fields::_name_ , std::string, tags::_value_ > , fusion::vector< fields::_birthday_ , std::string, tags::_value_ > , fusion::vector< fields::_address_id_, std::string, tags::_foreign_key_ > > table_type;
int main() { /// how to get the primary key type vector }
at_key<fields::_id_>(m) ???
I was looking at fusion's filter_view but that is only available for non-metaprogramming.
Not sure what you mean. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
Sorry for my bad problem description. Basically I have a map of type vectors. On element in the vector is used for tagging. I need a metafunction that can retrieve the type vector that that's is tagged with the _primary_key_ type. There is only one vector. I would also need the same functionality for the _foreign_key_ type. Here, it can be several type vectors. The MPL lib has a find_if metafunction that looks like the right way to do. But I haven't tried it yet. Is this description better? Christian On 3/19/07, Joel de Guzman <joel@boost-consulting.com> wrote:
Christian Henning wrote:
Hi there, next metaprogramming problem. Is it possible to extract a tagged type from a map?
namespace fields { struct _id_; struct _name_; struct _birthday_; struct _address_id_; }
namespace tags { struct _primary_key_; struct _foreign_key_; struct _value_; }
typedef fusion::map< fusion::vector< fields::_id_ , std::string, tags::_primary_key_ > , fusion::vector< fields::_name_ , std::string, tags::_value_ > , fusion::vector< fields::_birthday_ , std::string, tags::_value_ > , fusion::vector< fields::_address_id_, std::string, tags::_foreign_key_ > > table_type;
int main() { /// how to get the primary key type vector }
at_key<fields::_id_>(m) ???
I was looking at fusion's filter_view but that is only available for non-metaprogramming.
Not sure what you mean.
Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Christian Henning wrote:
Sorry for my bad problem description. Basically I have a map of type vectors. On element in the vector is used for tagging. I need a metafunction that can retrieve the type vector that that's is tagged with the _primary_key_ type. There is only one vector. I would also need the same functionality for the _foreign_key_ type. Here, it can be several type vectors.
The MPL lib has a find_if metafunction that looks like the right way to do. But I haven't tried it yet.
Is this description better?
Have you tried (either): result_of::at_key<S, K>::type result_of::value_at_key<S, K>::type ?? Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
I think the following example serves better for understanding my problem. I don't think that at_key is the right way to go. Instead, I'm looking for something like that finds me the right key for a value. #include <boost/fusion/sequence.hpp> using namespace std; using namespace boost; namespace fields { struct id {}; struct name {}; struct address {}; struct birthday {}; } namespace tags { struct pri {}; struct val {}; } typedef fusion::map< fusion::pair< fields::id, tags::pri > , fusion::pair< fields::name, tags::val > , fusion::pair< fields::address, tags::val > , fusion::pair< fields::birthday, tags::val > > table; int _tmain(int argc, _TCHAR* argv[]) { BOOST_STATIC_ASSERT((is_same< fusion::result_of::???< table , tags::pri >::type , fields::id >::value )); return 0; } Does that makes sense, now? Christian
Christian Henning wrote:
I think the following example serves better for understanding my problem. I don't think that at_key is the right way to go. Instead, I'm looking for something like that finds me the right key for a value.
[snips]
Does that makes sense, now?
Sorry, no :( Do you mean you want a reverse lookup? You have a value and you want the key associated with it? Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
Hi there, I think I was wrong when I was using a map. Instead I should have presented my code using a vector. Here is another try to explain in what I'm looking for. Image a 2D matrix of types. Meaning a vector of types vectors. Like: namespace fields { struct id {}; struct name {}; struct address {}; struct birthday {}; } namespace tags { struct pri {}; struct val {}; } typedef fusion::vector<fields::id, tags::pri> primary_key_t; typedef fusion::vector<fields::name, tags::val> name_field_t; typedef fusion::vector<fields::name, tags::val> address_field_t; typedef fusion::vector<fields::name, tags::val> birthday__field_t; typedef fusion::vector< primary_key_t , name_field_t , address_field_t , birthday__field_t > table; My question is how can I find the type vector that contains a certain type, like for example tags::pri? Is such functionality supported by either fusion or mpl? Thanks again, Christian
On 3/22/07, Christian Henning <chhenning@gmail.com> wrote:
Hi there,
My question is how can I find the type vector that contains a certain type, like for example tags::pri?
Is such functionality supported by either fusion or mpl?
You probably want something like: find_if http://www.boost.org/libs/mpl/doc/refmanual/find-if.html Chris
Thanks Chris for the quick response. I was trying find_if but I don't think it provides the whole solution. Below is the minimal example, that doesn't compile since the static assertion fires. #include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp> using namespace std; using namespace boost; typedef mpl::vector<char, char> vec_1; typedef mpl::vector<char, int> vec_2; typedef mpl::vector<vec_1, vec_2> mat; typedef mpl::find_if<mat, is_same<mpl::_1, int> >::type iter; int _tmain(int argc, _TCHAR* argv[]) { BOOST_STATIC_ASSERT(( is_same< mpl::deref<iter>::type, vec_2 >::value )); return 0; } Do you know what I'm missing here? Christian
On 3/22/07, Christian Henning <chhenning@gmail.com> wrote:
Thanks Chris for the quick response. I was trying find_if but I don't think it provides the whole solution. Below is the minimal example, that doesn't compile since the static assertion fires.
#include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp>
using namespace std; using namespace boost;
typedef mpl::vector<char, char> vec_1; typedef mpl::vector<char, int> vec_2;
typedef mpl::vector<vec_1, vec_2> mat;
I would think you need to use mpl::at_c here. I haven't test this, but how about: typedef mpl::find_if<mat, is_same<mpl::at_c<mpl::_1,1>, int> >::type iter;
int _tmain(int argc, _TCHAR* argv[]) { BOOST_STATIC_ASSERT(( is_same< mpl::deref<iter>::type, vec_2 >::value ));
return 0; }
Do you know what I'm missing here?
Christian _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks, I tried it but seems like my compiler (MSVC 7.1) doesn't eat it. The error messages are: c:\boost\boost\mpl\aux_\preprocessed\plain\apply_wrap.hpp(38) : error C2903: 'apply' : symbol is neither a class template nor a function template c:\boost\boost\mpl\aux_\preprocessed\plain\apply.hpp(43) : see reference to class template instantiation 'boost::mpl::apply_wrap1<F,T1>' being compiled with [ F=boost::mpl::lambda<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>::type, T1=boost::mpl::deref<boost::mpl::aux::iter_fold_if_null_step<boost::mpl::iter_fold_if<mat,void,boost::mpl::arg<1>,boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>>>::first_,void>::iterator>::type ] c:\boost\boost\mpl\aux_\iter_apply.hpp(28) : see reference to class template instantiation 'boost::mpl::apply1<F,T1>' being compiled with [ F=boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>, T1=boost::mpl::deref<boost::mpl::aux::iter_fold_if_null_step<boost::mpl::iter_fold_if<mat,void,boost::mpl::arg<1>,boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>>>::first_,void>::iterator>::type ] c:\boost\boost\mpl\not.hpp(41) : see reference to class template instantiation 'boost::mpl::aux::iter_apply1<F,Iterator>' being compiled with [ F=boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>, Iterator=boost::mpl::aux::iter_fold_if_null_step<boost::mpl::iter_fold_if<mat,void,boost::mpl::arg<1>,boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>>>::first_,void>::iterator ] c:\boost\boost\mpl\aux_\preprocessed\plain\and.hpp(25) : see reference to class template instantiation 'boost::mpl::not_<T>' being compiled with [ T=boost::mpl::aux::iter_apply1<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>,boost::mpl::aux::iter_fold_if_null_step<boost::mpl::iter_fold_if<mat,void,boost::mpl::arg<1>,boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>>>::first_,void>::iterator> ] c:\boost\boost\mpl\aux_\preprocessed\plain\and.hpp(55) : see reference to class template instantiation 'boost::mpl::aux::and_impl<C_,T1,T2,T3,T4>' being compiled with [ C_=true, T1=boost::mpl::apply1<boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>>,boost::mpl::aux::iter_fold_if_null_step<boost::mpl::iter_fold_if<mat,void,boost::mpl::arg<1>,boost::mpl::protect<boost::mpl::aux::find_if_pred<boost::is_same<boost::mpl::at_c<boost::mpl::_1,1>,int>>>>::first_,void>::iterator>, T2=boost::mpl::true_, T3=boost::mpl::true_, T4=boost::mpl::true_ ] [snip] The code looks like this: #include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp> #include <boost/mpl/at.hpp> using namespace std; using namespace boost; typedef mpl::vector<char, char> vec_1; typedef mpl::vector<char, int> vec_2; typedef mpl::vector<vec_1, vec_2> mat; //typedef mpl::find_if<mat, is_same<mpl::_1, int> >::type iter; typedef mpl::find_if<mat, is_same<mpl::at_c<mpl::_1,1>, int> >::type iter; int _tmain(int argc, _TCHAR* argv[]) { BOOST_STATIC_ASSERT(( is_same< mpl::deref<iter>::type, vec_2 >::value )); return 0; } Regards, Christian On 3/22/07, Chris Weed <chrisweed@gmail.com> wrote:
On 3/22/07, Christian Henning <chhenning@gmail.com> wrote:
Thanks Chris for the quick response. I was trying find_if but I don't think it provides the whole solution. Below is the minimal example, that doesn't compile since the static assertion fires.
#include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp>
using namespace std; using namespace boost;
typedef mpl::vector<char, char> vec_1; typedef mpl::vector<char, int> vec_2;
typedef mpl::vector<vec_1, vec_2> mat;
I would think you need to use mpl::at_c here. I haven't test this, but how about:
typedef mpl::find_if<mat, is_same<mpl::at_c<mpl::_1,1>, int> >::type iter;
int _tmain(int argc, _TCHAR* argv[]) { BOOST_STATIC_ASSERT(( is_same< mpl::deref<iter>::type, vec_2 >::value ));
return 0; }
Do you know what I'm missing here?
Christian _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Chris Weed
-
Christian Henning
-
Joel de Guzman