|
Boost Users : |
From: Ronald Garcia (garcia_at_[hidden])
Date: 2008-07-17 15:19:47
Hello Johann,
On Jul 11, 2008, at 6:17 AM, Dr Johann A. Briffa wrote:
> I realize this topic has been discussed before (I've seen at least a
> thread in 2006 and another in 2007), but I believe there is more to
> add. At issue is the decision that multi_array objects cannot be
> assigned [with the operator=() that is] unless the target is already
> the same size as the source. Further, there is no documented way to
> easily resize an existing array to the same size and range as some
> other array.
Indeed there is no built-in way to easily resize a multi_array to be
the same size as another multi_array. While there is no resize member
function that takes a pointer, there is one that takes a model of the
Collection concept (classes like boost::array and std::vector are
concepts). Based on this interface, here is a stop-gap non-invasive
solution that can resize a multi_array based on another model of
MultiArray (multi_array, multi_array_ref, etc.):
//
=
=
=
=
=
=
=
=
=
=
========================================================================
#include <boost/multi_array.hpp>
#include <boost/static_assert.hpp>
#include <boost/array.hpp>
#include <algorithm>
template <typename T, typename U, std::size_t N>
void
resize_from_MultiArray(boost::multi_array<T,N>& marray, U& other) {
// U must be a model of MultiArray
boost::function_requires<
boost
::detail::multi_array::ConstMultiArrayConcept<U,U::dimensionality> >();
// U must have U::dimensionality == N
BOOST_STATIC_ASSERT(U::dimensionality == N);
boost::array<typename boost::multi_array<T,N>::size_type, N> shape;
std::copy(other.shape(), other.shape()+N, shape.begin());
marray.resize(shape);
}
//
// Example usage
//
#include <iostream>
int main () {
boost::multi_array<int,2> A(boost::extents[5][4]), B;
boost::multi_array<int,3> C;
resize_from_MultiArray(B,A);
#if 0
resize_from_MultiArray(C,A); // Compile-time error
#endif
std::cout << B.shape()[0] << ", " << B.shape()[1] << '\n';
}
//
=
=
=
=
=
=
=
=
=
=
=
=
=
========================================================================
One can use this function to easily resize a multi_array in terms of
another multi_array. This does not solve the problem you describe
below, where you want operator=() to resize a multi_array.
>
> As far as my needs are concerned, a multi_array that cannot be
> assigned is next to useless. Allow me to elaborate: I am using
> multi_array as a replacement to my own (old) 2/3D containers, as
> recently I've had need for higher dimensions. I have classes
> containing array members, where the size of the arrays is dynamic
> through the object lifetime. So my class default constructor uses
> the array default constructor for its member objects, creating empty
> arrays. Eventually as my classes get used, the array members are
> updated accordingly, and get to have some non-zero size. Now the
> problem is that my classes need to be assignable, and the only way
> that can be achieved is if the array members are assignable; the
> alternative is to have to write a specific assignment operator for
> any of my classes that use arrays, resizing each member of the
> target before copying. Clearly that would involve a lot of extra
> effort.
>
I believe that in a previous discussion I had suggested a template
argument-based solution to this, where a multi_array type would have
resizing assignment (and thereby no longer be a model of the
MultiArray concept). I don't recall getting feedback on that proposal.
Cheers,
ron
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net