diff --git a/include/boost/multi_array.hpp b/include/boost/multi_array.hpp index 398c345..4325377 100644 --- a/include/boost/multi_array.hpp +++ b/include/boost/multi_array.hpp @@ -33,7 +33,20 @@ #include #include + + namespace boost { + namespace detail { + namespace multi_array { + struct populate_index_ranges { + multi_array_types::index_range + operator()(multi_array_types::index base, + multi_array_types::size_type extent) { + return multi_array_types::index_range(base,base+extent); + } + }; + } //namespace multi_array + } // namespace detail template @@ -162,6 +175,70 @@ public: } + multi_array& resize(const detail::multi_array + ::extent_gen& ranges) { + + + // build a multi_array with the specs given + multi_array new_array(ranges); + + + // build a view of tmp with the minimum extents + + // Get the minimum extents of the arrays. + boost::array min_extents; + + const size_type& (*min)(const size_type&, const size_type&) = + std::min; + std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(), + this->extent_list_.begin(), + min_extents.begin(), + min); + + + // typedef boost::array index_list; + // Build index_gen objects to create views with the same shape + + // these need to be separate to handle non-zero index bases + typedef detail::multi_array::index_gen index_gen; + index_gen old_idxes; + index_gen new_idxes; + + std::transform(new_array.index_base_list_.begin(), + new_array.index_base_list_.end(), + min_extents.begin(),old_idxes.ranges_.begin(), + detail::multi_array::populate_index_ranges()); + + std::transform(this->index_base_list_.begin(), + this->index_base_list_.end(), + min_extents.begin(),new_idxes.ranges_.begin(), + detail::multi_array::populate_index_ranges()); + + // Build same-shape views of the two arrays + multi_array::array_view<3>::type view_old = (*this)[old_idxes]; + multi_array::array_view<3>::type view_new = new_array[new_idxes]; + + // Set the right portion of the new array + view_new = view_old; + + using std::swap; + // Swap the internals of these arrays. + swap(this->super_type::base_,new_array.super_type::base_); + swap(this->storage_,new_array.storage_); + swap(this->extent_list_,new_array.extent_list_); + swap(this->stride_list_,new_array.stride_list_); + swap(this->index_base_list_,new_array.index_base_list_); + swap(this->origin_offset_,new_array.origin_offset_); + swap(this->directional_offset_,new_array.directional_offset_); + swap(this->num_elements_,new_array.num_elements_); + swap(this->allocator_,new_array.allocator_); + swap(this->base_,new_array.base_); + swap(this->allocated_elements_,new_array.allocated_elements_); + + return *this; + } + + ~multi_array() { deallocate_space(); } diff --git a/test/resize.cpp b/test/resize.cpp new file mode 100644 index 0000000..72aed54 --- /dev/null +++ b/test/resize.cpp @@ -0,0 +1,69 @@ +// +// resize.cpp - Test of resizing multi_arrays +// + +#include "boost/multi_array.hpp" +#include +using namespace std; + +template +void print(std::ostream& os, const Array& A) +{ + typename Array::const_iterator i; + os << "["; + for (i = A.begin(); i != A.end(); ++i) { + print(os, *i); + if (boost::next(i) != A.end()) + os << ','; + } + os << "]"; +} + +void print(std::ostream& os, const int& x) +{ + os << x; +} + +int main() { + + typedef boost::multi_array marray; + + + int A_data[] = { + 0,1,2,3, + 4,5,6,7, + 8,9,10,11, + + 12,13,14,15, + 16,17,18,19, + 20,21,22,23 + }; + + + marray A(boost::extents[2][3][4]); + + A.assign(A_data,A_data+(2*3*4)); + + A.resize(boost::extents[4][3][2]); + + int A_resize[] = { + 0,1, + 4,5, + 8,9, + + 12,13, + 16,17, + 20,21, + + 0,0, + 0,0, + 0,0, + + 0,0, + 0,0, + 0,0 + }; + + assert(std::equal(A_resize,A_resize+(4*3*2),A.data())); + +}