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 <typename ValueType, 30 std::size_t NumDims, 31 typename Allocator = std::allocator<ValueType> > 32 class multi_array; 33 34 template <typename ValueType, 35 std::size_t NumDims> 36 class multi_array_ref; 37 38 template <typename ValueType, 39 std::size_t NumDims> 40 class const_multi_array_ref; 41 42 multi_array_types::extent_gen extents; 43 multi_array_types::index_gen indices; 44 45 template <typename Array, int N> class subarray_gen; 46 template <typename Array, int N> class const_subarray_gen; 47 template <typename Array, int N> class array_view_gen; 48 template <typename Array, int N> class const_array_view_gen; 49 50 class c_storage_order; 51 class fortran_storage_order; 52 template <std::size_t NumDims> 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"><boost/multi_array/concept_checks.hpp></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<Dims<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<index,NumDims></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&</code>. Otherwise, this is the same type as 179<code class="literal">template subarray<NumDims-1>::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&</code>. Otherwise, this is the same 186type as 187<code class="literal">template const_subarray<NumDims-1>::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<iterator>::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<1>::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<Dims>::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<Dims>::type</code> object. 249</td></tr><tr><td> 250<code class="literal">template subarray<Dims>::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<Dims>::type</code> 258</td><td> 259This is the const subarray type. 260</td></tr><tr><td> 261<code class="literal">template array_view<Dims>::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<Dims>::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<size_type>()); 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&</code>; if <code class="literal">a</code> is mutable, 303<code class="literal">const element&</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<index>()), 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<Dims>::type</code> if 348<code class="literal">a</code> is mutable, 349<code class="literal">const_array_view<Dims>::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 < 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 <= 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 > 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 >= 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 <= index_range() < 10;</pre><p> or 410</p><pre class="programlisting">4 < index_range() <= 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&</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&</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&</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 < 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 <= 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 < 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 <= 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<Dims,Ranges>::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::<Dims,Ranges>::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<0,0>::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<0,0>::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<Dims+1,Ranges+1>::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<Dims,Ranges+1>::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<Dims+1,Ranges+1>::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<Dims>::type</code></li><li class="listitem"><code class="literal">template const_array_view<Dims>::type</code></li><li class="listitem"><code class="literal">template subarray<Dims>::type</code></li><li class="listitem"><code class="literal">template const_subarray<Dims>::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*& rhs); 529bool operator!=(const *array-type*& rhs); 530bool operator<(const *array-type*& rhs); 531bool operator>(const *array-type*& rhs); 532bool operator>=(const *array-type*& rhs); 533bool operator<=(const *array-type*& 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 <typename SizeList> 542void reshape(const SizeList& 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<size_type>()) == this->num_elements(); 552sizes.size() == NumDims; 553</pre><p title="Postconditions"><b>Postconditions.�</b> 554<code class="literal">std::equal(sizes.begin(),sizes.end(),this->shape) == true;</code> 555</p></dd><dt><span class="term"> 556<pre class="programlisting"> 557 558template <typename BaseList> 559void reindex(const BaseList& 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->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->index_bases(),this->index_bases()+this->num_dimensions(), 576 std::bind_2nd(std::equal_to<index>(),value)) == 577 this->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 <typename ValueType, 598 std::size_t NumDims, 599 typename Allocator = std::allocator<ValueType> > 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 <std::size_t Dims> struct subarray; 623 template <std::size_t Dims> struct const_subarray; 624 template <std::size_t Dims> struct array_view; 625 template <std::size_t Dims> 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 <typename ExtentList> 636 explicit multi_array(const ExtentList& sizes, 637 const storage_order_type& store = c_storage_order(), 638 const Allocator& alloc = Allocator()); 639 explicit multi_array(const extents_tuple& ranges, 640 const storage_order_type& store = c_storage_order(), 641 const Allocator& alloc = Allocator()); 642 multi_array(const multi_array& x); 643 multi_array(const const_multi_array_ref<ValueType,NumDims>& x); 644 multi_array(const const_subarray<NumDims>::type& x); 645 multi_array(const const_array_view<NumDims>::type& x); 646 647 multi_array(const multi_array_ref<ValueType,NumDims>& x); 648 multi_array(const subarray<NumDims>::type& x); 649 multi_array(const array_view<NumDims>::type& x); 650 651 ~multi_array(); 652 653 // modifiers 654 655 multi_array& operator=(const multi_array& x); 656 template <class Array> multi_array& operator=(const Array& 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 <typename IndexList> 675 element& operator()(const IndexList& indices); 676 template <typename IndexList> 677 const element& operator()(const IndexList& indices) const; 678 reference operator[](index i); 679 const_reference operator[](index i) const; 680 array_view<Dims>::type operator[](const indices_tuple& r); 681 const_array_view<Dims>::type operator[](const indices_tuple& 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& storage_order() const; 692 693 // comparators 694 bool operator==(const multi_array& rhs); 695 bool operator!=(const multi_array& rhs); 696 bool operator<(const multi_array& rhs); 697 bool operator>(const multi_array& rhs); 698 bool operator>=(const multi_array& rhs); 699 bool operator<=(const multi_array& rhs); 700 701 // modifiers: 702 template <typename InputIterator> 703 void assign(InputIterator begin, InputIterator end); 704 template <typename SizeList> 705 void reshape(const SizeList& sizes) 706 template <typename BaseList> void reindex(const BaseList& values); 707 void reindex(index value); 708 template <typename ExtentList> 709 multi_array& resize(const ExtentList& extents); 710 multi_array& resize(extents_tuple& extents); 711}; 712 713</pre><p title="Constructors"><b>Constructors.�</b></p><div class="variablelist"><dl><dt><span class="term"><pre class="programlisting">template <typename ExtentList> 714explicit multi_array(const ExtentList& sizes, 715 const storage_order_type& store = c_storage_order(), 716 const Allocator& 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<NumDims>::type ranges, 728 const storage_order_type& store = c_storage_order(), 729 const Allocator& 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& x); 742multi_array(const const_multi_array_ref<ValueType,NumDims>& x); 743multi_array(const const_subarray<NumDims>::type& x); 744multi_array(const const_array_view<NumDims>::type& x); 745multi_array(const multi_array_ref<ValueType,NumDims>& x); 746multi_array(const subarray<NumDims>::type& x); 747multi_array(const array_view<NumDims>::type& 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<int,3> A(boost::extents[5][4][3]); 760</pre><p title="Note on Constructors"> 761and 762</p><pre class="programlisting"> 763 boost::array<multi_array_base::index,3> my_extents = {{5, 4, 3}}; 764 multi_array<int,3> 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& operator=(const multi_array& x); 769template <class Array> multi_array& operator=(const Array& 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->shape(),this->shape()+this->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 <typename InputIterator> 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->data())</code>. 788</p><p title="Preconditions"><b>Preconditions.�</b><code class="literal">std::distance(begin,end) == this->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->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& resize(extent_gen::gen_type<NumDims>::type extents); 795template <typename ExtentList> 796 multi_array& resize(const ExtentList& 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& 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 <typename ValueType, 829 std::size_t NumDims> 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 <std::size_t Dims> struct subarray; 852 template <std::size_t Dims> struct const_subarray; 853 template <std::size_t Dims> struct array_view; 854 template <std::size_t Dims> struct const_array_view; 855 856 857 static const std::size_t dimensionality = NumDims; 858 859 860 // constructors and destructors 861 862 template <typename ExtentList> 863 explicit multi_array_ref(element* data, const ExtentList& sizes, 864 const storage_order_type& store = c_storage_order()); 865 explicit multi_array_ref(element* data, const extents_tuple& ranges, 866 const storage_order_type& store = c_storage_order()); 867 multi_array_ref(const multi_array_ref& x); 868 ~multi_array_ref(); 869 870 // modifiers 871 872 multi_array_ref& operator=(const multi_array_ref& x); 873 template <class Array> multi_array_ref& operator=(const Array& 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 <typename IndexList> 892 element& operator()(const IndexList& indices); 893 template <typename IndexList> 894 const element& operator()(const IndexList& indices) const; 895 reference operator[](index i); 896 const_reference operator[](index i) const; 897 array_view<Dims>::type operator[](const indices_tuple& r); 898 const_array_view<Dims>::type operator[](const indices_tuple& 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& storage_order() const; 909 910 // comparators 911 bool operator==(const multi_array_ref& rhs); 912 bool operator!=(const multi_array_ref& rhs); 913 bool operator<(const multi_array_ref& rhs); 914 bool operator>(const multi_array_ref& rhs); 915 bool operator>=(const multi_array_ref& rhs); 916 bool operator<=(const multi_array_ref& rhs); 917 918 // modifiers: 919 template <typename InputIterator> 920 void assign(InputIterator begin, InputIterator end); 921 template <typename SizeList> 922 void reshape(const SizeList& sizes) 923 template <typename BaseList> void reindex(const BaseList& 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 <typename ExtentList> 928explicit multi_array_ref(element* data, 929 const ExtentList& sizes, 930 const storage_order& store = c_storage_order(), 931 const Allocator& 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<NumDims>::type ranges, 944 const storage_order& 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& 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& operator=(const multi_array_ref& x); 960template <class Array> multi_array_ref& operator=(const Array& 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->shape(),this->shape()+this->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 <typename ValueType, 990 std::size_t NumDims, 991 typename TPtr = const T*> 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 <std::size_t Dims> struct subarray; 1014 template <std::size_t Dims> struct const_subarray; 1015 template <std::size_t Dims> struct array_view; 1016 template <std::size_t Dims> struct const_array_view; 1017 1018 1019 // structors 1020 1021 template <typename ExtentList> 1022 explicit const_multi_array_ref(TPtr data, const ExtentList& sizes, 1023 const storage_order_type& store = c_storage_order()); 1024 explicit const_multi_array_ref(TPtr data, const extents_tuple& ranges, 1025 const storage_order_type& store = c_storage_order()); 1026 const_multi_array_ref(const const_multi_array_ref& 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 <typename IndexList> 1044 const element& operator()(const IndexList& indices) const; 1045 const_reference operator[](index i) const; 1046 const_array_view<Dims>::type operator[](const indices_tuple& 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& storage_order() const; 1055 1056 // comparators 1057 bool operator==(const const_multi_array_ref& rhs); 1058 bool operator!=(const const_multi_array_ref& rhs); 1059 bool operator<(const const_multi_array_ref& rhs); 1060 bool operator>(const const_multi_array_ref& rhs); 1061 bool operator>=(const const_multi_array_ref& rhs); 1062 bool operator<=(const const_multi_array_ref& rhs); 1063 1064 // modifiers: 1065 template <typename SizeList> 1066 void reshape(const SizeList& sizes) 1067 template <typename BaseList> void reindex(const BaseList& 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 <typename ExtentList> 1072explicit const_multi_array_ref(TPtr data, 1073 const ExtentList& sizes, 1074 const storage_order& 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<NumDims>::type ranges, 1086 const storage_order& 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& 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<int,3> A(extents[3][4][5]).</pre><p> 1161</p><p title="Synopsis"><b>Synopsis.�</b></p><pre class="programlisting"> 1162template <std::size_t NumRanges> 1163class *implementation_defined* { 1164public: 1165 typedef multi_array_types::index index; 1166 typedef multi_array_types::size_type size_type; 1167 1168 template <std::size_t NumRanges> class gen_type; 1169 1170 gen_type<NumRanges+1>::type operator[](const range& a_range) const; 1171 gen_type<NumRanges+1>::type operator[](index idx) const; 1172}; 1173 1174typedef *implementation_defined*<0> 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<Ranges>::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<0>::type</code> are the same.</p></dd><dt><span class="term"><code class="function">gen_type<NumRanges+1>::type 1180operator[](const extent_range& 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<NumRanges+1>::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<int,3> 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 <typename Array> 1241void my_function() { 1242 typedef typename Array::template array_view<3>::type view1_t; 1243 typedef typename boost::array_view_gen<Array,3>::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 <std::size_t NumDims> 1355class general_storage_order { 1356 1357 template <typename OrderingIter, typename AscendingIter> 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