On 2011-08-26 12:30:42 +0000, Martin B. said:
Hi!
Say I have a range R and I want to construct a new container from the range R. Will I always have to repeat the expression yielding the range, or is there a shorter way?
This is an interesting topic. There is *almost* a way to do what you want, using boost assign list_of, as per the example below. Note that I am assuming that you want to do this efficiently, hence use the slightly less convenient (because of the size parameter) cref_list_of function. There are two main problems with this approach. 1. The initial element of the range has to be explictly provided to cref_list_of. This is the 0 element in the examples below. 2. The range() function for cref_list_of completely fails when using a boost::irange. With the exception of the initial value, the container is filled with the final value of the irange (5 in this example). This looks like a bug to me… It would be really good to get boost assign enhanced to remove these limitations. In fact I wonder if it would be particularly hard to implement an assign::range_of function which uses the same underlying mechanism (ie an object which is convertible to the requisite container type). #define BOOST_TEST_MODULE assignrange #include <boost/test/unit_test.hpp> #include <boost/array.hpp> #include <boost/assign/list_of.hpp> #include <boost/range/irange.hpp> BOOST_AUTO_TEST_CASE(assignrange) { const boost::array<int, 5> input = {{ 1, 2, 3, 4, 5 }}; const std::vector<int> ivec = boost::assign::cref_list_of<6>(0).range(input); const boost::array<int, 6> expected = {{ 0, 1, 2, 3, 4, 5 }}; // Test passes BOOST_CHECK_EQUAL_COLLECTIONS(ivec.begin(), ivec.end(), expected.begin(), expected.end()); } BOOST_AUTO_TEST_CASE(assignirange) { const std::vector<int> ivec = boost::assign::cref_list_of<6>(0).range(boost::irange(1,6)); const boost::array<int, 6> expected = {{ 0, 1, 2, 3, 4, 5 }}; // Test fails! BOOST_CHECK_EQUAL_COLLECTIONS(ivec.begin(), ivec.end(), expected.begin(), expected.end()); }