Copy MPL sequence at runtime?

Evening all, I'd like to copy the contents of a boost::mpl::vector_c (or similar) into an output iterator at runtime. I've not found a clean way to get an MPL sequence into a runtime-usable form. So far, I've gotten the included ugliness to work. 0) Is there some simple, idiomatic way to accomplish this goal that I've missed? 1) Any suggestions for how to clean this up? Specifically ways to reduce the assumptions about the underlying MPL sequence or fixes for braindead mistakes I've made? 2) Is there some way to have syntax like 'seqcopy<S>(iter)' where the iterator type is deduced but the sequence type is explicit? Thanks, Rhys #define BOOST_TEST_MODULE $Id: test_mpl.cc 996 2010-03-18 07:04:23Z rhys $ #include <boost/mpl/empty.hpp> #include <boost/mpl/front.hpp> #include <boost/mpl/pop_front.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/utility.hpp> #include <boost/test/included/unit_test.hpp> using boost::disable_if; using boost::mpl::empty; using boost::mpl::front; using boost::mpl::pop_front; template<typename S, typename FI, class Enable = void> struct seqcopy { void operator()(FI fi) {} }; template<typename S, typename FI> struct seqcopy<S, FI, typename disable_if<typename empty<S>::type>::type> { void operator()(FI fi) { *fi++ = front<S>::type::value; seqcopy<typename pop_front<S>::type, FI>()(fi); } }; BOOST_AUTO_TEST_CASE( testing ) { typedef boost::mpl::vector_c<int,2,4,6> values; int a[3]; seqcopy<values, int*>()(a); BOOST_CHECK_EQUAL(a[0], 2); BOOST_CHECK_EQUAL(a[1], 4); BOOST_CHECK_EQUAL(a[2], 6); }

Rhys Ulerich wrote:
Evening all,
I'd like to copy the contents of a boost::mpl::vector_c (or similar) into an output iterator at runtime. I've not found a clean way to get an MPL sequence into a runtime-usable form. So far, I've gotten the included ugliness to work.
0) Is there some simple, idiomatic way to accomplish this goal that I've missed? 1) Any suggestions for how to clean this up? Specifically ways to reduce the assumptions about the underlying MPL sequence or fixes for braindead mistakes I've made? 2) Is there some way to have syntax like 'seqcopy<S>(iter)' where the iterator type is deduced but the sequence type is explicit?
Thanks, Rhys
Good morning, 0) the "only" run-time stuff in the MPL is mpl::for_each. 1) See attached, I guess this could be considered a bit cleaner. 2) Probably easiest by writing a function that does the type deduction for you. But ... Perhaps Boost.Fusion is what you are looking for? Hope this helps, Cheers, Rutger

Rutger ter Borg schrieb:
Rhys Ulerich wrote:
Good morning,
0) the "only" run-time stuff in the MPL is mpl::for_each.
Chapter 9 of the book c++ template metaprogramming from Abrahams and Gurtovoy gives an explanation about mpl::for_each with type visitation. hth Cheers, Kim
1) See attached, I guess this could be considered a bit cleaner. 2) Probably easiest by writing a function that does the type deduction for you.

AMDG Rutger ter Borg wrote:
Rhys Ulerich wrote:
I'd like to copy the contents of a boost::mpl::vector_c (or similar) into an output iterator at runtime. I've not found a clean way to get an MPL sequence into a runtime-usable form. So far, I've gotten the included ugliness to work.
0) Is there some simple, idiomatic way to accomplish this goal that I've missed? 1) Any suggestions for how to clean this up? Specifically ways to reduce the assumptions about the underlying MPL sequence or fixes for braindead mistakes I've made? 2) Is there some way to have syntax like 'seqcopy<S>(iter)' where the iterator type is deduced but the sequence type is explicit?
Good morning,
0) the "only" run-time stuff in the MPL is mpl::for_each. 1) See attached, I guess this could be considered a bit cleaner. 2) Probably easiest by writing a function that does the type deduction for you.
How about this #include <boost/mpl/int.hpp> #include <boost/mpl/for_each.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/lambda/lambda.hpp> #include <iostream> #include <iterator> using namespace boost; using namespace boost::lambda; int main() { typedef boost::mpl::vector_c<int,2,4,6> values; int output[3]; int* iter = &output[0]; mpl::for_each< values >( *var(iter)++ = _1 ); std::copy( &output[0], &output[3], std::ostream_iterator<int>( std::cout, " " ) ); } In Christ, Steven Watanabe

I'd like to copy the contents of a boost::mpl::vector_c (or similar) into an output iterator at runtime.
Thank you for the help Rutger, Kim, and Steven, and especially for the mpl::for_each examples and the copy functor. The more complete use case was to turn an MPL sequence into a form usable within an initialization list for either boost::array or something requiring an iterator. For completeness, the helper class I finally went with is below. I appreciate your expertise, Rhys #define BOOST_TEST_MODULE $Id: test_mpl.cc 999 2010-03-18 15:08:46Z rhys $ #include <boost/array.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/mpl/for_each.hpp> #include <boost/mpl/size.hpp> #include <boost/test/included/unit_test.hpp> template< typename Sequence > class sequence_array : public boost::array< typename Sequence::value_type, boost::mpl::size<Sequence>::type::value > { typedef typename boost::array< typename Sequence::value_type, boost::mpl::size<Sequence>::type::value >::iterator iterator; struct copier_ { copier_(iterator it) : it_(it) {} template<typename U> void operator()(U u) { *(it_++) = u; } iterator it_; }; public: sequence_array() { boost::mpl::for_each<Sequence>(copier_(this->begin())); } }; BOOST_AUTO_TEST_CASE( testing ) { sequence_array< boost::mpl::vector_c<int,2,4,6> > a; BOOST_CHECK_EQUAL(a[0], 2); BOOST_CHECK_EQUAL(a[1], 4); BOOST_CHECK_EQUAL(a[2], 6); boost::array<int, 3> b = { 2, 4, 6 }; BOOST_CHECK( b == a ); BOOST_CHECK( a == b ); }
participants (4)
-
Kim Kuen Tang
-
Rhys Ulerich
-
Rutger ter Borg
-
Steven Watanabe