[mpl] find_all type vectors in a type matrix that match a predicate.

Hi there, is it possible to find all type vectors in a type matrix ( 2D type vector ) that match a predicate? In the end I would like to have them in another type matrix. Can somebody point out how I would put together such a metafunction? I'm not sure if the mpl lib supports my feature request. Consider the following code: #include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp> #include <boost/mpl/at.hpp> using namespace std; using namespace boost; namespace fields { struct id {}; struct name {}; struct address {}; struct birthday {}; } namespace tags { struct primary {}; struct foreign {}; struct no_key {}; } typedef mpl::vector<fields::id , tags::primary> id_field_t; typedef mpl::vector<fields::name , tags::foreign> name_field_t; typedef mpl::vector<fields::address , tags::foreign> address_field_t; typedef mpl::vector<fields::birthday, tags::no_key> birthday_field_t; typedef mpl::vector< id_field_t , name_field_t , address_field_t , birthday_field_t > table; // aggregate all foreign keys in the following vector typedef mpl::vector0<> foreign_keys; /// ??? metafunction for aggregating all foreign keys ??? int main() { return 0; } BTW, I'm not particular interested in a certain order of the aggregated type vectors. Reagrds, Christian

on Sun Apr 01 2007, "Christian Henning" <chhenning-AT-gmail.com> wrote:
Hi there,
is it possible to find all type vectors in a type matrix ( 2D type vector ) that match a predicate? In the end I would like to have them in another type matrix.
How about using filter_view?
Can somebody point out how I would put together such a metafunction? I'm not sure if the mpl lib supports my feature request.
Consider the following code:
#include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp> #include <boost/mpl/at.hpp>
using namespace std; using namespace boost;
namespace fields { struct id {}; struct name {}; struct address {}; struct birthday {}; }
namespace tags { struct primary {}; struct foreign {}; struct no_key {}; }
typedef mpl::vector<fields::id , tags::primary> id_field_t; typedef mpl::vector<fields::name , tags::foreign> name_field_t; typedef mpl::vector<fields::address , tags::foreign> address_field_t; typedef mpl::vector<fields::birthday, tags::no_key> birthday_field_t;
typedef mpl::vector< id_field_t , name_field_t , address_field_t , birthday_field_t > table;
// untested mpl::filter_view<table, mpl::is_same<mpl::back<_>, tags::foreign> > You can copy the filter_view into a vector if you want to, but you're probably better off just using it as though it were a vector. -- Dave Abrahams Boost Consulting www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

Thanks David, it works beautifully. Here is my code including conversion to fusion list plus printing of the foreign key fields. #include "boost/mpl/vector.hpp" #include <boost/mpl/find_if.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/filter_view.hpp> #include <boost/fusion/sequence.hpp> #include <boost/fusion/algorithm.hpp> using namespace std; using namespace boost; namespace fields { struct id { void print() { cout << "id" << endl; } }; struct name { void print() { cout << "name" << endl;} }; struct address { void print() { cout << "address" << endl; }}; struct birthday { void print() { cout << "birthday" << endl; }}; } namespace tags { struct primary {}; struct foreign {}; struct no_key {}; } typedef mpl::vector<fields::id , tags::primary> id_field_t; typedef mpl::vector<fields::name , tags::foreign> name_field_t; typedef mpl::vector<fields::address , tags::foreign> address_field_t; typedef mpl::vector<fields::birthday, tags::no_key> birthday_field_t; typedef mpl::vector< id_field_t , name_field_t , address_field_t , birthday_field_t > table; // find all foreign keys fields typedef mpl::filter_view<table, is_same<mpl::back<mpl::_>, tags::foreign> >::type iter_2; typedef fusion::result_of::as_list<iter_2>::type foreign_keys_t; struct print { template <typename T> void operator()( T const& vec ) const { fusion::at<mpl::int_<0> >(vec).print(); } }; int _tmain(int argc, _TCHAR* argv[]) { BOOST_STATIC_ASSERT(( is_same< mpl::deref<iter>::type, id_field_t
::value ));
foreign_keys_t foreign_keys; for_each( foreign_keys, do_something() ); return 0; }

on Mon Apr 02 2007, "Christian Henning" <chhenning-AT-gmail.com> wrote:
// find all foreign keys fields typedef mpl::filter_view<table, is_same<mpl::back<mpl::_>, tags::foreign> >::type iter_2; ^^^^^^ not needed
Why are you calling this type sequence "iter_2"? It's not an iterator, is it? -- Dave Abrahams Boost Consulting www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com

// find all foreign keys fields typedef mpl::filter_view<table, is_same<mpl::back<mpl::_>, tags::foreign> >::type iter_2; ^^^^^^ not needed
Why are you calling this type sequence "iter_2"? It's not an iterator, is it?
Sorry this was my error. But how can I use the filter_view result to do something useful? For what I understand the filter_view results in a lazy forward sequence and though, why not use it with the transform1 algorithm. The following code displays what I trying to do. #include "boost/mpl/vector.hpp" #include "boost/mpl/list.hpp" #include <boost/mpl/find_if.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/filter_view.hpp> #include <boost/mpl/transform.hpp> using namespace std; using namespace boost; namespace fields { struct id { void print() { cout << "id" << endl; } }; struct name { void print() { cout << "name" << endl;} }; struct address { void print() { cout << "address" << endl; }}; struct birthday { void print() { cout << "birthday" << endl; }}; } namespace tags { struct primary {}; struct foreign {}; struct no_key {}; } typedef mpl::vector<fields::id , tags::primary> id_field_t; typedef mpl::vector<fields::name , tags::foreign> name_field_t; typedef mpl::vector<fields::address , tags::foreign> address_field_t; typedef mpl::vector<fields::birthday, tags::no_key> birthday_field_t; typedef mpl::vector< id_field_t , name_field_t , address_field_t , birthday_field_t > table; // finds primary key field typedef mpl::find_if< table, is_same< mpl::at< mpl::_1, mpl::int_<1>
, tags::primary > >::type primary_key_t;
template <typename T> struct add_vector { typedef mpl::at_c< T, 0 >::type field_t; typedef std::vector<field_t> type; }; // find all foreign keys fields typedef mpl::filter_view<table, is_same<mpl::back<mpl::_>, tags::foreign> > foreign_keys_view_t; typedef mpl::transform1< foreign_keys_view_t, add_vector<mpl::_1>
::type foreign_key_vectors_t;
int _tmain(int argc, _TCHAR* argv[]) { return 0; } Regards, Christian

On Mon, April 2, 2007 18:05, Christian Henning wrote:
// find all foreign keys fields typedef mpl::filter_view<table, is_same<mpl::back<mpl::_>, tags::foreign> >::type iter_2; ^^^^^^ not needed
Why are you calling this type sequence "iter_2"? It's not an iterator, is it?
Sorry this was my error. But how can I use the filter_view result to do something useful? For what I understand the filter_view results in a lazy forward sequence and though, why not use it with the transform1 algorithm. The following code displays what I trying to do.
Sorry to intervene this discussion and may be put into other direction... Looks like you are going to emulate a db-table-like view? If so why don't you like the idea of using Boost.MultiIndex lib? It is extremely powerful (also offers the tag dispatching techniques), already debugged, easy to use and very flexible... With Kind Regards, Ovanes Markarian

Sorry to intervene this discussion and may be put into other direction... Looks like you are going to emulate a db-table-like view? If so why don't you like the idea of using Boost.MultiIndex lib? It is extremely powerful (also offers the tag dispatching techniques), already debugged, easy to use and very flexible...
I'm always open for new ideas. I have never dealt with boost::MultiIndex. So I'm not aware of the advantages in using it for my project. I will take a look at it. Is there any sample code that does something similar? Regards, Christian

On Mon, April 2, 2007 19:12, Christian Henning wrote:
Sorry to intervene this discussion and may be put into other direction... Looks like you are going to emulate a db-table-like view? If so why don't you like the idea of using Boost.MultiIndex lib? It is extremely powerful (also offers the tag dispatching techniques), already debugged, easy to use and very flexible...
I'm always open for new ideas. I have never dealt with boost::MultiIndex. So I'm not aware of the advantages in using it for my project. I will take a look at it. Is there any sample code that does something similar?
Regards, Christian _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
With MultiIndex you can index columns of a table with some best suitable view concepts. For example one view to the table can be defined using the hashing function and find extremely quickly the required entry or another view can index the same column by its order (how the elements are naturally inserted) and much more. I suggest you to take a look at this tutorial: http://www.boost.org/libs/multi_index/doc/tutorial.html With Kind Regards, Ovanes Markarian
participants (3)
-
Christian Henning
-
David Abrahams
-
Ovanes Markarian