epoc32/include/stdapis/boost/multi_array.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
// Copyright 2002 The Trustees of Indiana University.
williamr@2
     2
williamr@2
     3
// Use, modification and distribution is subject to the Boost Software 
williamr@2
     4
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     5
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     6
williamr@2
     7
//  Boost.MultiArray Library
williamr@2
     8
//  Authors: Ronald Garcia
williamr@2
     9
//           Jeremy Siek
williamr@2
    10
//           Andrew Lumsdaine
williamr@2
    11
//  See http://www.boost.org/libs/multi_array for documentation.
williamr@2
    12
williamr@2
    13
#ifndef BOOST_MULTI_ARRAY_RG071801_HPP
williamr@2
    14
#define BOOST_MULTI_ARRAY_RG071801_HPP
williamr@2
    15
williamr@2
    16
//
williamr@2
    17
// multi_array.hpp - contains the multi_array class template
williamr@2
    18
// declaration and definition
williamr@2
    19
//
williamr@2
    20
williamr@2
    21
#include "boost/multi_array/base.hpp"
williamr@2
    22
#include "boost/multi_array/collection_concept.hpp"
williamr@2
    23
#include "boost/multi_array/copy_array.hpp"
williamr@2
    24
#include "boost/multi_array/iterator.hpp"
williamr@2
    25
#include "boost/multi_array/subarray.hpp"
williamr@2
    26
#include "boost/multi_array/multi_array_ref.hpp"
williamr@2
    27
#include "boost/multi_array/algorithm.hpp"
williamr@2
    28
#include "boost/array.hpp"
williamr@2
    29
#include "boost/mpl/if.hpp"
williamr@2
    30
#include "boost/type_traits.hpp"
williamr@2
    31
#include <algorithm>
williamr@2
    32
#include <cstddef>
williamr@2
    33
#include <functional>
williamr@2
    34
#include <numeric>
williamr@2
    35
#include <vector>
williamr@2
    36
williamr@2
    37
williamr@2
    38
williamr@2
    39
namespace boost {
williamr@2
    40
  namespace detail {
williamr@2
    41
    namespace multi_array {
williamr@2
    42
williamr@2
    43
      struct populate_index_ranges {
williamr@2
    44
        multi_array_types::index_range
williamr@2
    45
        // RG: underscore on extent_ to stifle strange MSVC warning.
williamr@2
    46
        operator()(multi_array_types::index base,
williamr@2
    47
                   multi_array_types::size_type extent_) {
williamr@2
    48
          return multi_array_types::index_range(base,base+extent_);
williamr@2
    49
        }
williamr@2
    50
      };
williamr@2
    51
williamr@2
    52
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
williamr@2
    53
//
williamr@2
    54
// Compilers that don't support partial ordering may need help to
williamr@2
    55
// disambiguate multi_array's templated constructors.  Even vc6/7 are
williamr@2
    56
// capable of some limited SFINAE, so we take the most-general version
williamr@2
    57
// out of the overload set with disable_multi_array_impl.
williamr@2
    58
//
williamr@2
    59
template <typename T, std::size_t NumDims, typename TPtr>
williamr@2
    60
char is_multi_array_impl_help(const_multi_array_view<T,NumDims,TPtr>&);
williamr@2
    61
template <typename T, std::size_t NumDims, typename TPtr>
williamr@2
    62
char is_multi_array_impl_help(const_sub_array<T,NumDims,TPtr>&);
williamr@2
    63
template <typename T, std::size_t NumDims, typename TPtr>
williamr@2
    64
char is_multi_array_impl_help(const_multi_array_ref<T,NumDims,TPtr>&);
williamr@2
    65
williamr@2
    66
char ( &is_multi_array_impl_help(...) )[2];
williamr@2
    67
williamr@2
    68
template <class T>
williamr@2
    69
struct is_multi_array_impl
williamr@2
    70
{
williamr@2
    71
    static T x;
williamr@2
    72
    BOOST_STATIC_CONSTANT(bool, value = sizeof((is_multi_array_impl_help)(x)) == 1);
williamr@2
    73
williamr@2
    74
  typedef mpl::bool_<value> type;
williamr@2
    75
};
williamr@2
    76
williamr@2
    77
template <bool multi_array = false>
williamr@2
    78
struct disable_multi_array_impl_impl
williamr@2
    79
{
williamr@2
    80
    typedef int type;
williamr@2
    81
};
williamr@2
    82
williamr@2
    83
template <>
williamr@2
    84
struct disable_multi_array_impl_impl<true>
williamr@2
    85
{
williamr@2
    86
    // forming a pointer to a reference triggers SFINAE
williamr@2
    87
    typedef int& type; 
williamr@2
    88
};
williamr@2
    89
williamr@2
    90
williamr@2
    91
template <class T>
williamr@2
    92
struct disable_multi_array_impl :
williamr@2
    93
  disable_multi_array_impl_impl<is_multi_array_impl<T>::value>
williamr@2
    94
{ };
williamr@2
    95
williamr@2
    96
williamr@2
    97
template <>
williamr@2
    98
struct disable_multi_array_impl<int>
williamr@2
    99
{
williamr@2
   100
  typedef int type;
williamr@2
   101
};
williamr@2
   102
williamr@2
   103
williamr@2
   104
#endif
williamr@2
   105
williamr@2
   106
    } //namespace multi_array
williamr@2
   107
  } // namespace detail
williamr@2
   108
williamr@2
   109
template<typename T, std::size_t NumDims,
williamr@2
   110
  typename Allocator>
williamr@2
   111
class multi_array :
williamr@2
   112
  public multi_array_ref<T,NumDims>
williamr@2
   113
{
williamr@2
   114
  typedef multi_array_ref<T,NumDims> super_type;
williamr@2
   115
public:
williamr@2
   116
  typedef typename super_type::value_type value_type;
williamr@2
   117
  typedef typename super_type::reference reference;
williamr@2
   118
  typedef typename super_type::const_reference const_reference;
williamr@2
   119
  typedef typename super_type::iterator iterator;
williamr@2
   120
  typedef typename super_type::const_iterator const_iterator;
williamr@2
   121
  typedef typename super_type::reverse_iterator reverse_iterator;
williamr@2
   122
  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
williamr@2
   123
  typedef typename super_type::element element;
williamr@2
   124
  typedef typename super_type::size_type size_type;
williamr@2
   125
  typedef typename super_type::difference_type difference_type;
williamr@2
   126
  typedef typename super_type::index index;
williamr@2
   127
  typedef typename super_type::extent_range extent_range;
williamr@2
   128
williamr@2
   129
williamr@2
   130
  template <std::size_t NDims>
williamr@2
   131
  struct const_array_view {
williamr@2
   132
    typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
williamr@2
   133
  };
williamr@2
   134
williamr@2
   135
  template <std::size_t NDims>
williamr@2
   136
  struct array_view {
williamr@2
   137
    typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
williamr@2
   138
  };
williamr@2
   139
williamr@2
   140
  explicit multi_array() :
williamr@2
   141
    super_type((T*)initial_base_,c_storage_order(),
williamr@2
   142
               /*index_bases=*/0, /*extents=*/0) {
williamr@2
   143
    allocate_space(); 
williamr@2
   144
  }
williamr@2
   145
williamr@2
   146
  template <class ExtentList>
williamr@2
   147
  explicit multi_array(
williamr@2
   148
      ExtentList const& extents
williamr@2
   149
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
williamr@2
   150
      , typename mpl::if_<
williamr@2
   151
      detail::multi_array::is_multi_array_impl<ExtentList>,
williamr@2
   152
      int&,int>::type* = 0
williamr@2
   153
#endif
williamr@2
   154
      ) :
williamr@2
   155
    super_type((T*)initial_base_,extents) {
williamr@2
   156
    boost::function_requires<
williamr@2
   157
      detail::multi_array::CollectionConcept<ExtentList> >();
williamr@2
   158
    allocate_space();
williamr@2
   159
  }
williamr@2
   160
williamr@2
   161
    
williamr@2
   162
  template <class ExtentList>
williamr@2
   163
  explicit multi_array(ExtentList const& extents,
williamr@2
   164
                       const general_storage_order<NumDims>& so) :
williamr@2
   165
    super_type((T*)initial_base_,extents,so) {
williamr@2
   166
    boost::function_requires<
williamr@2
   167
      detail::multi_array::CollectionConcept<ExtentList> >();
williamr@2
   168
    allocate_space();
williamr@2
   169
  }
williamr@2
   170
williamr@2
   171
  template <class ExtentList>
williamr@2
   172
  explicit multi_array(ExtentList const& extents,
williamr@2
   173
                       const general_storage_order<NumDims>& so,
williamr@2
   174
                       Allocator const& alloc) :
williamr@2
   175
    super_type((T*)initial_base_,extents,so), allocator_(alloc) {
williamr@2
   176
    boost::function_requires<
williamr@2
   177
      detail::multi_array::CollectionConcept<ExtentList> >();
williamr@2
   178
    allocate_space();
williamr@2
   179
  }
williamr@2
   180
williamr@2
   181
williamr@2
   182
  explicit multi_array(const detail::multi_array
williamr@2
   183
                       ::extent_gen<NumDims>& ranges) :
williamr@2
   184
    super_type((T*)initial_base_,ranges) {
williamr@2
   185
williamr@2
   186
    allocate_space();
williamr@2
   187
  }
williamr@2
   188
williamr@2
   189
williamr@2
   190
  explicit multi_array(const detail::multi_array
williamr@2
   191
                       ::extent_gen<NumDims>& ranges,
williamr@2
   192
                       const general_storage_order<NumDims>& so) :
williamr@2
   193
    super_type((T*)initial_base_,ranges,so) {
williamr@2
   194
williamr@2
   195
    allocate_space();
williamr@2
   196
  }
williamr@2
   197
williamr@2
   198
williamr@2
   199
  explicit multi_array(const detail::multi_array
williamr@2
   200
                       ::extent_gen<NumDims>& ranges,
williamr@2
   201
                       const general_storage_order<NumDims>& so,
williamr@2
   202
                       Allocator const& alloc) :
williamr@2
   203
    super_type((T*)initial_base_,ranges,so), allocator_(alloc) {
williamr@2
   204
williamr@2
   205
    allocate_space();
williamr@2
   206
  }
williamr@2
   207
williamr@2
   208
  multi_array(const multi_array& rhs) :
williamr@2
   209
  super_type(rhs), allocator_(rhs.allocator_) {
williamr@2
   210
    allocate_space();
williamr@2
   211
    boost::detail::multi_array::copy_n(rhs.base_,rhs.num_elements(),base_);
williamr@2
   212
  }
williamr@2
   213
williamr@2
   214
williamr@2
   215
  //
williamr@2
   216
  // A multi_array is constructible from any multi_array_ref, subarray, or
williamr@2
   217
  // array_view object.  The following constructors ensure that.
williamr@2
   218
  //
williamr@2
   219
williamr@2
   220
  // Due to limited support for partial template ordering, 
williamr@2
   221
  // MSVC 6&7 confuse the following with the most basic ExtentList 
williamr@2
   222
  // constructor.
williamr@2
   223
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
williamr@2
   224
  template <typename OPtr>
williamr@2
   225
  multi_array(const const_multi_array_ref<T,NumDims,OPtr>& rhs,
williamr@2
   226
              const general_storage_order<NumDims>& so = c_storage_order())
williamr@2
   227
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   228
  {
williamr@2
   229
    allocate_space();
williamr@2
   230
    // Warning! storage order may change, hence the following copy technique.
williamr@2
   231
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   232
  }
williamr@2
   233
williamr@2
   234
  template <typename OPtr>
williamr@2
   235
  multi_array(const detail::multi_array::
williamr@2
   236
              const_sub_array<T,NumDims,OPtr>& rhs,
williamr@2
   237
              const general_storage_order<NumDims>& so = c_storage_order())
williamr@2
   238
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   239
  {
williamr@2
   240
    allocate_space();
williamr@2
   241
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   242
  }
williamr@2
   243
williamr@2
   244
williamr@2
   245
  template <typename OPtr>
williamr@2
   246
  multi_array(const detail::multi_array::
williamr@2
   247
              const_multi_array_view<T,NumDims,OPtr>& rhs,
williamr@2
   248
              const general_storage_order<NumDims>& so = c_storage_order())
williamr@2
   249
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   250
  {
williamr@2
   251
    allocate_space();
williamr@2
   252
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   253
  }
williamr@2
   254
williamr@2
   255
#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
williamr@2
   256
  // More limited support for MSVC
williamr@2
   257
williamr@2
   258
williamr@2
   259
  multi_array(const const_multi_array_ref<T,NumDims>& rhs)
williamr@2
   260
    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
williamr@2
   261
  {
williamr@2
   262
    allocate_space();
williamr@2
   263
    // Warning! storage order may change, hence the following copy technique.
williamr@2
   264
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   265
  }
williamr@2
   266
williamr@2
   267
  multi_array(const const_multi_array_ref<T,NumDims>& rhs,
williamr@2
   268
              const general_storage_order<NumDims>& so)
williamr@2
   269
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   270
  {
williamr@2
   271
    allocate_space();
williamr@2
   272
    // Warning! storage order may change, hence the following copy technique.
williamr@2
   273
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   274
  }
williamr@2
   275
williamr@2
   276
  multi_array(const detail::multi_array::
williamr@2
   277
              const_sub_array<T,NumDims>& rhs)
williamr@2
   278
    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
williamr@2
   279
  {
williamr@2
   280
    allocate_space();
williamr@2
   281
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   282
  }
williamr@2
   283
williamr@2
   284
  multi_array(const detail::multi_array::
williamr@2
   285
              const_sub_array<T,NumDims>& rhs,
williamr@2
   286
              const general_storage_order<NumDims>& so)
williamr@2
   287
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   288
  {
williamr@2
   289
    allocate_space();
williamr@2
   290
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   291
  }
williamr@2
   292
williamr@2
   293
williamr@2
   294
  multi_array(const detail::multi_array::
williamr@2
   295
              const_multi_array_view<T,NumDims>& rhs)
williamr@2
   296
    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
williamr@2
   297
  {
williamr@2
   298
    allocate_space();
williamr@2
   299
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   300
  }
williamr@2
   301
williamr@2
   302
  multi_array(const detail::multi_array::
williamr@2
   303
              const_multi_array_view<T,NumDims>& rhs,
williamr@2
   304
              const general_storage_order<NumDims>& so)
williamr@2
   305
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   306
  {
williamr@2
   307
    allocate_space();
williamr@2
   308
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   309
  }
williamr@2
   310
williamr@2
   311
#endif // !BOOST_NO_FUNCTION_TEMPLATE_ORDERING
williamr@2
   312
williamr@2
   313
  // Thes constructors are necessary because of more exact template matches.
williamr@2
   314
  multi_array(const multi_array_ref<T,NumDims>& rhs)
williamr@2
   315
    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
williamr@2
   316
  {
williamr@2
   317
    allocate_space();
williamr@2
   318
    // Warning! storage order may change, hence the following copy technique.
williamr@2
   319
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   320
  }
williamr@2
   321
williamr@2
   322
  multi_array(const multi_array_ref<T,NumDims>& rhs,
williamr@2
   323
              const general_storage_order<NumDims>& so)
williamr@2
   324
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   325
  {
williamr@2
   326
    allocate_space();
williamr@2
   327
    // Warning! storage order may change, hence the following copy technique.
williamr@2
   328
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   329
  }
williamr@2
   330
williamr@2
   331
williamr@2
   332
  multi_array(const detail::multi_array::
williamr@2
   333
              sub_array<T,NumDims>& rhs)
williamr@2
   334
    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
williamr@2
   335
  {
williamr@2
   336
    allocate_space();
williamr@2
   337
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   338
  }
williamr@2
   339
williamr@2
   340
  multi_array(const detail::multi_array::
williamr@2
   341
              sub_array<T,NumDims>& rhs,
williamr@2
   342
              const general_storage_order<NumDims>& so)
williamr@2
   343
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   344
  {
williamr@2
   345
    allocate_space();
williamr@2
   346
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   347
  }
williamr@2
   348
williamr@2
   349
williamr@2
   350
  multi_array(const detail::multi_array::
williamr@2
   351
              multi_array_view<T,NumDims>& rhs)
williamr@2
   352
    : super_type(0,c_storage_order(),rhs.index_bases(),rhs.shape()) 
williamr@2
   353
  {
williamr@2
   354
    allocate_space();
williamr@2
   355
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   356
  }
williamr@2
   357
    
williamr@2
   358
  multi_array(const detail::multi_array::
williamr@2
   359
              multi_array_view<T,NumDims>& rhs,
williamr@2
   360
              const general_storage_order<NumDims>& so)
williamr@2
   361
    : super_type(0,so,rhs.index_bases(),rhs.shape()) 
williamr@2
   362
  {
williamr@2
   363
    allocate_space();
williamr@2
   364
    std::copy(rhs.begin(),rhs.end(),this->begin());
williamr@2
   365
  }
williamr@2
   366
    
williamr@2
   367
  // Since assignment is a deep copy, multi_array_ref
williamr@2
   368
  // contains all the necessary code.
williamr@2
   369
  template <typename ConstMultiArray>
williamr@2
   370
  multi_array& operator=(const ConstMultiArray& other) {
williamr@2
   371
    super_type::operator=(other);
williamr@2
   372
    return *this;
williamr@2
   373
  }
williamr@2
   374
williamr@2
   375
  multi_array& operator=(const multi_array& other) {
williamr@2
   376
    if (&other != this) {
williamr@2
   377
      super_type::operator=(other);
williamr@2
   378
    }
williamr@2
   379
    return *this;
williamr@2
   380
  }
williamr@2
   381
williamr@2
   382
williamr@2
   383
  template <typename ExtentList>
williamr@2
   384
  multi_array& resize(const ExtentList& extents) {
williamr@2
   385
    boost::function_requires<
williamr@2
   386
      detail::multi_array::CollectionConcept<ExtentList> >();
williamr@2
   387
williamr@2
   388
    typedef detail::multi_array::extent_gen<NumDims> gen_type;
williamr@2
   389
    gen_type ranges;
williamr@2
   390
williamr@2
   391
    for (int i=0; i != NumDims; ++i) {
williamr@2
   392
      typedef typename gen_type::range range_type;
williamr@2
   393
      ranges.ranges_[i] = range_type(0,extents[i]);
williamr@2
   394
    }
williamr@2
   395
    
williamr@2
   396
    return this->resize(ranges);
williamr@2
   397
  }
williamr@2
   398
williamr@2
   399
williamr@2
   400
williamr@2
   401
  multi_array& resize(const detail::multi_array
williamr@2
   402
                      ::extent_gen<NumDims>& ranges) {
williamr@2
   403
williamr@2
   404
williamr@2
   405
    // build a multi_array with the specs given
williamr@2
   406
    multi_array new_array(ranges,this->storage_order());
williamr@2
   407
williamr@2
   408
williamr@2
   409
    // build a view of tmp with the minimum extents
williamr@2
   410
williamr@2
   411
    // Get the minimum extents of the arrays.
williamr@2
   412
    boost::array<size_type,NumDims> min_extents;
williamr@2
   413
williamr@2
   414
    const size_type& (*min)(const size_type&, const size_type&) =
williamr@2
   415
      std::min;
williamr@2
   416
    std::transform(new_array.extent_list_.begin(),new_array.extent_list_.end(),
williamr@2
   417
                   this->extent_list_.begin(),
williamr@2
   418
                   min_extents.begin(),
williamr@2
   419
                   min);
williamr@2
   420
williamr@2
   421
williamr@2
   422
    // typedef boost::array<index,NumDims> index_list;
williamr@2
   423
    // Build index_gen objects to create views with the same shape
williamr@2
   424
williamr@2
   425
    // these need to be separate to handle non-zero index bases
williamr@2
   426
    typedef detail::multi_array::index_gen<NumDims,NumDims> index_gen;
williamr@2
   427
    index_gen old_idxes;
williamr@2
   428
    index_gen new_idxes;
williamr@2
   429
williamr@2
   430
    std::transform(new_array.index_base_list_.begin(),
williamr@2
   431
                   new_array.index_base_list_.end(),
williamr@2
   432
                   min_extents.begin(),old_idxes.ranges_.begin(),
williamr@2
   433
                   detail::multi_array::populate_index_ranges());
williamr@2
   434
williamr@2
   435
    std::transform(this->index_base_list_.begin(),
williamr@2
   436
                   this->index_base_list_.end(),
williamr@2
   437
                   min_extents.begin(),new_idxes.ranges_.begin(),
williamr@2
   438
                   detail::multi_array::populate_index_ranges());
williamr@2
   439
williamr@2
   440
    // Build same-shape views of the two arrays
williamr@2
   441
    typename
williamr@2
   442
      multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_old = (*this)[old_idxes];
williamr@2
   443
    typename
williamr@2
   444
      multi_array::BOOST_NESTED_TEMPLATE array_view<NumDims>::type view_new = new_array[new_idxes];
williamr@2
   445
williamr@2
   446
    // Set the right portion of the new array
williamr@2
   447
    view_new = view_old;
williamr@2
   448
williamr@2
   449
    using std::swap;
williamr@2
   450
    // Swap the internals of these arrays.
williamr@2
   451
    swap(this->super_type::base_,new_array.super_type::base_);
williamr@2
   452
    swap(this->storage_,new_array.storage_);
williamr@2
   453
    swap(this->extent_list_,new_array.extent_list_);
williamr@2
   454
    swap(this->stride_list_,new_array.stride_list_);
williamr@2
   455
    swap(this->index_base_list_,new_array.index_base_list_);
williamr@2
   456
    swap(this->origin_offset_,new_array.origin_offset_);
williamr@2
   457
    swap(this->directional_offset_,new_array.directional_offset_);
williamr@2
   458
    swap(this->num_elements_,new_array.num_elements_);
williamr@2
   459
    swap(this->allocator_,new_array.allocator_);
williamr@2
   460
    swap(this->base_,new_array.base_);
williamr@2
   461
    swap(this->allocated_elements_,new_array.allocated_elements_);
williamr@2
   462
williamr@2
   463
    return *this;
williamr@2
   464
  }
williamr@2
   465
williamr@2
   466
williamr@2
   467
  ~multi_array() {
williamr@2
   468
    deallocate_space();
williamr@2
   469
  }
williamr@2
   470
williamr@2
   471
private:
williamr@2
   472
  void allocate_space() {
williamr@2
   473
    typename Allocator::const_pointer no_hint=0;
williamr@2
   474
    base_ = allocator_.allocate(this->num_elements(),no_hint);
williamr@2
   475
    this->set_base_ptr(base_);
williamr@2
   476
    allocated_elements_ = this->num_elements();
williamr@2
   477
    std::uninitialized_fill_n(base_,allocated_elements_,T());
williamr@2
   478
  }
williamr@2
   479
williamr@2
   480
  void deallocate_space() {
williamr@2
   481
    if(base_) {
williamr@2
   482
      for(T* i = base_; i != base_+allocated_elements_; ++i)
williamr@2
   483
        allocator_.destroy(i);
williamr@2
   484
      allocator_.deallocate(base_,allocated_elements_);
williamr@2
   485
    }
williamr@2
   486
  }
williamr@2
   487
williamr@2
   488
  typedef boost::array<size_type,NumDims> size_list;
williamr@2
   489
  typedef boost::array<index,NumDims> index_list;
williamr@2
   490
williamr@2
   491
  Allocator allocator_;
williamr@2
   492
  T* base_;
williamr@2
   493
  size_type allocated_elements_;
williamr@2
   494
  enum {initial_base_ = 0};
williamr@2
   495
};
williamr@2
   496
williamr@2
   497
} // namespace boost
williamr@2
   498
williamr@2
   499
#endif // BOOST_MULTI_ARRAY_RG071801_HPP