range addition - generic constructor

It is not unusual to need to construct a container from another where one or the other doesn't comply with sequence. When generic code needs to convert to a container of unknown type (e.g., the return container type of a function is a template parameter), a generic constructor is useful, and could be part of range. Here is the idea: #ifndef const_from_range_hpp #define const_from_range_hpp #include <boost/range.hpp> #include <algorithm> #include <boost/numeric/ublas/vector.hpp> namespace detail { template<typename cont_t, typename range> struct construct_from_range_impl { cont_t operator() (range const& r) { return cont_t (boost::begin (r), boost::end (r)); } }; template<typename T, typename range> struct construct_from_range_impl<boost::numeric::ublas::vector<T>, range> { typedef typename boost::numeric::ublas::vector<T> ret_t; ret_t operator() (range const& r) { ret_t v (boost::size (r)); std::copy (boost::begin (r), boost::end (r), v.begin()); return v; } }; } template<typename cont_t, typename range> cont_t construct_from_range (range const& r) { return detail::construct_from_range_impl<cont_t,range>() (r); } #endif Here is a test example: #include "const_from_range.hpp" #include <vector> #include <boost/numeric/ublas/vector.hpp> namespace ublas = boost::numeric::ublas; // simple example int main() { std::vector<int> v (10); ublas::vector<int> w = construct_from_range<ublas::vector<int> > (v); } // more realistic example template<typename cont_t> cont_t F () { std::vector<int> v (10); do_something(); return construct_from_range<cont_t> (v); }

"Neal Becker" <ndbecker2@verizon.net> wrote in message news:chvoo4$qbl$1@sea.gmane.org... | It is not unusual to need to construct a container from another where one or | the other doesn't comply with sequence. | | When generic code needs to convert to a container of unknown type (e.g., the | return container type of a function is a template parameter), a generic | constructor is useful, and could be part of range. Here is the idea: | | #ifndef const_from_range_hpp | #define const_from_range_hpp | | #include <boost/range.hpp> | #include <algorithm> | #include <boost/numeric/ublas/vector.hpp> | | namespace detail { | template<typename cont_t, typename range> | struct construct_from_range_impl { | cont_t operator() (range const& r) { | return cont_t (boost::begin (r), boost::end (r)); | } | }; Please see the "Utility" section of the docs. You would be looking for copy_range(). | template<typename T, typename range> | struct construct_from_range_impl<boost::numeric::ublas::vector<T>, range> | { | typedef typename boost::numeric::ublas::vector<T> ret_t; | ret_t operator() (range const& r) { | ret_t v (boost::size (r)); | std::copy (boost::begin (r), boost::end (r), v.begin()); this can write past the end | return v; | } | }; | } hm..if ublas support is needed one could either do 1. give ublas classes a constructor that takes two iterators 2. overload copy_range I would prefer 1. br Thorsten

Thorsten Ottosen wrote:
Please see the "Utility" section of the docs. You would be looking for copy_range().
Thanks!
hm..if ublas support is needed one could either do
1. give ublas classes a constructor that takes two iterators 2. overload copy_range
I would prefer 1.
Me too, but I don't think that's going to happen.

"Neal Becker" <ndbecker2@verizon.net> wrote in message news:chvtba$eud$1@sea.gmane.org... | > hm..if ublas support is needed one could either do | > | > 1. give ublas classes a constructor that takes two iterators | > 2. overload copy_range | > | > I would prefer 1. | > | | Me too, but I don't think that's going to happen. Why not? br Thorsten

Thorsten Ottosen wrote:
"Neal Becker" <ndbecker2@verizon.net> wrote in message news:chvtba$eud$1@sea.gmane.org...
| > hm..if ublas support is needed one could either do | > | > 1. give ublas classes a constructor that takes two iterators | > 2. overload copy_range | > | > I would prefer 1. | > | | Me too, but I don't think that's going to happen.
Why not?
I brought this up on ublas-dev list, and it was basically rejected. Honestly, I don't completely understand why.

Thorsten Ottosen wrote:
"Neal Becker" <ndbecker2@verizon.net> wrote in message news:chvoo4$qbl$1@sea.gmane.org... | It is not unusual to need to construct a container from another where | one or the other doesn't comply with sequence. | | When generic code needs to convert to a container of unknown type (e.g., | the return container type of a function is a template parameter), a | generic | constructor is useful, and could be part of range. Here is the idea: | | #ifndef const_from_range_hpp | #define const_from_range_hpp | | #include <boost/range.hpp> | #include <algorithm> | #include <boost/numeric/ublas/vector.hpp> | | namespace detail { | template<typename cont_t, typename range> | struct construct_from_range_impl { | cont_t operator() (range const& r) { | return cont_t (boost::begin (r), boost::end (r)); | } | };
Please see the "Utility" section of the docs. You would be looking for copy_range().
| template<typename T, typename range> | struct construct_from_range_impl<boost::numeric::ublas::vector<T>, | range> | { | typedef typename boost::numeric::ublas::vector<T> ret_t; | ret_t operator() (range const& r) { | ret_t v (boost::size (r)); | std::copy (boost::begin (r), boost::end (r), v.begin());
this can write past the end
| return v; | } | }; | }
hm..if ublas support is needed one could either do
1. give ublas classes a constructor that takes two iterators 2. overload copy_range
I would prefer 1.
How would 2 work? copy_range is a function, so can't have a partial specialization. How would you overload for converting an arbitrary range to ublas::vector<T>?

"Neal Becker" <ndbecker2@verizon.net> wrote in message news:ci2eu0$r3b$1@sea.gmane.org... | Thorsten Ottosen wrote: | | > "Neal Becker" <ndbecker2@verizon.net> wrote in message | > | namespace detail { | > | template<typename cont_t, typename range> | > | struct construct_from_range_impl { | > | cont_t operator() (range const& r) { | > | return cont_t (boost::begin (r), boost::end (r)); | > | } | > | }; | > | > Please see the "Utility" section of the docs. You would be looking for | > copy_range(). | > | > | template<typename T, typename range> | > | struct construct_from_range_impl<boost::numeric::ublas::vector<T>, | > | range> | > | { | > | typedef typename boost::numeric::ublas::vector<T> ret_t; | > | ret_t operator() (range const& r) { | > | ret_t v (boost::size (r)); | > | std::copy (boost::begin (r), boost::end (r), v.begin()); | > hm..if ublas support is needed one could either do | > | > 1. give ublas classes a constructor that takes two iterators | > 2. overload copy_range | > | > I would prefer 1. | > | How would 2 work? copy_range is a function, so can't have a partial | specialization. How would you overload for converting an arbitrary range | to ublas::vector<T>? hm...I see the problem...I guess you can't. br Thorsten
participants (2)
-
Neal Becker
-
Thorsten Ottosen