Ticket #1045: multi_array_swap.patch

File multi_array_swap.patch, 10.8 KB (added by Rhys Ulerich <rhys.ulerich@…>, 13 years ago)

Patch implementing the requested functionality

  • boost/multi_array/multi_array_ref.hpp

     
    3030#include "boost/concept_check.hpp"
    3131#include "boost/functional.hpp"
    3232#include "boost/limits.hpp"
     33#include "boost/swap.hpp"
    3334#include <algorithm>
    3435#include <cstddef>
    3536#include <functional>
     
    262263  }
    263264
    264265
     266
    265267  template <typename OPtr>
    266268  bool operator==(const
    267269                  const_multi_array_ref<T,NumDims,OPtr>& rhs)
     
    348350   }
    349351 }
    350352
    351 
    352353  TPtr base_;
    353354  storage_order_type storage_;
    354355  size_list extent_list_;
     
    358359  index directional_offset_;
    359360  size_type num_elements_;
    360361
     362protected:
     363  // const_multi_array_ref cannot be swapped, but we need swap for subclasses
     364  void swap(const_multi_array_ref& other) {
     365    boost::swap(base_, other.base_);
     366    boost::swap(storage_, other.storage_);
     367    boost::swap(extent_list_, other.extent_list_);
     368    boost::swap(stride_list_, other.stride_list_);
     369    boost::swap(index_base_list_, other.index_base_list_);
     370    boost::swap(origin_offset_, other.origin_offset_);
     371    boost::swap(directional_offset_, other.directional_offset_);
     372    boost::swap(num_elements_, other.num_elements_);
     373  }
     374
    361375private:
    362376  // const_multi_array_ref cannot be assigned to (no deep copies!)
    363377  const_multi_array_ref& operator=(const const_multi_array_ref& other);
     
    618632    return super_type::rend();
    619633  }
    620634
     635  void swap(multi_array_ref& other) {
     636    super_type::swap(other);
     637  }
     638
    621639protected:
    622640  // This is only supplied to support multi_array's default constructor
    623641  explicit multi_array_ref(T* base,
     
    628646
    629647};
    630648
     649// global swap()
     650template <typename T, std::size_t NumDims>
     651inline void swap(multi_array_ref<T,NumDims>& x,
     652                 multi_array_ref<T,NumDims>& y) {
     653    x.swap(y);
     654}
     655
    631656} // namespace boost
    632657
    633658#endif // BOOST_MULTI_ARRAY_REF_RG071801_HPP
  • boost/multi_array.hpp

     
    2727#include "boost/multi_array/algorithm.hpp"
    2828#include "boost/array.hpp"
    2929#include "boost/mpl/if.hpp"
     30#include "boost/swap.hpp"
    3031#include "boost/type_traits.hpp"
    3132#include <algorithm>
    3233#include <cstddef>
     
    446447    // Set the right portion of the new array
    447448    view_new = view_old;
    448449
    449     using std::swap;
    450450    // Swap the internals of these arrays.
    451     swap(this->super_type::base_,new_array.super_type::base_);
    452     swap(this->storage_,new_array.storage_);
    453     swap(this->extent_list_,new_array.extent_list_);
    454     swap(this->stride_list_,new_array.stride_list_);
    455     swap(this->index_base_list_,new_array.index_base_list_);
    456     swap(this->origin_offset_,new_array.origin_offset_);
    457     swap(this->directional_offset_,new_array.directional_offset_);
    458     swap(this->num_elements_,new_array.num_elements_);
    459     swap(this->allocator_,new_array.allocator_);
    460     swap(this->base_,new_array.base_);
    461     swap(this->allocated_elements_,new_array.allocated_elements_);
     451    swap(new_array);
    462452
    463453    return *this;
    464454  }
    465455
     456  void swap(multi_array& other) {
     457      super_type::swap(other);
     458      boost::swap(allocator_, other.allocator_);
     459      boost::swap(base_, other.base_);
     460      boost::swap(allocated_elements_, other.allocated_elements_);
     461  }
    466462
    467463  ~multi_array() {
    468464    deallocate_space();
     
    494490  enum {initial_base_ = 0};
    495491};
    496492
     493// global swap()
     494template <typename T, std::size_t NumDims>
     495inline void swap(multi_array<T,NumDims>& x, multi_array<T,NumDims>& y) {
     496    x.swap(y);
     497}
     498
    497499} // namespace boost
    498500
    499501#endif // BOOST_MULTI_ARRAY_RG071801_HPP
  • libs/multi_array/test/regression.cfg

     
    1212run libs/multi_array/test/range1.cpp
    1313run libs/multi_array/test/idxgen1.cpp
    1414run libs/multi_array/test/stl_interaction.cpp
     15run libs/multi_array/test/swap.cpp
    1516compile libs/multi_array/test/concept_checks.cpp
    1617
    1718compile-fail libs/multi_array/test/fail_cbracket.cpp
  • libs/multi_array/test/swap.cpp

     
     1// Copyright 2002 The Trustees of Indiana University.
     2
     3// Use, modification and distribution is subject to the Boost Software
     4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     5// http://www.boost.org/LICENSE_1_0.txt)
     6
     7//  Boost.MultiArray Library
     8//  Authors: Ronald Garcia
     9//           Jeremy Siek
     10//           Andrew Lumsdaine
     11//  See http://www.boost.org/libs/multi_array for documentation.
     12
     13//
     14// swap.cpp - Test swap member for multi_array, multi_array_ref
     15//
     16
     17#include "boost/test/minimal.hpp"
     18
     19#include "boost/multi_array.hpp"
     20#include <algorithm>
     21#include <list>
     22
     23void check_shape(const double&, std::size_t*, int*, unsigned int)
     24{}
     25
     26template <class Array>
     27void check_shape(const Array& A,
     28                 std::size_t* sizes,
     29                 int* strides,
     30                 unsigned int num_elements)
     31{
     32  BOOST_CHECK(A.num_elements() == num_elements);
     33  BOOST_CHECK(A.size() == *sizes);
     34  BOOST_CHECK(std::equal(sizes, sizes + A.num_dimensions(), A.shape()));
     35  BOOST_CHECK(std::equal(strides, strides + A.num_dimensions(), A.strides()));
     36  check_shape(A[0], ++sizes, ++strides, num_elements / A.size());
     37}
     38
     39
     40bool equal(const double& a, const double& b)
     41{
     42  return a == b;
     43}
     44
     45template <typename ArrayA, typename ArrayB>
     46bool equal(const ArrayA& A, const ArrayB& B)
     47{
     48  typename ArrayA::const_iterator ia;
     49  typename ArrayB::const_iterator ib = B.begin();
     50  for (ia = A.begin(); ia != A.end(); ++ia, ++ib)
     51    if (!equal(*ia, *ib))
     52      return false;
     53  return true;
     54}
     55
     56
     57int
     58test_main(int, char*[])
     59{
     60  typedef boost::multi_array<double, 3>::size_type size_type;
     61  boost::array<size_type,3> sizes[2] = { {{4, 5, 6}}, {{1, 2, 3}} };
     62  int strides[2][3] = { { 30, 6, 1 }, { 6, 3, 1 }};
     63  size_type num_elements[2] = { 4*5*6, 1*2*3 };
     64
     65  // multi_array_ref::swap, default storage order and allocator
     66  {
     67    double aptr[] = { 777 };
     68    boost::multi_array_ref<double,3> A(aptr,sizes[0]);
     69    check_shape(A, &sizes[0][0], strides[0], num_elements[0]);
     70
     71    double bptr[] = { 888 };
     72    boost::multi_array_ref<double,3> B(bptr,sizes[1]);
     73    check_shape(B, &sizes[1][0], strides[1], num_elements[1]);
     74
     75    A.swap(B);
     76
     77    check_shape(A, &sizes[1][0], strides[1], num_elements[1]);
     78    check_shape(B, &sizes[0][0], strides[0], num_elements[0]);
     79    BOOST_CHECK(A.data() == bptr);
     80    BOOST_CHECK(B.data() == aptr);
     81  }
     82
     83  // multi_array_ref::swap, self swap
     84  {
     85    double aptr[] = { 777 };
     86    boost::multi_array_ref<double,3> A(aptr,sizes[0]);
     87    check_shape(A, &sizes[0][0], strides[0], num_elements[0]);
     88
     89    A.swap(A);
     90
     91    check_shape(A, &sizes[0][0], strides[0], num_elements[0]);
     92    BOOST_CHECK(A.data() == aptr);
     93  }
     94
     95  // multi_array::swap, default storage order and allocator
     96  {
     97    boost::multi_array<double, 3> A(sizes[0]);
     98    check_shape(A, &sizes[0][0], strides[0], num_elements[0]);
     99    A[0][0][0] = 777.0;
     100
     101    boost::multi_array<double, 3> B(sizes[1]);
     102    check_shape(B, &sizes[1][0], strides[1], num_elements[1]);
     103    B[0][0][0] = 888.0;
     104
     105    A.swap(B);
     106
     107    check_shape(A, &sizes[1][0], strides[1], num_elements[1]);
     108    check_shape(B, &sizes[0][0], strides[0], num_elements[0]);
     109    BOOST_CHECK(A[0][0][0] == 888.0);
     110    BOOST_CHECK(B[0][0][0] == 777.0);
     111  }
     112
     113  // multi_array::swap, self swap
     114  {
     115    boost::multi_array<double, 3> A(sizes[0]);
     116    check_shape(A, &sizes[0][0], strides[0], num_elements[0]);
     117    A[0][0][0] = 777.0;
     118
     119    A.swap(A);
     120
     121    check_shape(A, &sizes[0][0], strides[0], num_elements[0]);
     122    BOOST_CHECK(A[0][0][0] == 777.0);
     123  }
     124
     125  return boost::exit_success;
     126}
  • libs/multi_array/test/Jamfile.v2

    Property changes on: libs/multi_array/test/swap.cpp
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    Added: svn:keywords
       + Id
    Added: svn:eol-style
       + native
    
     
    4545      [ run stl_interaction.cpp ../../test/build//boost_test_exec_monitor ]
    4646      [ run resize.cpp ../../test/build//boost_test_exec_monitor ]
    4747      [ run assert.cpp ../../test/build//boost_test_exec_monitor ]
     48      [ run swap.cpp ../../test/build//boost_test_exec_monitor ]
    4849      [ compile concept_checks.cpp ]
    4950    ;
  • libs/multi_array/doc/xml/multi_array_ref.xml

     
    124124    void                        reshape(const SizeList& sizes)
    125125  template <typename BaseList>  void reindex(const BaseList& values);
    126126  void                          reindex(index value);
     127  void                          swap(multi_array_ref &other);
    127128};
    128129]]>
    129130</programlisting>
  • libs/multi_array/doc/xml/multi_array.xml

     
    140140  template <typename ExtentList>
    141141    multi_array&                resize(const ExtentList& extents);
    142142  multi_array&                  resize(extents_tuple& extents);
     143  void                          swap(multi_array& other);
    143144};
    144145]]>
    145146</programlisting>
  • libs/multi_array/doc/reference.html

     
    697697  template &lt;typename ExtentList&gt;
    698698    multi_array&amp;            resize(const ExtentList&amp; extents);
    699699  multi_array&amp;                  resize(extents_tuple&amp; extents);
     700  void                              swap(multi_array&amp; other);
    700701};
    701702
    702703</pre><p><b>Constructors. </b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">template &lt;typename ExtentList&gt;
     
    908909    void                        reshape(const SizeList&amp; sizes)
    909910  template &lt;typename BaseList&gt;    void reindex(const BaseList&amp; values);
    910911  void                          reindex(index value);
     912  void              swap(multi_array_ref&amp; other);
    911913};
    912914
    913915</pre><p><b>Constructors. </b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">template &lt;typename ExtentList&gt;