[MPL][FUSION] generate fusion::map from mpl::vector
Hi, I get as template parameter a mpl::vector with various types. Now want to generate one object of each type. To do so, i like to generate a fusion::map, which has as key the type itself (from the mpl::vector) and as object e.g. boost::promise_stream< type >. Well this is what i've got so far: template< typename OutSignatures > class filter_impl{ typedef typename mpl::transform< OutSignatures, boost::promise_stream<mpl::_1> >::type OutStreams; typedef typename mpl::transform< OutSignatures, OutStreams, fusion::make_pair< mpl::_1, mpl::_2 > >::type OutPairs; typedef typename fusion::result_of::as_map< fusion::vector< OutPairs >
::type Out_type;
} This compiles fine. But i'm not able to generate some fusion::map from the Out_type. I get compiling errors than. Well I'm new to the whole MPL and fusion stuff. Am i doing the right things? Or maybe my goal could be achived easier? Thanks for any hints, Kind Regards Manuel
Manuel Jung <gzahl <at> arcor.de> writes:
Hi,
I get as template parameter a mpl::vector with various types. Now want to generate one object of each type. To do so, i like to generate a fusion::map, which has as key the type itself (from the mpl::vector) and as object e.g. boost::promise_stream< type >.
Well this is what i've got so far:
<snip>
This compiles fine. But i'm not able to generate some fusion::map from the Out_type. I get compiling errors than. Well I'm new to the whole MPL and fusion stuff. Am i doing the right things? Or maybe my goal could be achived easier?
I don't have a compiler handy, so I couldn't attempt to compile your code to see if there was a simple fix, but the following should work (untested): namespace fusion = boost::fusion; namespace mpl = boost::mpl; template<typename T> struct make_out_signature_pair { typedef typename fusion::result_of::make_pair < T, boost::promise_stream<T> >::type type; }; template<typename OutSignatures> struct filter_impl { typedef typename fusion::result_of::as_map < typename mpl::transform < OutSignatures, make_out_signature_pair<mpl::_1> >::type >::type OutMap; }; filter_impl<Sequence>::OutMap is now an instantiable fusion::map. Two noteworthy things: First, the value type of the map (e.g. boost::promise_stream) must be default constructable. Second, by default the maximum size of an mpl::vector is 20 and of a fusion::map is 10. So if you have 10+ elements in your OutSignatures sequence, you'll need to define the BOOST_MPL_LIMIT_VECTOR_SIZE and/or FUSION_MAX_MAP_SIZE macros before including any boost headers. See http://ln-s.net/2GhE and http://ln-s.net/2GhF for more details.
Manuel Jung <gzahl <at> arcor.de> writes:
Well this is what i've got so far:
template< typename OutSignatures > class filter_impl{ typedef typename mpl::transform< OutSignatures, boost::promise_stream<mpl::_1> >::type OutStreams;
typedef typename mpl::transform< OutSignatures, OutStreams, fusion::make_pair< mpl::_1, mpl::_2 > >::type OutPairs;
typedef typename fusion::result_of::as_map< fusion::vector< OutPairs >
::type Out_type;
}
This compiles fine. But i'm not able to generate some fusion::map from the Out_type. I get compiling errors than.
Upon looking at your original code further, there does indeed appear to be a trivial fix to get it to compile -- add result_of:: before make_pair, and get rid of fusion::vector<> around OutPairs: template<typename OutSignatures> struct filter_impl { typedef typename mpl::transform < OutSignatures, boost::promise_stream<mpl::_1> >::type OutStreams; typedef typename mpl::transform < OutSignatures, OutStreams, fusion::result_of::make_pair<mpl::_1, mpl::_2> >::type OutPairs; typedef typename fusion::result_of::as_map<OutPairs>::type OutMap; }; This can now be reduced to the more succinct: template<typename OutSignatures> struct filter_impl { typedef typename fusion::result_of::as_map < typename mpl::transform < OutSignatures, fusion::result_of::make_pair < mpl::_1, boost::promise_stream<mpl::_1> > >::type >::type OutMap; };
Adam Merz wrote: Hey,
Manuel Jung <gzahl <at> arcor.de> writes:
Well this is what i've got so far:
template< typename OutSignatures > class filter_impl{ typedef typename mpl::transform< OutSignatures, boost::promise_stream<mpl::_1> >::type OutStreams;
typedef typename mpl::transform< OutSignatures, OutStreams, fusion::make_pair< mpl::_1, mpl::_2 > >::type OutPairs;
typedef typename fusion::result_of::as_map< fusion::vector< OutPairs >
::type Out_type;
}
This compiles fine. But i'm not able to generate some fusion::map from the Out_type. I get compiling errors than.
Upon looking at your original code further, there does indeed appear to be a trivial fix to get it to compile -- add result_of:: before make_pair, and get rid of fusion::vector<> around OutPairs:
template<typename OutSignatures> struct filter_impl { typedef typename mpl::transform < OutSignatures, boost::promise_stream<mpl::_1> >::type OutStreams;
typedef typename mpl::transform < OutSignatures, OutStreams, fusion::result_of::make_pair<mpl::_1, mpl::_2> >::type OutPairs;
typedef typename fusion::result_of::as_map<OutPairs>::type OutMap; };
This can now be reduced to the more succinct:
template<typename OutSignatures> struct filter_impl { typedef typename fusion::result_of::as_map < typename mpl::transform < OutSignatures, fusion::result_of::make_pair < mpl::_1, boost::promise_stream<mpl::_1> > >::type >::type OutMap; };
Well this looks nice, but it doesn't compile for me. I attached the compile errors output. Thanks!
AMDG Manuel Jung wrote:
Well this looks nice, but it doesn't compile for me. I attached the compile errors output. Thanks!
The following compiles for me. #include <boost/fusion/include/map.hpp> #include <boost/fusion/include/mpl.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/transform.hpp> namespace mpl = boost::mpl; namespace fusion = boost::fusion; namespace boost { template<class T> class promise_stream {}; } template< typename OutSignatures > struct filter_impl{ typedef typename fusion::result_of::as_map< typename mpl::transform< OutSignatures, fusion::pair<mpl::_1, boost::promise_stream<mpl::_1> > >::type >::type Out_type; }; #include <iostream> #include <typeinfo> int main() { std::cout << typeid(filter_impl<mpl::vector<int, char, double>
::Out_type).name() << std::endl; }
In Christ, Steven Watanabe
participants (3)
-
Adam Merz
-
Manuel Jung
-
Steven Watanabe