Boost logo

Boost :

From: Kresimir Fresl (fresl_at_[hidden])
Date: 2002-09-26 11:47:35

Michael Stevens wrote:

>> From:
>> nbecker_at_[hidden] (Neal D. Becker)

>> Can ublas matrixes interconvert to/from plain old C pointers (to
>> interop with legacy code)? If so, how can a Matrix be converted to a
>> pointer to the start of storage? Is conversion in the other direction
>> possible?

> It is very easy to get a pointer to the start of storage.

Unfortunately, not always. Or, to be more exact, it seems that there
is no simple `universal' solution.

> The uBLAS
> contianer (matrix,vector etc) all wrap an underling storage type. This
> is usualy the 'unbounded_array' type. You can easily get a reference to
> this array using the accessor functions '.data()'.

> From then it is easy to get a pointer to the begin of the storage
> using '.begin()'

> Therefore to get a pointer to the first element of matrix A used

Yes, ublas::unbounded_array<>::begin() returns
ublas::unbounded_array<>::iterator (or const_iterator),
which *happens* to be a pointer. (The same is true
for ublas::bounded_array<>.)

But, for other storage types this need not be true; e.g. storage
type can be std::vector<> and its iterator can be `proper' class
(and it is in gnu library).

One can try


that is, take the address of the first element of storage array.

But this does not work when storage type is
ublas::(un)bounded_array<> and A is const. Namely,
return type of `operator[]() const' is
ublas::type_traits<>::const_reference, which for
built-in types (e.g. float and double) is not reference,
but value (e.g. not `double const&' but `double').



This works both with ublas::(un)bounded_array<>
and std::vector<>. But if storage type defines
const_iterator type whose const_reference is
ublas::type_traits<>::const_reference, there's again
a problem.

Maybe (let's suppose that A is const boost::vector<double>):

   &const_cast<vector<double>&> (A).data()[0]

i.e. remove vector's const; or:

   &const_cast<unbounded_array<double>&> ([0]

or (more general):

   &const_cast<vector<double>::array_type&> ([0]

i.e. remove const from storage.

I think that the proper solution is some kind of a traits class;
something like:

   template <typename V>
   struct storage_traits {
     typedef typename V::pointer pointer;
     static pointer storage (V& v) {
       return &[0];

   template <typename V>
   struct storage_traits<V const> {
     typedef typename V::const_pointer pointer;
     static pointer storage (V const& v) {
       V& vv = const_cast<V&> (v);
       return &[0];

   template <typename V>
   inline typename storage_traits<V>::pointer storage (V& v) {
     return storage_traits<V>::storage (v);

Of course, all these work if storage type has continuous


> I don't think it is possible at present to go the other way.

Oh, it is. There is (undocumented) class array_adaptor<>
(in storage.hpp):

   double b[] = { 1., 2. };
   array_adaptor<double> aa1 (2, b); // `2' is array size
   vector<double, array_adaptor<double> > v1 (2, aa1);

   double *c = new double[2];
   array_adaptor<double> aa2 (2, c);
   vector<double, array_adaptor<double> > v2 (2, aa2);
   c[0] = 1.; c[1] = 2.;
   cout << v2 (0) << " " << v2 (1) << endl;




Boost list run by bdawes at, gregod at, cpdaniel at, john at