• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Boost.MultiArray Reference Manual</title><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" title="Boost.MultiArray Reference Manual"><div class="titlepage"><div><div><h2 class="title"><a name="idp2304"></a>Boost.MultiArray Reference Manual</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Ronald</span> <span class="surname">Garcia</span></h3><div class="affiliation"><span class="orgname">Indiana University<br></span> <span class="orgdiv">Open Systems Lab<br></span></div></div></div><div><p class="copyright">Copyright � 2002 The Trustees of Indiana University</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#synopsis">Library Synopsis</a></span></dt><dt><span class="sect1"><a href="#MultiArray">MultiArray Concept</a></span></dt><dd><dl><dt><span class="sect2"><a href="#idp18427760">Notation</a></span></dt><dt><span class="sect2"><a href="#idp18446208">Associated Types</a></span></dt><dt><span class="sect2"><a href="#idp18501744">Valid expressions</a></span></dt><dt><span class="sect2"><a href="#idp18588736">Complexity guarantees</a></span></dt><dt><span class="sect2"><a href="#idp18591264">Invariants</a></span></dt><dt><span class="sect2"><a href="#view_types">Associated Types for Views</a></span></dt><dt><span class="sect2"><a href="#idp18737792">Models</a></span></dt></dl></dd><dt><span class="sect1"><a href="#array_types">Array Components</a></span></dt><dd><dl><dt><span class="sect2"><a href="#multi_array_class"><code class="literal">multi_array</code></a></span></dt><dt><span class="sect2"><a href="#multi_array_ref"><code class="literal">multi_array_ref</code></a></span></dt><dt><span class="sect2"><a href="#const_multi_array_ref"><code class="literal">const_multi_array_ref</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="#auxiliary">Auxiliary Components</a></span></dt><dd><dl><dt><span class="sect2"><a href="#multi_array_types"><code class="literal">multi_array_types</code></a></span></dt><dt><span class="sect2"><a href="#extent_range"><code class="classname">extent_range</code></a></span></dt><dt><span class="sect2"><a href="#extent_gen"><code class="classname">extent_gen</code></a></span></dt><dt><span class="sect2"><a href="#idp19487120">Global Objects</a></span></dt><dt><span class="sect2"><a href="#generators">View and SubArray Generators</a></span></dt><dt><span class="sect2"><a href="#memory_layout">Memory Layout Specifiers</a></span></dt><dt><span class="sect2"><a href="#range_checking">Range Checking</a></span></dt></dl></dd></dl></div><p>Boost.MultiArray is composed of several components.
2The MultiArray concept defines a generic interface to multidimensional
3containers.
4<code class="literal">multi_array</code> is a general purpose container class
5that models MultiArray. <code class="literal">multi_array_ref</code>
6and <code class="literal">const_multi_array_ref</code> are adapter
7classes. Using them,
8you can manipulate any block of contiguous data as though it were a
9<code class="literal">multi_array</code>.
10<code class="literal">const_multi_array_ref</code> differs from
11<code class="literal">multi_array_ref</code> in that its elements cannot
12be modified through its interface. Finally, several auxiliary classes are used
13to create and specialize arrays and some global objects are defined as
14part of the library interface.</p><div class="sect1" title="Library Synopsis"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="synopsis"></a>Library Synopsis</h2></div></div></div><p>To use Boost.MultiArray, you must include the header
15<code class="filename">boost/multi_array.hpp</code> in your source. This file
16brings the following declarations into scope:</p><pre class="programlisting">
17namespace boost {
18
19  namespace multi_array_types {
20    typedef *unspecified* index;
21    typedef *unspecified* size_type;
22    typedef *unspecified* difference_type;
23    typedef *unspecified* index_range;
24    typedef *unspecified* extent_range;
25    typedef *unspecified* index_gen;
26    typedef *unspecified* extent_gen;
27  }
28
29  template &lt;typename ValueType,
30            std::size_t NumDims,
31            typename Allocator = std::allocator&lt;ValueType&gt; &gt;
32  class multi_array;
33
34  template &lt;typename ValueType,
35            std::size_t NumDims&gt;
36  class multi_array_ref;
37
38  template &lt;typename ValueType,
39            std::size_t NumDims&gt;
40  class const_multi_array_ref;
41
42  multi_array_types::extent_gen extents;
43  multi_array_types::index_gen  indices;
44
45  template &lt;typename Array, int N&gt; class subarray_gen;
46  template &lt;typename Array, int N&gt; class const_subarray_gen;
47  template &lt;typename Array, int N&gt; class array_view_gen;
48  template &lt;typename Array, int N&gt; class const_array_view_gen;
49
50  class c_storage_order;
51  class fortran_storage_order;
52  template &lt;std::size_t NumDims&gt; class general_storage_order;
53
54}
55</pre></div><div class="sect1" title="MultiArray Concept"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="MultiArray"></a>MultiArray Concept</h2></div></div></div><p>The MultiArray
56concept defines an interface to hierarchically nested
57containers.  It specifies operations for accessing elements,
58traversing containers, and creating views
59of array data.
60MultiArray defines
61a flexible memory model that accomodates
62a variety of data layouts.
63</p><p>
64At each level (or dimension) of a MultiArray's
65container hierarchy lie a set of ordered containers, each of which
66contains the same number and type of values. The depth of this
67container hierarchy is the MultiArray's <span class="emphasis"><em>dimensionality</em></span>.
68MultiArray is recursively defined; the
69containers at each level of the container hierarchy model
70MultiArray as well. While each dimension of a MultiArray
71has its own size, the list of sizes for all dimensions
72defines the <span class="emphasis"><em>shape</em></span> of the entire MultiArray.
73At the base of this hierarchy lie 1-dimensional
74MultiArrays.  Their values are the contained
75objects of interest and not part of the container hierarchy. These are
76the MultiArray's elements.
77</p><p>
78Like other container concepts, MultiArray exports
79iterators to traverse its values. In addition, values can be
80addressed directly using the familiar bracket notation.
81</p><p>
82MultiArray also specifies
83routines for creating
84specialized views. A <span class="emphasis"><em>view</em></span> lets you treat a
85subset of the underlying
86elements in a MultiArray as though it were a separate
87MultiArray. Since a view refers to the same underlying elements,
88changes made to a view's elements will be reflected in the original
89MultiArray. For
90example, given a 3-dimensional "cube" of elements, a 2-dimensional
91slice can be viewed as if it were an independent
92MultiArray.
93
94Views are created using <code class="literal">index_gen</code> and
95<code class="literal">index_range</code> objects.
96<code class="literal">index_range</code>s denote elements from a certain
97dimension that are to be included in a
98view. <code class="literal">index_gen</code> aggregates range data and performs
99bookkeeping to determine the view type to be returned.
100
101MultiArray's <code class="literal">operator[]</code>
102 must be passed the result
103of <code class="literal">N</code> chained calls to
104<code class="literal">index_gen::operator[]</code>, i.e.
105
106</p><pre class="programlisting">indices[a0][a1]...[aN];
107</pre><p>
108
109where <code class="literal">N</code> is the
110MultiArray's dimensionality and
111<code class="literal">indices</code> an object of type <code class="literal">index_gen</code>.
112
113The view type is dependent upon the number of degenerate dimensions
114specified to <code class="literal">index_gen</code>.  A degenerate dimension
115occurs when a single-index is specified to
116<code class="literal">index_gen</code> for a certain dimension.  For example, if
117<code class="literal">indices</code> is an object of type
118<code class="literal">index_gen</code>, then the following example:
119
120</p><pre class="programlisting">indices[index_range(0,5)][2][index_range(0,4)];
121</pre><p>
122
123has a degenerate second dimension.  The view generated from the above
124specification will have 2 dimensions with shape <code class="literal">5 x 4</code>.
125If the "<code class="literal">2</code>" above were replaced with
126another <code class="literal">index_range</code> object, for example:
127
128</p><pre class="programlisting">indices[index_range(0,5)][index_range(0,2)][index_range(0,4)];
129</pre><p>
130
131then the view would have 3 dimensions.</p><p>
132MultiArray exports
133information regarding the memory
134layout of its contained elements. Its memory model for elements is
135completely defined by 4 properties: the origin, shape, index bases,
136and strides.  The origin is the address in memory of the element
137accessed as <code class="literal">a[0][0]...[0]</code>, where
138<code class="literal">a</code> is a MultiArray. The shape is a list of numbers
139specifying the size of containers at each dimension.  For example, the
140first extent is the size of the outermost container, the second extent
141is the size of its subcontainers, and so on. The index bases are a
142list of signed values specifying the index of the first value in a
143container. All containers at the same dimension share the same index
144base.  Note that since positive index bases are
145possible, the origin need not exist in order to determine the location
146in memory of the MultiArray's elements.
147  The strides determine how index values are mapped to memory offsets.
148They accomodate a
149number of possible element layouts.  For example, the elements of a 2
150dimensional array can be stored by row (i.e., the elements of each row
151are stored contiguously) or by column (i.e., the elements of each
152column are stored contiguously).
153</p><p>
154Two concept checking classes for the MultiArray concepts
155(<code class="literal">ConstMultiArrayConcept</code> and
156<code class="literal">MutableMultiArrayConcept</code>) are in the namespace
157<code class="literal">boost::multi_array_concepts</code> in
158<code class="literal">&lt;boost/multi_array/concept_checks.hpp&gt;</code>.
159</p><div class="sect2" title="Notation"><div class="titlepage"><div><div><h3 class="title"><a name="idp18427760"></a>Notation</h3></div></div></div><p>What follows are the descriptions of symbols that will be used
160to describe the MultiArray interface.</p><div class="table"><a name="idp18428768"></a><p class="title"><b>Table�1.�Notation</b></p><div class="table-contents"><table summary="Notation" border="1"><colgroup><col><col></colgroup><tbody><tr><td><code class="literal">A</code></td><td>A type that is a model of MultiArray
161</td></tr><tr><td><code class="literal">a,b</code></td><td>Objects of type <code class="literal">A</code></td></tr><tr><td><code class="literal">NumDims</code></td><td>The numeric dimension parameter associated with
162<code class="literal">A</code>.</td></tr><tr><td><code class="literal">Dims</code></td><td>Some numeric dimension parameter such that
163<code class="literal">0&lt;Dims&lt;NumDims</code>.
164</td></tr><tr><td><code class="literal">indices</code></td><td>An object created by some number of chained calls
165to <code class="literal">index_gen::operator[](index_range)</code>.</td></tr><tr><td><code class="literal">index_list</code></td><td>An object whose type models
166<a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a>
167</td></tr><tr><td><code class="literal">idx</code></td><td>A signed integral value.</td></tr><tr><td><code class="literal">tmp</code></td><td>An object of type
168	      <code class="literal">boost::array&lt;index,NumDims&gt;</code></td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="Associated Types"><div class="titlepage"><div><div><h3 class="title"><a name="idp18446208"></a>Associated Types</h3></div></div></div><p>
169</p><div class="table"><a name="idp18447104"></a><p class="title"><b>Table�2.�Associated Types</b></p><div class="table-contents"><table summary="Associated Types" border="1"><colgroup><col><col></colgroup><thead><tr><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">value_type</code></td><td>This is the value type of the container.
170  If <code class="literal">NumDims == 1</code>, then this is
171<code class="literal">element</code>. Otherwise, this is the value type of the
172immediately nested containers.
173</td></tr><tr><td>
174<code class="literal">reference</code>
175</td><td>
176This is the reference type of the contained value.
177If <code class="literal">NumDims == 1</code>, then this is
178<code class="literal">element&amp;</code>. Otherwise, this is the same type as
179<code class="literal">template subarray&lt;NumDims-1&gt;::type</code>.
180</td></tr><tr><td>
181<code class="literal">const_reference</code>
182</td><td>
183This is the const reference type of the contained value.
184If <code class="literal">NumDims == 1</code>, then this is
185<code class="literal">const element&amp;</code>. Otherwise, this is the same
186type as
187<code class="literal">template const_subarray&lt;NumDims-1&gt;::type</code>.
188</td></tr><tr><td>
189<code class="literal">size_type</code>
190</td><td>
191This is an unsigned integral type.  It is primarily used to specify array shape.
192</td></tr><tr><td>
193<code class="literal">difference_type</code>
194</td><td>
195This is a signed integral type used to represent the distance between two
196iterators. It is the same type as
197<code class="literal">std::iterator_traits&lt;iterator&gt;::difference_type</code>.
198</td></tr><tr><td><code class="literal">iterator</code></td><td>
199This is an iterator over the values of <code class="literal">A</code>.
200If <code class="literal">NumDims == 1</code>, then it models
201<a class="ulink" href="http://www.boost.org/doc/html/RandomAccessIterator.html" target="_top">
202<code class="literal">Random Access Iterator</code></a>.
203Otherwise it models
204<a class="ulink" href="./iterator_categories.html#concept_RandomAccessTraversalIterator" target="_top">
205Random Access Traversal Iterator</a>,
206<a class="ulink" href="./iterator_categories.html#concept_ReadableIterator" target="_top">
207Readable Iterator</a>,
208<a class="ulink" href="./iterator_categories.html#concept_WritableIterator" target="_top">
209Writable Iterator</a>, and
210<a class="ulink" href="http://www.boost.org/doc/html/OutputIterator.html" target="_top">
211<code class="literal">Output Iterator</code></a>.
212</td></tr><tr><td>
213<code class="literal">const_iterator</code>
214</td><td>
215This is the const iterator over the values of <code class="literal">A</code>.
216</td></tr><tr><td>
217<code class="literal">reverse_iterator</code>
218</td><td>
219This is the reversed iterator, used to iterate backwards over the values of
220<code class="literal">A</code>.
221</td></tr><tr><td>
222<code class="literal">const_reverse_iterator</code>
223</td><td>
224This is the reversed const iterator.
225<code class="literal">A</code>.
226</td></tr><tr><td>
227<code class="literal">element</code>
228</td><td>
229This is the type of objects stored at the base of the
230hierarchy of MultiArrays. It is the same as
231<code class="literal">template subarray&lt;1&gt;::value_type</code>
232</td></tr><tr><td>
233<code class="literal">index</code>
234</td><td>
235This is a signed integral type used for indexing into <code class="literal">A</code>. It
236is also used to represent strides and index bases.
237</td></tr><tr><td>
238<code class="literal">index_gen</code>
239</td><td>
240This type is used to create a tuple of <code class="literal">index_range</code>s
241passed to <code class="literal">operator[]</code> to create
242an <code class="literal">array_view&lt;Dims&gt;::type</code> object.
243</td></tr><tr><td>
244<code class="literal">index_range</code>
245</td><td>
246This type specifies a range of indices over some dimension of a
247MultiArray.  This range will be visible through an
248<code class="literal">array_view&lt;Dims&gt;::type</code> object.
249</td></tr><tr><td>
250<code class="literal">template subarray&lt;Dims&gt;::type</code>
251</td><td>
252This is subarray type with <code class="literal">Dims</code> dimensions.
253It is the reference type of the <code class="literal">(NumDims - Dims)</code>
254dimension of <code class="literal">A</code> and also models
255MultiArray.
256</td></tr><tr><td>
257<code class="literal">template const_subarray&lt;Dims&gt;::type</code>
258</td><td>
259This is the const subarray type.
260</td></tr><tr><td>
261<code class="literal">template array_view&lt;Dims&gt;::type</code>
262</td><td>
263This is the view type with <code class="literal">Dims</code> dimensions.  It is
264returned by calling <code class="literal">operator[](<code class="literal">indices</code>)</code>.
265It models MultiArray.
266</td></tr><tr><td>
267<code class="literal">template
268const_array_view&lt;Dims&gt;::type</code>
269</td><td>
270This is the const view type with <code class="literal">Dims</code> dimensions.
271</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="Valid expressions"><div class="titlepage"><div><div><h3 class="title"><a name="idp18501744"></a>Valid expressions</h3></div></div></div><div class="table"><a name="idp18502256"></a><p class="title"><b>Table�3.�Valid Expressions</b></p><div class="table-contents"><table summary="Valid Expressions" border="1"><colgroup><col><col><col></colgroup><thead><tr><th>Expression</th><th>Return type</th><th>Semantics</th></tr></thead><tbody><tr><td><code class="literal">A::dimensionality</code></td><td><code class="literal">size_type</code></td><td>This compile-time constant represents the number of
272dimensions of the array (note that
273<code class="literal">A::dimensionality == NumDims</code>).</td></tr><tr><td><code class="literal">a.shape()</code></td><td><code class="literal">const size_type*</code></td><td>
274This returns a list of <code class="literal">NumDims</code> elements specifying the
275extent of each array dimension.
276</td></tr><tr><td><code class="literal">a.strides()</code></td><td><code class="literal">const index*</code></td><td>
277This returns a list of <code class="literal">NumDims</code> elements specifying the
278stride associated with each array dimension. When accessing values,
279strides is used to calculate an element's location in memory.
280</td></tr><tr><td><code class="literal">a.index_bases()</code></td><td><code class="literal">const index*</code></td><td>
281This returns a list of <code class="literal">NumDims</code> elements specifying the
282numeric index of the first element for each array dimension.
283</td></tr><tr><td><code class="literal">a.origin()</code></td><td>
284<code class="literal">element*</code> if <code class="literal">a</code> is mutable,
285<code class="literal">const element*</code> otherwise.
286</td><td>
287This returns the address of the element accessed by the expression
288<code class="literal">a[0][0]...[0].</code>. If the index bases are positive,
289this element won't exist, but the address can still be used to locate
290a valid element given its indices.
291</td></tr><tr><td><code class="literal">a.num_dimensions()</code></td><td><code class="literal">size_type</code></td><td>This returns the number of dimensions of the array
292(note that <code class="literal">a.num_dimensions() == NumDims</code>).</td></tr><tr><td><code class="literal">a.num_elements()</code></td><td><code class="literal">size_type</code></td><td>This returns the number of elements contained
293in the array. It is equivalent to the following code:
294<pre class="programlisting">
295std::accumulate(a.shape(),a.shape+a.num_dimensions(),
296    size_type(1),std::multiplies&lt;size_type&gt;());
297</pre>
298</td></tr><tr><td><code class="literal">a.size()</code></td><td><code class="literal">size_type</code></td><td>
299This returns the number of values contained in
300<code class="literal">a</code>. It is equivalent to <code class="literal">a.shape()[0];</code>
301</td></tr><tr><td><code class="literal">a(index_list)</code></td><td>
302<code class="literal">element&amp;</code>;  if <code class="literal">a</code> is mutable,
303<code class="literal">const element&amp;</code> otherwise.
304            </td><td>
305This expression accesses a specific element of
306<code class="literal">a</code>.<code class="literal">index_list</code> is the unique set
307of indices that address the element returned.  It is
308equivalent to the following code (disregarding intermediate temporaries):
309<pre class="programlisting">
310    // multiply indices by strides
311    std::transform(index_list.begin(), index_list.end(),
312      a.strides(), tmp.begin(), std::multiplies&lt;index&gt;()),
313
314    // add the sum of the products to the origin
315    *std::accumulate(tmp.begin(), tmp.end(), a.origin());
316</pre>
317</td></tr><tr><td><code class="literal">a.begin()</code></td><td>
318<code class="literal">iterator</code> if <code class="literal">a</code> is mutable,
319<code class="literal">const_iterator</code> otherwise.
320            </td><td>This returns an iterator pointing to the beginning of
321<code class="literal">a</code>.</td></tr><tr><td><code class="literal">a.end()</code></td><td>
322<code class="literal">iterator</code> if <code class="literal">a</code> is mutable,
323<code class="literal">const_iterator</code> otherwise.
324            </td><td>This returns an iterator pointing to the end of
325<code class="literal">a</code>.</td></tr><tr><td><code class="literal">a.rbegin()</code></td><td>
326<code class="literal">reverse_iterator</code> if <code class="literal">a</code> is mutable,
327<code class="literal">const_reverse_iterator</code> otherwise.
328            </td><td>This returns a reverse iterator pointing to the
329beginning of <code class="literal">a</code> reversed.
330</td></tr><tr><td><code class="literal">a.rend()</code></td><td>
331<code class="literal">reverse_iterator</code> if <code class="literal">a</code> is mutable,
332<code class="literal">const_reverse_iterator</code> otherwise.
333</td><td>
334This returns a reverse iterator pointing to the end of <code class="literal">a</code>
335reversed.
336</td></tr><tr><td><code class="literal">a[idx]</code></td><td>
337<code class="literal">reference</code> if <code class="literal">a</code> is mutable,
338<code class="literal">const_reference</code> otherwise.
339            </td><td>
340This returns a reference type that is bound to the index
341<code class="literal">idx</code> value of <code class="literal">a</code>.  Note that if
342<code class="literal">i</code> is the index base for this dimension, the above
343expression returns the <code class="literal">(idx-i)</code>th element (counting
344from zero).  The expression is equivalent to
345<code class="literal">*(a.begin()+idx-a.index_bases()[0]);</code>.
346</td></tr><tr><td><code class="literal">a[indices]</code></td><td>
347<code class="literal">array_view&lt;Dims&gt;::type</code> if
348<code class="literal">a</code> is mutable,
349<code class="literal">const_array_view&lt;Dims&gt;::type</code> otherwise.
350            </td><td>
351This expression generates a view of the array determined by the
352<code class="literal">index_range</code> and <code class="literal">index</code> values
353 used to construct <code class="literal">indices</code>.
354</td></tr><tr><td><code class="literal">a == b</code></td><td>bool</td><td>This performs a lexicographical comparison of the
355values of <code class="literal">a</code> and <code class="literal">b</code>.  The element
356type must model <a class="ulink" href="https://www.boost.org/sgi/stl/EqualityComparable.html" target="_top">EqualityComparable</a> for this
357expression to be valid.</td></tr><tr><td><code class="literal">a &lt; b</code></td><td>bool</td><td>This performs a lexicographical comparison of the
358values of <code class="literal">a</code> and <code class="literal">b</code>.  The element
359type must model <a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a> for this
360expression to be valid.</td></tr><tr><td><code class="literal">a &lt;= b</code></td><td>bool</td><td>This performs a lexicographical comparison of the
361values of <code class="literal">a</code> and <code class="literal">b</code>.  The element
362type must model <a class="ulink" href="https://www.boost.org/sgi/stl/EqualityComparable.html" target="_top">EqualityComparable</a> and
363<a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a> for this
364expression to be valid.</td></tr><tr><td><code class="literal">a &gt; b</code></td><td>bool</td><td>This performs a lexicographical comparison of the
365values of <code class="literal">a</code> and <code class="literal">b</code>.  The element
366type must model <a class="ulink" href="https://www.boost.org/sgi/stl/EqualityComparable.html" target="_top">EqualityComparable</a> and
367<a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a> for this
368expression to be valid.</td></tr><tr><td><code class="literal">a &gt;= b</code></td><td>bool</td><td>This performs a lexicographical comparison of the
369values of <code class="literal">a</code> and <code class="literal">b</code>.  The element
370type must model <a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a> for this
371expression to be valid.</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="Complexity guarantees"><div class="titlepage"><div><div><h3 class="title"><a name="idp18588736"></a>Complexity guarantees</h3></div></div></div><code class="literal">begin()</code> and <code class="literal">end()</code> execute in amortized
372constant time.
373<code class="literal">size()</code> executes in at most linear time in the
374MultiArray's size.
375</div><div class="sect2" title="Invariants"><div class="titlepage"><div><div><h3 class="title"><a name="idp18591264"></a>Invariants</h3></div></div></div><div class="table"><a name="idp18591904"></a><p class="title"><b>Table�4.�Invariants</b></p><div class="table-contents"><table summary="Invariants" border="1"><colgroup><col><col></colgroup><tbody><tr><td>Valid range</td><td><code class="literal">[a.begin(),a.end())</code> is a valid range.
376            </td></tr><tr><td>Range size</td><td>
377<code class="literal">a.size() == std::distance(a.begin(),a.end());</code>.
378</td></tr><tr><td>Completeness</td><td>
379Iteration through the range
380<code class="literal">[a.begin(),a.end())</code> will traverse across every
381<code class="literal">value_type</code> of <code class="literal">a</code>.
382</td></tr><tr><td>Accessor Equivalence</td><td>
383Calling <code class="literal">a[a1][a2]...[aN]</code> where <code class="literal">N==NumDims</code>
384yields the same result as calling
385<code class="literal">a(index_list)</code>, where <code class="literal">index_list</code>
386is a <a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a> containing the values <code class="literal">a1...aN</code>.
387</td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect2" title="Associated Types for Views"><div class="titlepage"><div><div><h3 class="title"><a name="view_types"></a>Associated Types for Views</h3></div></div></div><p>The following MultiArray  associated
388types define the interface for creating views of existing
389MultiArrays. Their interfaces and roles in the
390concept are described below.</p><div class="sect3" title="index_range"><div class="titlepage"><div><div><h4 class="title"><a name="index_range"></a><code class="literal">index_range</code></h4></div></div></div><p><code class="literal">index_range</code> objects represent half-open
391strided intervals.  They are aggregated (using an
392<code class="literal">index_gen</code> object) and passed to
393a MultiArray's <code class="literal">operator[]</code>
394to create an array view. When creating a view,
395each <code class="literal">index_range</code> denotes a range of
396valid indices along one dimension of a MultiArray.
397Elements that are accessed through the set of ranges specified will be
398included in the constructed view. In some cases, an
399<code class="literal">index_range</code> is created without specifying start
400or finish values.  In those cases, the object is interpreted to
401start at the beginning of a MultiArray dimension
402and end at its end.</p><p>
403<code class="literal">index_range</code> objects can be constructed and modified
404several ways in order to allow convenient and clear expression of a
405range of indices.  To specify ranges, <code class="literal">index_range</code>
406supports a set of constructors, mutating member functions, and a novel
407specification involving inequality operators.  Using inequality
408operators,  a half open range [5,10) can be specified as follows:
409</p><pre class="programlisting">5 &lt;= index_range() &lt; 10;</pre><p> or
410</p><pre class="programlisting">4 &lt; index_range() &lt;= 9;</pre><p> and so on.
411
412The following describes the
413<code class="literal">index_range</code> interface.
414</p><div class="table"><a name="idp18614960"></a><p class="title"><b>Table�5.�Notation</b></p><div class="table-contents"><table summary="Notation" border="1"><colgroup><col><col></colgroup><tbody><tr><td><code class="literal">i</code></td><td>An object of type <code class="literal">index_range</code>.</td></tr><tr><td><code class="literal">idx,idx1,idx2,idx3</code></td><td>Objects of type <code class="literal">index</code>.</td></tr></tbody></table></div></div><br class="table-break"><div class="table"><a name="idp18620944"></a><p class="title"><b>Table�6.�Associated Types</b></p><div class="table-contents"><table summary="Associated Types" border="1"><colgroup><col><col></colgroup><thead><tr><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">index</code></td><td>This is a signed integral type. It is used to
415specify the start, finish, and stride values.</td></tr><tr><td><code class="literal">size_type</code></td><td>This is an unsigned integral type. It is used to
416report the size of the range an <code class="literal">index_range</code>
417represents.</td></tr></tbody></table></div></div><br class="table-break"><div class="table"><a name="idp18627920"></a><p class="title"><b>Table�7.�Valid Expressions</b></p><div class="table-contents"><table summary="Valid Expressions" border="1"><colgroup><col><col><col></colgroup><thead><tr><th>Expression</th><th>Return type</th><th>Semantics</th></tr></thead><tbody><tr><td><code class="literal">index_range(idx1,idx2,idx3)</code></td><td><code class="literal">index_range</code></td><td>This constructs an <code class="literal">index_range</code>
418	    representing the interval <code class="literal">[idx1,idx2)</code>
419 with stride <code class="literal">idx3</code>.</td></tr><tr><td><code class="literal">index_range(idx1,idx2)</code></td><td><code class="literal">index_range</code></td><td>This constructs an <code class="literal">index_range</code>
420	    representing the interval <code class="literal">[idx1,idx2)</code>
421 with unit stride. It is equivalent to
422	    <code class="literal">index_range(idx1,idx2,1)</code>.</td></tr><tr><td><code class="literal">index_range()</code></td><td><code class="literal">index_range</code></td><td>This construct an <code class="literal">index_range</code>
423with unspecified start and finish values.</td></tr><tr><td><code class="literal">i.start(idx1)</code></td><td><code class="literal">index&amp;</code></td><td>This sets the start index of <code class="literal">i</code> to
424	    <code class="literal">idx</code>.</td></tr><tr><td><code class="literal">i.finish(idx)</code></td><td><code class="literal">index&amp;</code></td><td>This sets the finish index of <code class="literal">i</code> to
425            <code class="literal">idx</code>.</td></tr><tr><td><code class="literal">i.stride(idx)</code></td><td><code class="literal">index&amp;</code></td><td>This sets the stride length of <code class="literal">i</code> to
426            <code class="literal">idx</code>.</td></tr><tr><td><code class="literal">i.start()</code></td><td><code class="literal">index</code></td><td>This returns the start index of <code class="literal">i</code>.</td></tr><tr><td><code class="literal">i.finish()</code></td><td><code class="literal">index</code></td><td>This returns the finish index of <code class="literal">i</code>.</td></tr><tr><td><code class="literal">i.stride()</code></td><td><code class="literal">index</code></td><td>This returns the stride length of <code class="literal">i</code>.</td></tr><tr><td><code class="literal">i.get_start(idx)</code></td><td><code class="literal">index</code></td><td>If <code class="literal">i</code> specifies a start
427value, this is equivalent to <code class="literal">i.start()</code>. Otherwise it
428returns <code class="literal">idx</code>.</td></tr><tr><td><code class="literal">i.get_finish(idx)</code></td><td><code class="literal">index</code></td><td>If <code class="literal">i</code> specifies a finish
429value, this is equivalent to <code class="literal">i.finish()</code>. Otherwise it
430returns <code class="literal">idx</code>.</td></tr><tr><td><code class="literal">i.size(idx)</code></td><td><code class="literal">size_type</code></td><td>If <code class="literal">i</code> specifies a both finish and
431start values, this is equivalent to
432<code class="literal">(i.finish()-i.start())/i.stride()</code>. Otherwise it
433returns <code class="literal">idx</code>.</td></tr><tr><td><code class="literal">i &lt; idx</code></td><td><code class="literal">index</code></td><td>This is another syntax for specifying the finish
434value. This notation does not include
435<code class="literal">idx</code> in the range of valid indices. It is equivalent to
436<code class="literal">index_range(r.start(), idx, r.stride())</code></td></tr><tr><td><code class="literal">i &lt;= idx</code></td><td><code class="literal">index</code></td><td>This is another syntax for specifying the finish
437value. This notation includes
438<code class="literal">idx</code> in the range of valid indices. It is equivalent to
439<code class="literal">index_range(r.start(), idx + 1, r.stride())</code></td></tr><tr><td><code class="literal">idx &lt; i</code></td><td><code class="literal">index</code></td><td>This is another syntax for specifying the start
440value. This notation does not include
441<code class="literal">idx</code> in the range of valid indices. It is equivalent to
442<code class="literal">index_range(idx + 1, i.finish(), i.stride())</code>.</td></tr><tr><td><code class="literal">idx &lt;= i</code></td><td><code class="literal">index</code></td><td>This is another syntax for specifying the start
443value. This notation includes
444<code class="literal">idx1</code> in the range of valid indices. It is equivalent to
445<code class="literal">index_range(idx, i.finish(), i.stride())</code>.</td></tr><tr><td><code class="literal">i + idx</code></td><td><code class="literal">index</code></td><td>This expression shifts the start and finish values
446of <code class="literal">i</code> up by <code class="literal">idx</code>. It is equivalent to
447<code class="literal">index_range(r.start()+idx1, r.finish()+idx, r.stride())</code></td></tr><tr><td><code class="literal">i - idx</code></td><td><code class="literal">index</code></td><td>This expression shifts the start and finish values
448of <code class="literal">i</code> up by <code class="literal">idx</code>. It is equivalent to
449<code class="literal">index_range(r.start()-idx1, r.finish()-idx, r.stride())</code></td></tr></tbody></table></div></div><br class="table-break"></div><div class="sect3" title="index_gen"><div class="titlepage"><div><div><h4 class="title"><a name="index_gen"></a><code class="literal">index_gen</code></h4></div></div></div><p> <code class="literal">index_gen</code> aggregates
450<code class="literal">index_range</code> objects in order to specify view
451parameters.  Chained calls to <code class="literal">operator[]</code> store
452range and dimension information used to
453instantiate a new view into a MultiArray.
454</p><div class="table"><a name="idp18699808"></a><p class="title"><b>Table�8.�Notation</b></p><div class="table-contents"><table summary="Notation" border="1"><colgroup><col><col></colgroup><tbody><tr><td><code class="literal">Dims,Ranges</code></td><td>Unsigned integral values.</td></tr><tr><td><code class="literal">x</code></td><td>An object of type
455<code class="literal">template gen_type&lt;Dims,Ranges&gt;::type</code>.</td></tr><tr><td><code class="literal">i</code></td><td>An object of type
456<code class="literal">index_range</code>.</td></tr><tr><td><code class="literal">idx</code></td><td>Objects of type <code class="literal">index</code>.</td></tr></tbody></table></div></div><br class="table-break"><div class="table"><a name="idp18709408"></a><p class="title"><b>Table�9.�Associated Types</b></p><div class="table-contents"><table summary="Associated Types" border="1"><colgroup><col><col></colgroup><thead><tr><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">index</code></td><td>This is a signed integral type. It is used to
457specify degenerate dimensions.</td></tr><tr><td><code class="literal">size_type</code></td><td>This is an unsigned integral type. It is used to
458report the size of the range an <code class="literal">index_range</code>
459represents.</td></tr><tr><td>
460<code class="literal">template gen_type::&lt;Dims,Ranges&gt;::type</code></td><td>This type generator names the result of
461<code class="literal">Dims</code> chained calls to
462<code class="literal">index_gen::operator[]</code>.  The
463<code class="literal">Ranges</code> parameter is determined by the number of
464degenerate ranges specified (i.e. calls to
465<code class="literal">operator[](index)</code>). Note that
466<code class="classname">index_gen</code> and
467<code class="classname">gen_type&lt;0,0&gt;::type</code> are the same type.</td></tr></tbody></table></div></div><br class="table-break"><div class="table"><a name="idp18721296"></a><p class="title"><b>Table�10.�Valid Expressions</b></p><div class="table-contents"><table summary="Valid Expressions" border="1"><colgroup><col><col><col></colgroup><thead><tr><th>Expression</th><th>Return type</th><th>Semantics</th></tr></thead><tbody><tr><td><code class="literal">index_gen()</code></td><td><code class="literal">gen_type&lt;0,0&gt;::type</code></td><td>This constructs an <code class="literal">index_gen</code>
468object. This object can then be used to generate tuples of
469<code class="literal">index_range</code> values.</td></tr><tr><td><code class="literal">x[i]</code></td><td><code class="literal">gen_type&lt;Dims+1,Ranges+1&gt;::type</code>
470</td><td>Returns a new object containing all previous
471<code class="classname">index_range</code> objects in addition to
472<code class="literal">i.</code> Chained calls to
473<code class="function">operator[]</code> are the means by which
474<code class="classname">index_range</code> objects are aggregated.</td></tr><tr><td><code class="literal">x[idx]</code></td><td><code class="literal">gen_type&lt;Dims,Ranges+1&gt;::type</code>
475</td><td>Returns a new object containing all previous
476<code class="classname">index_range</code> objects in addition to a degenerate
477range, <code class="literal">index_range(idx,idx).</code> Note that this is NOT
478equivalent to <code class="literal">x[index_range(idx,idx)].</code>, which will
479return an object of type
480<code class="literal">gen_type&lt;Dims+1,Ranges+1&gt;::type</code>.
481</td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="sect2" title="Models"><div class="titlepage"><div><div><h3 class="title"><a name="idp18737792"></a>Models</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><code class="literal">multi_array</code></li><li class="listitem"><code class="literal">multi_array_ref</code></li><li class="listitem"><code class="literal">const_multi_array_ref</code></li><li class="listitem"><code class="literal">template array_view&lt;Dims&gt;::type</code></li><li class="listitem"><code class="literal">template const_array_view&lt;Dims&gt;::type</code></li><li class="listitem"><code class="literal">template subarray&lt;Dims&gt;::type</code></li><li class="listitem"><code class="literal">template const_subarray&lt;Dims&gt;::type</code></li></ul></div></div></div><div class="sect1" title="Array Components"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="array_types"></a>Array Components</h2></div></div></div><p>
482Boost.MultiArray defines an array class,
483<code class="literal">multi_array</code>, and two adapter classes,
484<code class="literal">multi_array_ref</code> and
485<code class="literal">const_multi_array_ref</code>. The three classes model
486MultiArray and so they share a lot of functionality.
487<code class="literal">multi_array_ref</code> differs from
488<code class="literal">multi_array</code> in that the
489<code class="literal">multi_array</code> manages its own memory, while
490<code class="literal">multi_array_ref</code> is passed a block of memory that it
491expects to be externally managed.
492<code class="literal">const_multi_array_ref</code> differs from
493<code class="literal">multi_array_ref</code> in that the underlying elements it
494adapts cannot be modified through its interface, though some array
495properties, including the array shape and index bases, can be altered.
496Functionality the classes have in common is described
497below.
498</p><p title="Note: Preconditions, Effects, and Implementation"><b>Note: Preconditions, Effects, and Implementation.�</b>
499Throughout the following sections, small pieces of C++ code are
500used to specify constraints such as preconditions, effects, and
501postconditions.  These do not necessarily describe the underlying
502implementation of array components; rather, they describe the
503expected input to and
504behavior of the specified operations.  Failure to meet
505preconditions results in undefined behavior. Not all effects
506(i.e. copy constructors, etc.) must be mimicked exactly.  The code
507snippets for effects intend to capture the essence of the described
508operation.
509</p><p title="Queries"><b>Queries.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">element* data();
510const element* data() const;</pre></span></dt><dd><p>This returns a pointer to the beginning of the
511contiguous block that contains the array's data. If all dimensions of
512the array are 0-indexed and stored in ascending order, this is
513equivalent to <code class="literal">origin()</code>. Note that
514<code class="literal">const_multi_array_ref</code> only provides the const
515version of this function.
516</p></dd><dt><span class="term"><pre class="programlisting">element* origin();
517const element* origin() const;</pre></span></dt><dd><p>This returns the origin element of the
518<code class="literal">multi_array</code>. Note that
519<code class="literal">const_multi_array_ref</code> only provides the const
520version of this function. (Required by MultiArray)
521</p></dd><dt><span class="term"><code class="function">const index* index_bases();</code></span></dt><dd><p>This returns the index bases for the
522<code class="literal">multi_array</code>. (Required by MultiArray)
523</p></dd><dt><span class="term"><code class="function">const index* strides();</code></span></dt><dd><p>This returns the strides for the
524<code class="literal">multi_array</code>. (Required by MultiArray)
525</p></dd><dt><span class="term"><code class="function">const size_type* shape();</code></span></dt><dd><p>This returns the shape of the
526<code class="literal">multi_array</code>. (Required by MultiArray)
527</p></dd></dl></div><p title="Comparators"><b>Comparators.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">
528bool operator==(const *array-type*&amp; rhs);
529bool operator!=(const *array-type*&amp; rhs);
530bool operator&lt;(const *array-type*&amp; rhs);
531bool operator&gt;(const *array-type*&amp; rhs);
532bool operator&gt;=(const *array-type*&amp; rhs);
533bool operator&lt;=(const *array-type*&amp; rhs);</pre></span></dt><dd><p>Each comparator executes a lexicographical compare over
534the value types of the two arrays.
535(Required by MultiArray)
536</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">element</code> must support the
537comparator corresponding to that called on
538<code class="literal">multi_array</code>.</p><p title="Complexity"><b>Complexity.�</b>O(<code class="literal">num_elements()</code>).</p></dd></dl></div><p title="Modifiers"><b>Modifiers.�</b></p><div class="variablelist"><dl><dt><span class="term">
539<pre class="programlisting">
540
541template &lt;typename SizeList&gt;
542void reshape(const SizeList&amp; sizes)
543
544</pre>
545</span></dt><dd><p>This changes the shape of the <code class="literal">multi_array</code>.  The
546number of elements and the index bases remain the same, but the number
547of values at each level of the nested container hierarchy may
548change.</p><p title="SizeList Requirements"><b><code class="literal">SizeList</code> Requirements.�</b><code class="literal">SizeList</code> must model
549<a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a>.</p><p title="Preconditions"><b>Preconditions.�</b>
550</p><pre class="programlisting">
551std::accumulate(sizes.begin(),sizes.end(),size_type(1),std::times&lt;size_type&gt;()) == this-&gt;num_elements();
552sizes.size() == NumDims;
553</pre><p title="Postconditions"><b>Postconditions.�</b>
554<code class="literal">std::equal(sizes.begin(),sizes.end(),this-&gt;shape) == true;</code>
555</p></dd><dt><span class="term">
556<pre class="programlisting">
557
558template &lt;typename BaseList&gt;
559void reindex(const BaseList&amp; values);
560
561</pre>
562</span></dt><dd><p>This changes the index bases of the <code class="literal">multi_array</code> to
563correspond to the the values in <code class="literal">values</code>.</p><p title="BaseList Requirements"><b><code class="literal">BaseList</code> Requirements.�</b><code class="literal">BaseList</code> must model
564<a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a>.</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">values.size() == NumDims;</code></p><p title="Postconditions"><b>Postconditions.�</b><code class="literal">std::equal(values.begin(),values.end(),this-&gt;index_bases());
565</code></p></dd><dt><span class="term">
566<pre class="programlisting">
567
568void reindex(index value);
569
570</pre>
571</span></dt><dd><p>This changes the index bases of all dimensions of the
572<code class="literal">multi_array</code> to <code class="literal">value</code>.</p><p title="Postconditions"><b>Postconditions.�</b>
573</p><pre class="programlisting">
574
575std::count_if(this-&gt;index_bases(),this-&gt;index_bases()+this-&gt;num_dimensions(),
576              std::bind_2nd(std::equal_to&lt;index&gt;(),value)) ==
577              this-&gt;num_dimensions();
578
579</pre><p title="Postconditions">
580</p></dd></dl></div><div class="sect2" title="multi_array"><div class="titlepage"><div><div><h3 class="title"><a name="multi_array_class"></a><code class="literal">multi_array</code></h3></div></div></div><p>
581<code class="literal">multi_array</code> is a multi-dimensional container that
582supports random access iteration. Its number of dimensions is
583fixed at compile time, but its shape and the number of elements it
584contains are specified during its construction. The number of elements
585will remain fixed for the duration of a
586<code class="literal">multi_array</code>'s lifetime, but the shape of the container can
587be changed. A <code class="literal">multi_array</code> manages its data elements
588using a replaceable allocator.
589</p><p title="Model Of."><b>Model Of.�</b>
590<a class="link" href="#MultiArray" title="MultiArray Concept">MultiArray</a>,
591<a class="ulink" href="../../../libs/utility/CopyConstructible.html" target="_top">CopyConstructible</a>. Depending on the element type,
592it may also model <a class="ulink" href="https://www.boost.org/sgi/stl/EqualityComparable.html" target="_top">EqualityComparable</a> and <a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a>.
593</p><p title="Synopsis"><b>Synopsis.�</b></p><pre class="programlisting">
594
595namespace boost {
596
597template &lt;typename ValueType,
598          std::size_t NumDims,
599          typename Allocator = std::allocator&lt;ValueType&gt; &gt;
600class multi_array {
601public:
602// types:
603  typedef ValueType                             element;
604  typedef *unspecified*                         value_type;
605  typedef *unspecified*                         reference;
606  typedef *unspecified*                         const_reference;
607  typedef *unspecified*                         difference_type;
608  typedef *unspecified*                         iterator;
609  typedef *unspecified*                         const_iterator;
610  typedef *unspecified*                         reverse_iterator;
611  typedef *unspecified*                         const_reverse_iterator;
612  typedef multi_array_types::size_type          size_type;
613  typedef multi_array_types::index              index;
614  typedef multi_array_types::index_gen          index_gen;
615  typedef multi_array_types::index_range        index_range;
616  typedef multi_array_types::extent_gen         extent_gen;
617  typedef multi_array_types::extent_range       extent_range;
618  typedef *unspecified*                         storage_order_type;
619
620
621  // template typedefs
622  template &lt;std::size_t Dims&gt; struct            subarray;
623  template &lt;std::size_t Dims&gt; struct            const_subarray;
624  template &lt;std::size_t Dims&gt; struct            array_view;
625  template &lt;std::size_t Dims&gt; struct            const_array_view;
626
627
628  static const std::size_t dimensionality = NumDims;
629
630
631  // constructors and destructors
632
633  multi_array();
634
635  template &lt;typename ExtentList&gt;
636  explicit multi_array(const ExtentList&amp; sizes,
637                       const storage_order_type&amp; store = c_storage_order(),
638                       const Allocator&amp; alloc = Allocator());
639  explicit multi_array(const extents_tuple&amp; ranges,
640                       const storage_order_type&amp; store = c_storage_order(),
641	               const Allocator&amp; alloc = Allocator());
642  multi_array(const multi_array&amp; x);
643  multi_array(const const_multi_array_ref&lt;ValueType,NumDims&gt;&amp; x);
644  multi_array(const const_subarray&lt;NumDims&gt;::type&amp; x);
645  multi_array(const const_array_view&lt;NumDims&gt;::type&amp; x);
646
647  multi_array(const multi_array_ref&lt;ValueType,NumDims&gt;&amp; x);
648  multi_array(const subarray&lt;NumDims&gt;::type&amp; x);
649  multi_array(const array_view&lt;NumDims&gt;::type&amp; x);
650
651  ~multi_array();
652
653  // modifiers
654
655  multi_array&amp; operator=(const multi_array&amp; x);
656  template &lt;class Array&gt; multi_array&amp; operator=(const Array&amp; x);
657
658  // iterators:
659  iterator				begin();
660  iterator				end();
661  const_iterator			begin() const;
662  const_iterator			end() const;
663  reverse_iterator			rbegin();
664  reverse_iterator			rend();
665  const_reverse_iterator		rbegin() const;
666  const_reverse_iterator		rend() const;
667
668  // capacity:
669  size_type				size() const;
670  size_type				num_elements() const;
671  size_type				num_dimensions() const;
672
673  // element access:
674  template &lt;typename IndexList&gt;
675    element&amp;			operator()(const IndexList&amp; indices);
676  template &lt;typename IndexList&gt;
677    const element&amp;		operator()(const IndexList&amp; indices) const;
678  reference			operator[](index i);
679  const_reference		operator[](index i) const;
680  array_view&lt;Dims&gt;::type	operator[](const indices_tuple&amp; r);
681  const_array_view&lt;Dims&gt;::type	operator[](const indices_tuple&amp; r) const;
682
683  // queries
684  element*			data();
685  const element*		data() const;
686  element*			origin();
687  const element*		origin() const;
688  const size_type*		shape() const;
689  const index*			strides() const;
690  const index*			index_bases() const;
691  const storage_order_type&amp;     storage_order() const;
692
693  // comparators
694  bool operator==(const multi_array&amp; rhs);
695  bool operator!=(const multi_array&amp; rhs);
696  bool operator&lt;(const multi_array&amp; rhs);
697  bool operator&gt;(const multi_array&amp; rhs);
698  bool operator&gt;=(const multi_array&amp; rhs);
699  bool operator&lt;=(const multi_array&amp; rhs);
700
701  // modifiers:
702  template &lt;typename InputIterator&gt;
703    void			assign(InputIterator begin, InputIterator end);
704  template &lt;typename SizeList&gt;
705    void			reshape(const SizeList&amp; sizes)
706  template &lt;typename BaseList&gt;	void reindex(const BaseList&amp; values);
707    void			reindex(index value);
708  template &lt;typename ExtentList&gt;
709    multi_array&amp;		resize(const ExtentList&amp; extents);
710  multi_array&amp;                  resize(extents_tuple&amp; extents);
711};
712
713</pre><p title="Constructors"><b>Constructors.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">template &lt;typename ExtentList&gt;
714explicit multi_array(const ExtentList&amp; sizes,
715                     const storage_order_type&amp; store = c_storage_order(),
716                     const Allocator&amp; alloc = Allocator());
717</pre></span></dt><dd><p>
718This constructs a <code class="literal">multi_array</code> using the specified
719parameters.  <code class="literal">sizes</code> specifies the shape of the
720constructed <code class="literal">multi_array</code>.  <code class="literal">store</code>
721specifies the storage order or layout in memory of the array
722dimensions.  <code class="literal">alloc</code> is used to
723allocate the contained elements.
724</p><p title="ExtentList Requirements"><b><code class="literal">ExtentList</code> Requirements.�</b>
725<code class="literal">ExtentList</code> must model <a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a>.
726</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">sizes.size() == NumDims;</code></p></dd><dt><span class="term">
727<pre class="programlisting">explicit multi_array(extent_gen::gen_type&lt;NumDims&gt;::type ranges,
728                     const storage_order_type&amp; store = c_storage_order(),
729                     const Allocator&amp; alloc = Allocator());
730</pre></span></dt><dd><p>
731This constructs a <code class="literal">multi_array</code> using the specified
732    parameters.  <code class="literal">ranges</code> specifies the shape and
733index bases of the constructed multi_array. It is the result of
734<code class="literal">NumDims</code> chained calls to
735    <code class="literal">extent_gen::operator[]</code>. <code class="literal">store</code>
736specifies the storage order or layout in memory of the array
737dimensions.  <code class="literal">alloc</code> is the allocator used to
738allocate the memory used to store <code class="literal">multi_array</code>
739elements.
740</p></dd><dt><span class="term"><pre class="programlisting">
741multi_array(const multi_array&amp; x);
742multi_array(const const_multi_array_ref&lt;ValueType,NumDims&gt;&amp; x);
743multi_array(const const_subarray&lt;NumDims&gt;::type&amp; x);
744multi_array(const const_array_view&lt;NumDims&gt;::type&amp; x);
745multi_array(const multi_array_ref&lt;ValueType,NumDims&gt;&amp; x);
746multi_array(const subarray&lt;NumDims&gt;::type&amp; x);
747multi_array(const array_view&lt;NumDims&gt;::type&amp; x);
748</pre></span></dt><dd><p>These constructors all constructs a <code class="literal">multi_array</code> and
749perform a deep copy of <code class="literal">x</code>.
750</p><p title="Complexity"><b>Complexity.�</b> This performs O(<code class="literal">x.num_elements()</code>) calls to
751<code class="literal">element</code>'s copy
752constructor.
753</p></dd><dt><span class="term"><pre class="programlisting">
754multi_array();
755</pre></span></dt><dd><p>This constructs a <code class="literal">multi_array</code> whose shape is (0,...,0) and contains no elements.
756</p></dd></dl></div><p title="Note on Constructors"><b>Note on Constructors.�</b>
757The  <code class="literal">multi_array</code> construction expressions,
758</p><pre class="programlisting">
759     multi_array&lt;int,3&gt; A(boost::extents[5][4][3]);
760</pre><p title="Note on Constructors">
761and
762</p><pre class="programlisting">
763     boost::array&lt;multi_array_base::index,3&gt; my_extents = {{5, 4, 3}};
764     multi_array&lt;int,3&gt; A(my_extents);
765</pre><p title="Note on Constructors">
766are equivalent.
767</p><p title="Modifiers"><b>Modifiers.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">
768multi_array&amp; operator=(const multi_array&amp; x);
769template &lt;class Array&gt; multi_array&amp; operator=(const Array&amp; x);
770</pre>
771</span></dt><dd><p>This performs an element-wise copy of <code class="literal">x</code>
772into the current <code class="literal">multi_array</code>.</p><p title="Array Requirements"><b><code class="literal">Array</code> Requirements.�</b><code class="literal">Array</code> must model MultiArray.
773</p><p title="Preconditions"><b>Preconditions.�</b>
774</p><pre class="programlisting">std::equal(this-&gt;shape(),this-&gt;shape()+this-&gt;num_dimensions(),
775x.shape());</pre><p title="Postconditions"><b>Postconditions.�</b>
776</p><pre class="programlisting">(*.this) == x;</pre><p title="Postconditions">
777</p><p title="Complexity"><b>Complexity.�</b>The assignment operators perform
778O(<code class="literal">x.num_elements()</code>) calls to <code class="literal">element</code>'s
779copy constructor.</p></dd><dt><span class="term">
780<pre class="programlisting">
781
782template &lt;typename InputIterator&gt;
783void assign(InputIterator begin, InputIterator end);
784</pre>
785</span></dt><dd><p>This copies the elements in the range
786<code class="literal">[begin,end)</code> into the array.  It is equivalent to
787<code class="literal">std::copy(begin,end,this-&gt;data())</code>.
788</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">std::distance(begin,end) == this-&gt;num_elements();</code>
789</p><p title="Complexity"><b>Complexity.�</b>
790The <code class="literal">assign</code> member function performs
791O(<code class="literal">this-&gt;num_elements()</code>) calls to
792<code class="literal">ValueType</code>'s copy constructor.
793</p></dd><dt><span class="term">
794<pre class="programlisting">multi_array&amp; resize(extent_gen::gen_type&lt;NumDims&gt;::type extents);
795template &lt;typename ExtentList&gt;
796  multi_array&amp; resize(const ExtentList&amp; extents);
797
798</pre></span></dt><dd><p>
799This function resizes an array to the shape specified by
800<code class="literal">extents</code>, which is either a generated list of
801extents or a model of the <code class="literal">Collection</code> concept. The
802contents of the array are preserved whenever possible; if the new
803array size is smaller, then some data will be lost. Any new elements
804created by resizing the array are initialized with the
805<code class="literal">element</code> default constructor.
806</p></dd></dl></div><p title="Queries"><b>Queries.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">
807storage_order_type&amp; storage_order() const;
808</pre>
809</span></dt><dd><p>This query returns the storage order object associated with the
810<code class="literal">multi_array</code> in question.  It can be used to construct a new array with the same storage order.</p></dd></dl></div></div><div class="sect2" title="multi_array_ref"><div class="titlepage"><div><div><h3 class="title"><a name="multi_array_ref"></a><code class="literal">multi_array_ref</code></h3></div></div></div><p>
811<code class="literal">multi_array_ref</code> is a multi-dimensional container
812adaptor.  It provides the MultiArray interface over any contiguous
813block of elements.  <code class="literal">multi_array_ref</code> exports the
814same interface as <code class="literal">multi_array</code>, with the exception
815of the constructors.
816</p><p title="Model Of."><b>Model Of.�</b>
817<code class="literal">multi_array_ref</code> models
818<a class="link" href="#MultiArray" title="MultiArray Concept">MultiArray</a>,
819<a class="ulink" href="../../../libs/utility/CopyConstructible.html" target="_top">CopyConstructible</a>.
820and depending on the element type, it may also model
821<a class="ulink" href="https://www.boost.org/sgi/stl/EqualityComparable.html" target="_top">EqualityComparable</a> and <a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a>.
822Detailed descriptions are provided here only for operations that are
823not described in the <code class="literal">multi_array</code> reference.
824</p><p title="Synopsis"><b>Synopsis.�</b></p><pre class="programlisting">
825
826namespace boost {
827
828template &lt;typename ValueType,
829          std::size_t NumDims&gt;
830class multi_array_ref {
831public:
832// types:
833  typedef ValueType                             element;
834  typedef *unspecified*                         value_type;
835  typedef *unspecified*                         reference;
836  typedef *unspecified*                         const_reference;
837  typedef *unspecified*                         difference_type;
838  typedef *unspecified*                         iterator;
839  typedef *unspecified*                         const_iterator;
840  typedef *unspecified*                         reverse_iterator;
841  typedef *unspecified*                         const_reverse_iterator;
842  typedef multi_array_types::size_type          size_type;
843  typedef multi_array_types::index              index;
844  typedef multi_array_types::index_gen          index_gen;
845  typedef multi_array_types::index_range        index_range;
846  typedef multi_array_types::extent_gen         extent_gen;
847  typedef multi_array_types::extent_range       extent_range;
848  typedef *unspecified*                         storage_order_type;
849
850  // template typedefs
851  template &lt;std::size_t Dims&gt; struct            subarray;
852  template &lt;std::size_t Dims&gt; struct            const_subarray;
853  template &lt;std::size_t Dims&gt; struct            array_view;
854  template &lt;std::size_t Dims&gt; struct            const_array_view;
855
856
857  static const std::size_t dimensionality = NumDims;
858
859
860  // constructors and destructors
861
862  template &lt;typename ExtentList&gt;
863  explicit multi_array_ref(element* data, const ExtentList&amp; sizes,
864                       const storage_order_type&amp; store = c_storage_order());
865  explicit multi_array_ref(element* data, const extents_tuple&amp; ranges,
866                       const storage_order_type&amp; store = c_storage_order());
867  multi_array_ref(const multi_array_ref&amp; x);
868  ~multi_array_ref();
869
870  // modifiers
871
872  multi_array_ref&amp; operator=(const multi_array_ref&amp; x);
873  template &lt;class Array&gt; multi_array_ref&amp; operator=(const Array&amp; x);
874
875  // iterators:
876  iterator				begin();
877  iterator				end();
878  const_iterator			begin() const;
879  const_iterator			end() const;
880  reverse_iterator			rbegin();
881  reverse_iterator			rend();
882  const_reverse_iterator		rbegin() const;
883  const_reverse_iterator		rend() const;
884
885  // capacity:
886  size_type				size() const;
887  size_type				num_elements() const;
888  size_type				num_dimensions() const;
889
890  // element access:
891  template &lt;typename IndexList&gt;
892    element&amp;			operator()(const IndexList&amp; indices);
893  template &lt;typename IndexList&gt;
894    const element&amp;		operator()(const IndexList&amp; indices) const;
895  reference			operator[](index i);
896  const_reference		operator[](index i) const;
897  array_view&lt;Dims&gt;::type	operator[](const indices_tuple&amp; r);
898  const_array_view&lt;Dims&gt;::type	operator[](const indices_tuple&amp; r) const;
899
900  // queries
901  element*			data();
902  const element*		data() const;
903  element*			origin();
904  const element*		origin() const;
905  const size_type*		shape() const;
906  const index*			strides() const;
907  const index*			index_bases() const;
908  const storage_order_type&amp;     storage_order() const;
909
910  // comparators
911  bool operator==(const multi_array_ref&amp; rhs);
912  bool operator!=(const multi_array_ref&amp; rhs);
913  bool operator&lt;(const multi_array_ref&amp; rhs);
914  bool operator&gt;(const multi_array_ref&amp; rhs);
915  bool operator&gt;=(const multi_array_ref&amp; rhs);
916  bool operator&lt;=(const multi_array_ref&amp; rhs);
917
918  // modifiers:
919  template &lt;typename InputIterator&gt;
920    void			assign(InputIterator begin, InputIterator end);
921  template &lt;typename SizeList&gt;
922    void			reshape(const SizeList&amp; sizes)
923  template &lt;typename BaseList&gt;	void reindex(const BaseList&amp; values);
924  void				reindex(index value);
925};
926
927</pre><p title="Constructors"><b>Constructors.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">template &lt;typename ExtentList&gt;
928explicit multi_array_ref(element* data,
929                     const ExtentList&amp; sizes,
930                     const storage_order&amp; store = c_storage_order(),
931                     const Allocator&amp; alloc = Allocator());
932</pre></span></dt><dd><p>
933This constructs a <code class="literal">multi_array_ref</code> using the specified
934parameters.  <code class="literal">sizes</code> specifies the shape of the
935constructed <code class="literal">multi_array_ref</code>.  <code class="literal">store</code>
936specifies the storage order or layout in memory of the array
937dimensions.  <code class="literal">alloc</code> is used to
938allocate the contained elements.
939</p><p title="ExtentList Requirements"><b><code class="literal">ExtentList</code> Requirements.�</b>
940<code class="literal">ExtentList</code> must model <a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a>.
941</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">sizes.size() == NumDims;</code></p></dd><dt><span class="term">
942<pre class="programlisting">explicit multi_array_ref(element* data,
943                     extent_gen::gen_type&lt;NumDims&gt;::type ranges,
944                     const storage_order&amp; store = c_storage_order());
945</pre></span></dt><dd><p>
946This constructs a <code class="literal">multi_array_ref</code> using the specified
947    parameters.  <code class="literal">ranges</code> specifies the shape and
948index bases of the constructed multi_array_ref. It is the result of
949<code class="literal">NumDims</code> chained calls to
950    <code class="literal">extent_gen::operator[]</code>. <code class="literal">store</code>
951specifies the storage order or layout in memory of the array
952dimensions.
953</p></dd><dt><span class="term"><pre class="programlisting">
954multi_array_ref(const multi_array_ref&amp; x);
955</pre></span></dt><dd><p>This constructs a shallow copy of <code class="literal">x</code>.
956</p><p title="Complexity"><b>Complexity.�</b> Constant time (for contrast, compare this to
957the <code class="literal">multi_array</code> class copy constructor.
958</p></dd></dl></div><p title="Modifiers"><b>Modifiers.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">
959multi_array_ref&amp; operator=(const multi_array_ref&amp; x);
960template &lt;class Array&gt; multi_array_ref&amp; operator=(const Array&amp; x);
961</pre>
962</span></dt><dd><p>This performs an element-wise copy of <code class="literal">x</code>
963into the current <code class="literal">multi_array_ref</code>.</p><p title="Array Requirements"><b><code class="literal">Array</code> Requirements.�</b><code class="literal">Array</code> must model MultiArray.
964</p><p title="Preconditions"><b>Preconditions.�</b>
965</p><pre class="programlisting">std::equal(this-&gt;shape(),this-&gt;shape()+this-&gt;num_dimensions(),
966x.shape());</pre><p title="Postconditions"><b>Postconditions.�</b>
967</p><pre class="programlisting">(*.this) == x;</pre><p title="Postconditions">
968</p><p title="Complexity"><b>Complexity.�</b>The assignment operators perform
969O(<code class="literal">x.num_elements()</code>) calls to <code class="literal">element</code>'s
970copy constructor.</p></dd></dl></div></div><div class="sect2" title="const_multi_array_ref"><div class="titlepage"><div><div><h3 class="title"><a name="const_multi_array_ref"></a><code class="literal">const_multi_array_ref</code></h3></div></div></div><p>
971<code class="literal">const_multi_array_ref</code> is a multi-dimensional container
972adaptor.  It provides the MultiArray interface over any contiguous
973block of elements.  <code class="literal">const_multi_array_ref</code> exports the
974same interface as <code class="literal">multi_array</code>, with the exception
975of the constructors.
976</p><p title="Model Of."><b>Model Of.�</b>
977<code class="literal">const_multi_array_ref</code> models
978<a class="link" href="#MultiArray" title="MultiArray Concept">MultiArray</a>,
979<a class="ulink" href="../../../libs/utility/CopyConstructible.html" target="_top">CopyConstructible</a>.
980and depending on the element type, it may also model
981<a class="ulink" href="https://www.boost.org/sgi/stl/EqualityComparable.html" target="_top">EqualityComparable</a> and <a class="ulink" href="https://www.boost.org/sgi/stl/LessThanComparable.html" target="_top">LessThanComparable</a>.
982
983Detailed descriptions are provided here only for operations that are
984not described in the <code class="literal">multi_array</code> reference.
985</p><p title="Synopsis"><b>Synopsis.�</b></p><pre class="programlisting">
986
987namespace boost {
988
989template &lt;typename ValueType,
990          std::size_t NumDims,
991          typename TPtr = const T*&gt;
992class const_multi_array_ref {
993public:
994// types:
995  typedef ValueType                             element;
996  typedef *unspecified*                         value_type;
997  typedef *unspecified*                         reference;
998  typedef *unspecified*                         const_reference;
999  typedef *unspecified*                         difference_type;
1000  typedef *unspecified*                         iterator;
1001  typedef *unspecified*                         const_iterator;
1002  typedef *unspecified*                         reverse_iterator;
1003  typedef *unspecified*                         const_reverse_iterator;
1004  typedef multi_array_types::size_type          size_type;
1005  typedef multi_array_types::index              index;
1006  typedef multi_array_types::index_gen          index_gen;
1007  typedef multi_array_types::index_range        index_range;
1008  typedef multi_array_types::extent_gen         extent_gen;
1009  typedef multi_array_types::extent_range       extent_range;
1010  typedef *unspecified*                         storage_order_type;
1011
1012  // template typedefs
1013  template &lt;std::size_t Dims&gt; struct            subarray;
1014  template &lt;std::size_t Dims&gt; struct            const_subarray;
1015  template &lt;std::size_t Dims&gt; struct            array_view;
1016  template &lt;std::size_t Dims&gt; struct            const_array_view;
1017
1018
1019  // structors
1020
1021  template &lt;typename ExtentList&gt;
1022  explicit const_multi_array_ref(TPtr data, const ExtentList&amp; sizes,
1023                       const storage_order_type&amp; store = c_storage_order());
1024  explicit const_multi_array_ref(TPtr data, const extents_tuple&amp; ranges,
1025                       const storage_order_type&amp; store = c_storage_order());
1026  const_multi_array_ref(const const_multi_array_ref&amp; x);
1027  ~const_multi_array_ref();
1028
1029
1030
1031  // iterators:
1032  const_iterator			begin() const;
1033  const_iterator			end() const;
1034  const_reverse_iterator		rbegin() const;
1035  const_reverse_iterator		rend() const;
1036
1037  // capacity:
1038  size_type				size() const;
1039  size_type				num_elements() const;
1040  size_type				num_dimensions() const;
1041
1042  // element access:
1043  template &lt;typename IndexList&gt;
1044    const element&amp;		operator()(const IndexList&amp; indices) const;
1045  const_reference		operator[](index i) const;
1046  const_array_view&lt;Dims&gt;::type	operator[](const indices_tuple&amp; r) const;
1047
1048  // queries
1049  const element*		data() const;
1050  const element*		origin() const;
1051  const size_type*		shape() const;
1052  const index*			strides() const;
1053  const index*			index_bases() const;
1054  const storage_order_type&amp;     storage_order() const;
1055
1056  // comparators
1057  bool operator==(const const_multi_array_ref&amp; rhs);
1058  bool operator!=(const const_multi_array_ref&amp; rhs);
1059  bool operator&lt;(const const_multi_array_ref&amp; rhs);
1060  bool operator&gt;(const const_multi_array_ref&amp; rhs);
1061  bool operator&gt;=(const const_multi_array_ref&amp; rhs);
1062  bool operator&lt;=(const const_multi_array_ref&amp; rhs);
1063
1064  // modifiers:
1065  template &lt;typename SizeList&gt;
1066  void			reshape(const SizeList&amp; sizes)
1067  template &lt;typename BaseList&gt;	void reindex(const BaseList&amp; values);
1068  void				reindex(index value);
1069};
1070
1071</pre><p title="Constructors"><b>Constructors.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">template &lt;typename ExtentList&gt;
1072explicit const_multi_array_ref(TPtr data,
1073                     const ExtentList&amp; sizes,
1074                     const storage_order&amp; store = c_storage_order());
1075</pre></span></dt><dd><p>
1076This constructs a <code class="literal">const_multi_array_ref</code> using the specified
1077parameters.  <code class="literal">sizes</code> specifies the shape of the
1078constructed <code class="literal">const_multi_array_ref</code>.  <code class="literal">store</code>
1079specifies the storage order or layout in memory of the array
1080dimensions.
1081</p><p title="ExtentList Requirements"><b><code class="literal">ExtentList</code> Requirements.�</b>
1082<code class="literal">ExtentList</code> must model <a class="ulink" href="../../utility/Collection.html" target="_top">Collection</a>.
1083</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">sizes.size() == NumDims;</code></p></dd><dt><span class="term">
1084<pre class="programlisting">explicit const_multi_array_ref(TPtr data,
1085                     extent_gen::gen_type&lt;NumDims&gt;::type ranges,
1086                     const storage_order&amp; store = c_storage_order());
1087</pre></span></dt><dd><p title="Effects"><b>Effects.�</b>
1088This constructs a <code class="literal">const_multi_array_ref</code> using the specified
1089    parameters.  <code class="literal">ranges</code> specifies the shape and
1090index bases of the constructed const_multi_array_ref. It is the result of
1091<code class="literal">NumDims</code> chained calls to
1092    <code class="literal">extent_gen::operator[]</code>. <code class="literal">store</code>
1093specifies the storage order or layout in memory of the array
1094dimensions.
1095</p></dd><dt><span class="term"><pre class="programlisting">
1096const_multi_array_ref(const const_multi_array_ref&amp; x);
1097</pre></span></dt><dd><p title="Effects"><b>Effects.�</b>This constructs a shallow copy of <code class="literal">x</code>.
1098</p></dd></dl></div></div></div><div class="sect1" title="Auxiliary Components"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="auxiliary"></a>Auxiliary Components</h2></div></div></div><div class="sect2" title="multi_array_types"><div class="titlepage"><div><div><h3 class="title"><a name="multi_array_types"></a><code class="literal">multi_array_types</code></h3></div></div></div><pre class="programlisting">
1099namespace multi_array_types {
1100  typedef *unspecified* index;
1101  typedef *unspecified* size_type;
1102  typedef *unspecified* difference_type;
1103  typedef *unspecified* index_range;
1104  typedef *unspecified* extent_range;
1105  typedef *unspecified* index_gen;
1106  typedef *unspecified* extent_gen;
1107}
1108</pre><p>Namespace <code class="literal">multi_array_types</code> defines types
1109associated with <code class="literal">multi_array</code>,
1110<code class="literal">multi_array_ref</code>, and
1111<code class="literal">const_multi_array_ref</code> that are not
1112dependent upon template parameters.  These types find common use with
1113all Boost.Multiarray components.  They are defined
1114in a namespace from which they can be accessed conveniently.
1115With the exception of <code class="literal">extent_gen</code> and
1116<code class="literal">extent_range</code>, these types fulfill the roles of the
1117same name required by MultiArray and are described in its
1118concept definition.  <code class="literal">extent_gen</code> and
1119<code class="literal">extent_range</code> are described below.
1120</p></div><div class="sect2" title="extent_range"><div class="titlepage"><div><div><h3 class="title"><a name="extent_range"></a><code class="classname">extent_range</code></h3></div></div></div><p><code class="classname">extent_range</code> objects define half open
1121intervals.  They provide shape and index base information to
1122<code class="literal">multi_array</code>, <code class="literal">multi_array_ref</code>,
1123 and <code class="literal">const_multi_array_ref</code> constructors.
1124<code class="classname">extent_range</code>s are passed in
1125aggregate to an array constructor (see
1126<code class="classname">extent_gen</code> for more details).
1127</p><p title="Synopsis"><b>Synopsis.�</b></p><pre class="programlisting">
1128class extent_range {
1129public:
1130  typedef multi_array_types::index      index;
1131  typedef multi_array_types::size_type  size_type;
1132
1133  // Structors
1134  extent_range(index start, index finish);
1135  extent_range(index finish);
1136  ~extent_range();
1137
1138  // Queries
1139  index start();
1140  index finish();
1141  size_type size();
1142};</pre><p title="Model Of"><b>Model Of.�</b>DefaultConstructible,CopyConstructible</p><p title="Methods and Types"><b>Methods and Types.�</b></p><div class="variablelist"><dl><dt><span class="term"><code class="function">extent_range(index start, index finish)</code></span></dt><dd><p>  This constructor defines the half open interval
1143<code class="literal">[start,finish)</code>. The expression
1144<code class="literal">finish</code> must be greater than <code class="literal">start</code>.
1145</p></dd><dt><span class="term"><code class="function">extent_range(index finish)</code></span></dt><dd><p>This constructor defines the half open interval
1146<code class="literal">[0,finish)</code>. The value of <code class="literal">finish</code>
1147must be positive.</p></dd><dt><span class="term"><code class="function">index start()</code></span></dt><dd><p>This function returns the first index represented by the range</p></dd><dt><span class="term"><code class="function">index finish()</code></span></dt><dd><p>This function returns the upper boundary value of the half-open
1148interval.  Note that the range does not include this value.</p></dd><dt><span class="term"><code class="function">size_type size()</code></span></dt><dd><p>This function returns the size of the specified range. It is
1149equivalent to <code class="literal">finish()-start()</code>.</p></dd></dl></div></div><div class="sect2" title="extent_gen"><div class="titlepage"><div><div><h3 class="title"><a name="extent_gen"></a><code class="classname">extent_gen</code></h3></div></div></div><p>The <code class="classname">extent_gen</code> class defines an
1150interface for aggregating array shape and indexing information to be
1151passed to a <code class="literal">multi_array</code>,
1152<code class="literal">multi_array_ref</code>, or <code class="literal">const_multi_array_ref</code>
1153constructor. Its interface mimics
1154 the syntax used to declare built-in array types
1155in C++. For example, while a 3-dimensional array of
1156<code class="classname">int</code> values in C++ would be
1157declared as:
1158</p><pre class="programlisting">int A[3][4][5],</pre><p>
1159a similar <code class="classname">multi_array</code> would be declared:
1160</p><pre class="programlisting">multi_array&lt;int,3&gt; A(extents[3][4][5]).</pre><p>
1161</p><p title="Synopsis"><b>Synopsis.�</b></p><pre class="programlisting">
1162template &lt;std::size_t NumRanges&gt;
1163class *implementation_defined* {
1164public:
1165  typedef multi_array_types::index index;
1166  typedef multi_array_types::size_type size_type;
1167
1168  template &lt;std::size_t NumRanges&gt; class gen_type;
1169
1170  gen_type&lt;NumRanges+1&gt;::type  operator[](const range&amp; a_range) const;
1171  gen_type&lt;NumRanges+1&gt;::type  operator[](index idx) const;
1172};
1173
1174typedef *implementation_defined*&lt;0&gt; extent_gen;
1175</pre><p title="Methods and Types"><b>Methods and Types.�</b></p><div class="variablelist"><dl><dt><span class="term"><code class="function">template gen_type&lt;Ranges&gt;::type</code></span></dt><dd><p>This type generator is used to specify the result of
1176<code class="literal">Ranges</code> chained calls to
1177<code class="literal">extent_gen::operator[].</code> The types
1178<code class="classname">extent_gen</code> and
1179<code class="classname">gen_type&lt;0&gt;::type</code> are the same.</p></dd><dt><span class="term"><code class="function">gen_type&lt;NumRanges+1&gt;::type
1180operator[](const extent_range&amp; a_range) const;</code></span></dt><dd><p>This function returns a new object containing all previous
1181<code class="classname">extent_range</code> objects in addition to
1182<code class="literal">a_range.</code> <code class="classname">extent_range</code>
1183objects are aggregated by chained calls to
1184<code class="function">operator[]</code>.</p></dd><dt><span class="term"><code class="function">gen_type&lt;NumRanges+1&gt;::type
1185operator[](index idx) const;</code></span></dt><dd><p>This function returns a new object containing all previous
1186<code class="classname">extent_range</code> objects in addition to
1187<code class="literal">extent_range(0,idx).</code> This function gives the array
1188constructors a similar syntax to traditional C multidimensional array
1189declaration.</p></dd></dl></div></div><div class="sect2" title="Global Objects"><div class="titlepage"><div><div><h3 class="title"><a name="idp19487120"></a>Global Objects</h3></div></div></div><p>For syntactic convenience, Boost.MultiArray defines two
1190global objects as part of its
1191interface.  These objects play the role of object generators;
1192expressions involving them create other objects of interest.
1193</p><p> Under some circumstances, the two global objects may be
1194considered excessive overhead.  Their construction can be prevented by
1195defining the preprocessor symbol
1196<code class="literal">BOOST_MULTI_ARRAY_NO_GENERATORS</code> before including
1197<code class="filename">boost/multi_array.hpp.</code></p><div class="sect3" title="extents"><div class="titlepage"><div><div><h4 class="title"><a name="extents"></a><code class="literal">extents</code></h4></div></div></div><pre class="programlisting">
1198namespace boost {
1199  multi_array_base::extent_gen extents;
1200}
1201</pre><p>Boost.MultiArray's array classes use the
1202<code class="literal">extents</code> global object to specify
1203array shape during their construction.
1204For example,
1205a 3 by 3 by 3 <code class="classname">multi_array</code> is constructed as follows:
1206</p><pre class="programlisting">multi_array&lt;int,3&gt; A(extents[3][3][3]);</pre><p>
1207The same array could also be created by explicitly declaring an <code class="literal">extent_gen</code>
1208object locally,, but the global object makes this declaration unnecessary.
1209</p></div><div class="sect3" title="indices"><div class="titlepage"><div><div><h4 class="title"><a name="indices"></a><code class="literal">indices</code></h4></div></div></div><pre class="programlisting">
1210namespace boost {
1211  multi_array_base::index_gen  indices;
1212}
1213</pre><p>The MultiArray concept specifies an
1214<code class="literal">index_gen</code> associated type that is used to
1215create views.
1216<code class="literal">indices</code> is a global object that serves the role of
1217<code class="literal">index_gen</code> for all array components provided by this
1218library and their associated subarrays and views.
1219</p><p>For example, using the <code class="literal">indices</code> object,
1220a view of an array <code class="literal">A</code> is constructed as follows:
1221</p><pre class="programlisting">
1222A[indices[index_range(0,5)][2][index_range(2,4)]];
1223</pre><p>
1224</p></div></div><div class="sect2" title="View and SubArray Generators"><div class="titlepage"><div><div><h3 class="title"><a name="generators"></a>View and SubArray Generators</h3></div></div></div><p>
1225Boost.MultiArray provides traits classes, <code class="literal">subarray_gen</code>,
1226<code class="literal">const_subarray_gen</code>,
1227<code class="literal">array_view_gen</code>,
1228and <code class="literal">const_array_view_gen</code>, for naming of
1229array associated types within function templates.
1230In general this is no more convenient to use than the nested
1231type generators, but the library author found that some C++ compilers do not
1232properly handle templates nested within function template parameter types.
1233These generators constitute a workaround for this deficit.
1234The following code snippet illustrates
1235the correspondence between the <code class="literal">array_view_gen</code>
1236traits class and the <code class="literal">array_view</code> type associated to
1237an array:
1238
1239</p><pre class="programlisting">
1240template &lt;typename Array&gt;
1241void my_function() {
1242  typedef typename Array::template array_view&lt;3&gt;::type view1_t;
1243  typedef typename boost::array_view_gen&lt;Array,3&gt;::type view2_t;
1244  // ...
1245}
1246</pre><p>
1247
1248In the above example, <code class="literal">view1_t</code> and
1249<code class="literal">view2_t</code> have the same type.
1250</p></div><div class="sect2" title="Memory Layout Specifiers"><div class="titlepage"><div><div><h3 class="title"><a name="memory_layout"></a>Memory Layout Specifiers</h3></div></div></div><p>
1251While a multidimensional array represents a hierarchy of containers of
1252elements, at some point the elements must be laid out in
1253memory.  As a result, a single multidimensional array
1254can be represented in memory more than one way.
1255</p><p>For example, consider the two dimensional array shown below in
1256matrix notation:
1257
1258</p><div><img src="matrix.gif"></div><p>
1259
1260Here is how the above array is expressed in C++:
1261</p><pre class="programlisting">
1262int a[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
1263</pre><p>
1264This is an example of row-major storage, where elements of each row
1265are stored contiguously.
1266
1267While C++ transparently handles accessing elements of an array, you
1268can also manage the array and its indexing manually.  One way that
1269this may be expressed in memory is as follows:
1270</p><pre class="programlisting">
1271int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
1272int s[] = { 4, 1 };
1273</pre><p>
1274
1275With the latter declaration of <code class="literal">a</code> and
1276strides <code class="literal">s</code>, element <code class="literal">a(i,j)</code>
1277of the array can be
1278accessed using the expression
1279</p><pre class="programlisting">*a+i*s[0]+j*s[1]</pre><p>.
1280</p><p>The same two dimensional array could be laid out by column as follows:
1281
1282</p><pre class="programlisting">
1283int a[] = { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11 };
1284int s[] = { 3, 1 };
1285</pre><p>
1286Notice that the strides here are different. As a result,
1287The expression given above to access values will work with this pair
1288of data and strides as well.
1289</p><p>In addition to dimension order, it is also possible to
1290store any dimension in descending order. For example, returning to the
1291first example, the first dimension of the example array, the
1292rows,  could be stored in
1293reverse, resulting in the following:
1294
1295</p><pre class="programlisting">
1296int data[] = { 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 };
1297int *a = data + 8;
1298int s[] = { -4, 1 };
1299</pre><p>
1300
1301Note that in this example <code class="literal">a</code> must be explicitly set
1302to the origin. In the previous examples, the
1303first element stored in memory was the origin; here this is no longer
1304the case.
1305</p><p>
1306Alternatively, the second dimension, or the columns, could be reversed
1307and the rows stored in ascending order:
1308
1309</p><pre class="programlisting">
1310int data[] = { 3, 2, 1, 0,  7, 6, 5, 4, 11, 10, 9, 8 };
1311int *a = data + 3;
1312int s[] = { 4, -1 };
1313</pre><p>
1314</p><p>
1315Finally, both dimensions could be stored in descending order:
1316
1317</p><pre class="programlisting">
1318int data[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
1319int *a = data + 11;
1320int s[] = { -4, -1 };
1321</pre><p>
1322<code class="literal">
1323</code>
1324</p><p>
1325All of the above arrays are equivalent. The expression
1326given above for <code class="literal">a(i,j)</code> will yield the same value
1327regardless of the memory layout.
1328
1329Boost.MultiArray arrays can be created with customized storage
1330parameters as described above. Thus, existing data can be adapted
1331(with <code class="literal">multi_array_ref</code> or
1332<code class="literal">const_multi_array_ref</code>) as suited to the array
1333abstraction.  A common usage of this feature would be to wrap arrays
1334that must interoperate with Fortran routines so they can be
1335manipulated naturally at both the C++ and Fortran levels. The
1336following sections describe the Boost.MultiArray components used to
1337specify memory layout.
1338</p><div class="sect3" title="c_storage_order"><div class="titlepage"><div><div><h4 class="title"><a name="c_storage_order"></a><code class="literal">c_storage_order</code></h4></div></div></div><pre class="programlisting">
1339class c_storage_order {
1340  c_storage_order();
1341};
1342</pre><p><code class="literal">c_storage_order</code> is used to specify that an
1343array should store its elements using the same layout as that used by
1344primitive C++ multidimensional arrays, that is, from last dimension
1345to first. This is the default storage order for the arrays provided by
1346this library.</p></div><div class="sect3" title="fortran_storage_order"><div class="titlepage"><div><div><h4 class="title"><a name="fortran_storage_order"></a><code class="literal">fortran_storage_order</code></h4></div></div></div><pre class="programlisting">
1347class fortran_storage_order {
1348  fortran_storage_order();
1349};
1350</pre><p><code class="literal">fortran_storage_order</code> is used to specify that
1351an array should store its elements using the same memory layout as a
1352Fortran multidimensional array would, that is, from first dimension to
1353last.</p></div><div class="sect3" title="general_storage_order"><div class="titlepage"><div><div><h4 class="title"><a name="general_storage_order"></a><code class="literal">general_storage_order</code></h4></div></div></div><pre class="programlisting">
1354template &lt;std::size_t NumDims&gt;
1355class general_storage_order {
1356
1357  template &lt;typename OrderingIter, typename AscendingIter&gt;
1358  general_storage_order(OrderingIter ordering, AscendingIter ascending);
1359};
1360</pre><p><code class="literal">general_storage_order</code> allows the user to
1361specify an arbitrary memory layout for the contents of an array.  The
1362constructed object is passed to the array constructor in order to
1363specify storage order.</p><p>
1364<code class="literal">OrderingIter</code> and <code class="literal">AscendingIter</code>
1365must model the <code class="literal">InputIterator</code> concept.  Both
1366iterators must refer to a range of <code class="literal">NumDims</code>
1367elements.  <code class="literal">AscendingIter</code> points to objects
1368convertible to <code class="literal">bool</code>.  A value of
1369<code class="literal">true</code> means that a dimension is stored in ascending
1370order while <code class="literal">false</code> means that a dimension is stored
1371in descending order.  <code class="literal">OrderingIter</code> specifies the
1372order in which dimensions are stored.
1373</p></div></div><div class="sect2" title="Range Checking"><div class="titlepage"><div><div><h3 class="title"><a name="range_checking"></a>Range Checking</h3></div></div></div><p>
1374By default, the array access methods <code class="literal">operator()</code> and
1375<code class="literal">operator[]</code> perform range
1376checking.  If a supplied index is out of the range defined for an
1377array, an assertion will abort the program.  To disable range
1378checking (for performance reasons in production releases), define
1379the <code class="literal">BOOST_DISABLE_ASSERTS</code> preprocessor macro prior to
1380including multi_array.hpp in an application.
1381</p></div></div></div></body></html>
1382