<sect2 id="multi_array_ref">
<title><literal>multi_array_ref</literal></title>

<para>
<literal>multi_array_ref</literal> is a multi-dimensional container
adaptor.  It provides the MultiArray interface over any contiguous
block of elements.  <literal>multi_array_ref</literal> exports the
same interface as <literal>multi_array</literal>, with the exception
of the constructors.
</para>


<formalpara>
      <title>Model Of.</title>
<para>
<literal>multi_array_ref</literal> models 
<link linkend="MultiArray">MultiArray</link>,
<ulink url="../../../libs/utility/CopyConstructible.html">CopyConstructible</ulink>.
and depending on the element type, it may also model
<ulink url="http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</ulink> and <ulink url="http://www.sgi.com/tech/stl/LessThanComparable.html">LessThanComparable</ulink>. 
Detailed descriptions are provided here only for operations that are
not described in the <literal>multi_array</literal> reference.
</para>
</formalpara>

<formalpara>
<title>Synopsis</title>

<programlisting>
<![CDATA[
namespace boost {

template <typename ValueType, 
          std::size_t NumDims, 
          typename Allocator = std::allocator<ValueType> >
class multi_array_ref {
public:
// types:
  typedef ValueType                             element;
  typedef *implementation-defined*              value_type;
  typedef *implementation-defined*              reference;
  typedef *implementation-defined*              const_reference;
  typedef *implementation-defined*              difference_type;
  typedef *implementation-defined*              iterator;
  typedef *implementation-defined*              const_iterator;
  typedef *implementation-defined*              reverse_iterator;
  typedef *implementation-defined*              const_reverse_iterator;
  typedef multi_array_types::size_type          size_type;
  typedef multi_array_types::index              index;
  typedef multi_array_types::index_gen          index_gen;
  typedef multi_array_types::index_range        index_range;
  typedef multi_array_types::extent_gen         extent_gen;
  typedef multi_array_types::extent_range       extent_range;
  typedef *implementation-defined*              storage_order_type;
  
  // template typedefs
  template <std::size_t Dims> struct            subarray;
  template <std::size_t Dims> struct            const_subarray;
  template <std::size_t Dims> struct            array_view;
  template <std::size_t Dims> struct            const_array_view;
  

  // structors

  template <typename ExtentList>
  explicit multi_array_ref(element* data, const ExtentList& sizes,
                       const storage_order_type& store = c_storage_order());
  explicit multi_array_ref(element* data, const extents_tuple& ranges,
                       const storage_order_type& store = c_storage_order());
  multi_array_ref(const multi_array_ref& x);
  ~multi_array_ref();

  // modifiers

  multi_array_ref& operator=(const multi_array_ref& x);
  template <class Array> multi_array_ref& operator=(const Array& x);

  // iterators:
  iterator				begin();
  iterator				end();
  const_iterator			begin() const;
  const_iterator			end() const;
  reverse_iterator			rbegin();
  reverse_iterator			rend();
  const_reverse_iterator		rbegin() const;
  const_reverse_iterator		rend() const;

  // capacity:
  size_type				size() const;
  size_type				num_elements() const;
  size_type				num_dimensions() const;
 
  // element access:
  template <typename IndexList> 
    element&			operator()(const IndexList& indices);
  template <typename IndexList>
    const element&		operator()(const IndexList& indices) const;
  reference			operator[](index i);
  const_reference		operator[](index i) const;
  array_view<Dims>::type	operator[](const indices_tuple& r);
  const_array_view<Dims>::type	operator[](const indices_tuple& r) const;

  // queries
  element*			data();
  const element*		data() const;
  element*			origin();
  const element*		origin() const;
  const size_type*		shape() const;
  const index*			strides() const;
  const index*			index_bases() const;
  const storage_order_type&     storage_order() const;

  // comparators
  bool operator==(const multi_array_ref& rhs);
  bool operator!=(const multi_array_ref& rhs);
  bool operator<(const multi_array_ref& rhs);
  bool operator>(const multi_array_ref& rhs);
  bool operator>=(const multi_array_ref& rhs);
  bool operator<=(const multi_array_ref& rhs);

  // modifiers:
  template <typename InputIterator>
    void			assign(InputIterator begin, InputIterator end);
  template <typename SizeList>
    void			reshape(const SizeList& sizes)
  template <typename BaseList>	void reindex(const BaseList& values);
  void				reindex(index value);
};
]]>
</programlisting>
</formalpara>

<formalpara>
<title>Constructors</title>

<variablelist>
<varlistentry>
<term><programlisting>template &lt;typename ExtentList&gt;
explicit multi_array_ref(element* data, 
                     const ExtentList&amp; sizes,
                     const storage_order&amp; store = c_storage_order(),
                     const Allocator&amp; alloc = Allocator());
</programlisting></term>
<listitem>

<para>
This constructs a <literal>multi_array_ref</literal> using the specified
parameters.  <literal>sizes</literal> specifies the shape of the
constructed <literal>multi_array_ref</literal>.  <literal>store</literal>
specifies the storage order or layout in memory of the array
dimensions.  <literal>alloc</literal> is used to
allocate the contained elements.
</para>

<formalpara><title><literal>ExtentList</literal> Requirements</title>
<para>
<literal>ExtentList</literal> must model <ulink url="../../utility/Collection.html">Collection</ulink>.
</para>
</formalpara>

<formalpara><title>Preconditions</title>
<para><literal>sizes.size() == NumDims;</literal></para>
</formalpara>

</listitem>
</varlistentry>

<varlistentry>
<term>
<programlisting><![CDATA[explicit multi_array_ref(element* data,
                     extent_gen::gen_type<NumDims>::type ranges,
                     const storage_order& store = c_storage_order());]]>
</programlisting></term> 
<listitem>
<para>
This constructs a <literal>multi_array_ref</literal> using the specified
    parameters.  <literal>ranges</literal> specifies the shape and
index bases of the constructed multi_array_ref. It is the result of 
<literal>NumDims</literal> chained calls to 
    <literal>extent_gen::operator[]</literal>. <literal>store</literal>
specifies the storage order or layout in memory of the array
dimensions. 
</para>
</listitem>
</varlistentry> 


<varlistentry>
<term><programlisting>
<![CDATA[multi_array_ref(const multi_array_ref& x);]]>
</programlisting></term>
<listitem>
<para>This constructs a shallow copy of <literal>x</literal>.
</para>

<formalpara>
<title>Complexity</title>
<para> Constant time (for contrast, compare this to
the <literal>multi_array</literal> class copy constructor.
</para></formalpara>
</listitem>
</varlistentry>

</variablelist>

</formalpara>


<formalpara>
<title>Modifiers</title>

<variablelist>
<varlistentry>

<term><programlisting>
<![CDATA[multi_array_ref& operator=(const multi_array_ref& x);
template <class Array> multi_array_ref& operator=(const Array& x);]]>
</programlisting>
</term>

<listitem>
<para>This performs an element-wise copy of <literal>x</literal>
into the current <literal>multi_array_ref</literal>.</para>

<formalpara>
<title><literal>Array</literal> Requirements</title>
<para><literal>Array</literal> must model MultiArray. 
</para></formalpara>

<formalpara>
<title>Preconditions</title>
<para>
<programlisting>std::equal(this->shape(),this->shape()+this->num_dimensions(),
x.shape());</programlisting></para>
</formalpara>


<formalpara>
<title>Postconditions</title>
<para>
<programlisting>(*.this) == x;</programlisting>
</para>
</formalpara>

<formalpara>
<title>Complexity</title>
<para>The assignment operators perform 
O(<literal>x.num_elements()</literal>) calls to <literal>element</literal>'s 
copy constructor.</para></formalpara>
</listitem>
</varlistentry>
</variablelist>

</formalpara>
</sect2>
