Boost logo

Boost :

From: Neal Becker (ndbecker2_at_[hidden])
Date: 2004-09-11 15:55:32


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);
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk