]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multi_array/doc/xml/reference.xml
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / multi_array / doc / xml / reference.xml
1 <?xml version='1.0' encoding="ISO-Latin-1" ?>
2 <!DOCTYPE article
3 PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
4 "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" [
5 <!ENTITY concepts SYSTEM "MultiArray.xml">
6 <!ENTITY multi_array SYSTEM "multi_array.xml">
7 <!ENTITY multi_array_ref SYSTEM "multi_array_ref.xml">
8 <!ENTITY const_multi_array_ref SYSTEM "const_multi_array_ref.xml">
9 ]>
10
11 <article>
12 <articleinfo>
13 <title>Boost.MultiArray Reference Manual</title>
14 <author>
15 <surname>Garcia</surname><firstname>Ronald</firstname>
16 <affiliation>
17 <orgname>Indiana University</orgname>
18 <orgdiv>Open Systems Lab</orgdiv>
19 </affiliation>
20 </author>
21 <orgname>BOOST</orgname>
22 <copyright>
23 <year>2002</year>
24 <holder>The Trustees of Indiana University</holder>
25 </copyright>
26 </articleinfo>
27
28
29 <para>Boost.MultiArray is composed of several components.
30 The MultiArray concept defines a generic interface to multidimensional
31 containers.
32 <literal>multi_array</literal> is a general purpose container class
33 that models MultiArray. <literal>multi_array_ref</literal>
34 and <literal>const_multi_array_ref</literal> are adapter
35 classes. Using them,
36 you can manipulate any block of contiguous data as though it were a
37 <literal>multi_array</literal>.
38 <literal>const_multi_array_ref</literal> differs from
39 <literal>multi_array_ref</literal> in that its elements cannot
40 be modified through its interface. Finally, several auxiliary classes are used
41 to create and specialize arrays and some global objects are defined as
42 part of the library interface.</para>
43
44 <sect1 id="synopsis">
45 <title>Library Synopsis</title>
46 <para>To use Boost.MultiArray, you must include the header
47 <filename>boost/multi_array.hpp</filename> in your source. This file
48 brings the following declarations into scope:</para>
49 <programlisting>
50 <![CDATA[namespace boost {
51
52 namespace multi_array_types {
53 typedef *unspecified* index;
54 typedef *unspecified* size_type;
55 typedef *unspecified* difference_type;
56 typedef *unspecified* index_range;
57 typedef *unspecified* extent_range;
58 typedef *unspecified* index_gen;
59 typedef *unspecified* extent_gen;
60 }
61
62 template <typename ValueType,
63 std::size_t NumDims,
64 typename Allocator = std::allocator<ValueType> >
65 class multi_array;
66
67 template <typename ValueType,
68 std::size_t NumDims>
69 class multi_array_ref;
70
71 template <typename ValueType,
72 std::size_t NumDims>
73 class const_multi_array_ref;
74
75 multi_array_types::extent_gen extents;
76 multi_array_types::index_gen indices;
77
78 template <typename Array, int N> class subarray_gen;
79 template <typename Array, int N> class const_subarray_gen;
80 template <typename Array, int N> class array_view_gen;
81 template <typename Array, int N> class const_array_view_gen;
82
83 class c_storage_order;
84 class fortran_storage_order;
85 template <std::size_t NumDims> class general_storage_order;
86
87 }]]>
88 </programlisting>
89 </sect1>
90
91 &concepts;
92
93 <sect1 id="array_types">
94 <title>Array Components</title>
95 <para>
96 Boost.MultiArray defines an array class,
97 <literal>multi_array</literal>, and two adapter classes,
98 <literal>multi_array_ref</literal> and
99 <literal>const_multi_array_ref</literal>. The three classes model
100 MultiArray and so they share a lot of functionality.
101 <literal>multi_array_ref</literal> differs from
102 <literal>multi_array</literal> in that the
103 <literal>multi_array</literal> manages its own memory, while
104 <literal>multi_array_ref</literal> is passed a block of memory that it
105 expects to be externally managed.
106 <literal>const_multi_array_ref</literal> differs from
107 <literal>multi_array_ref</literal> in that the underlying elements it
108 adapts cannot be modified through its interface, though some array
109 properties, including the array shape and index bases, can be altered.
110 Functionality the classes have in common is described
111 below.
112 </para>
113
114 <formalpara>
115 <title>Note: Preconditions, Effects, and Implementation</title>
116 <para>
117 Throughout the following sections, small pieces of C++ code are
118 used to specify constraints such as preconditions, effects, and
119 postconditions. These do not necessarily describe the underlying
120 implementation of array components; rather, they describe the
121 expected input to and
122 behavior of the specified operations. Failure to meet
123 preconditions results in undefined behavior. Not all effects
124 (i.e. copy constructors, etc.) must be mimicked exactly. The code
125 snippets for effects intend to capture the essence of the described
126 operation.
127 </para>
128 </formalpara>
129
130 <formalpara>
131 <title>Queries</title>
132
133 <variablelist>
134 <varlistentry>
135 <term><programlisting>element* data();
136 const element* data() const;</programlisting></term>
137 <listitem>
138 <para>This returns a pointer to the beginning of the
139 contiguous block that contains the array's data. If all dimensions of
140 the array are 0-indexed and stored in ascending order, this is
141 equivalent to <literal>origin()</literal>. Note that
142 <literal>const_multi_array_ref</literal> only provides the const
143 version of this function.
144 </para>
145 </listitem>
146 </varlistentry>
147
148 <varlistentry>
149 <term><programlisting>element* origin();
150 const element* origin() const;</programlisting></term>
151 <listitem>
152 <para>This returns the origin element of the
153 <literal>multi_array</literal>. Note that
154 <literal>const_multi_array_ref</literal> only provides the const
155 version of this function. (Required by MultiArray)
156 </para>
157 </listitem>
158 </varlistentry>
159
160 <varlistentry>
161 <term><function>const index* index_bases();</function></term>
162 <listitem>
163 <para>This returns the index bases for the
164 <literal>multi_array</literal>. (Required by MultiArray)
165 </para>
166 </listitem>
167 </varlistentry>
168
169 <varlistentry>
170 <term><function>const index* strides();</function></term>
171 <listitem>
172 <para>This returns the strides for the
173 <literal>multi_array</literal>. (Required by MultiArray)
174 </para>
175 </listitem>
176 </varlistentry>
177
178 <varlistentry>
179 <term><function>const size_type* shape();</function></term>
180 <listitem>
181 <para>This returns the shape of the
182 <literal>multi_array</literal>. (Required by MultiArray)
183 </para>
184 </listitem>
185 </varlistentry>
186 </variablelist>
187
188 </formalpara>
189
190 <formalpara>
191 <title>Comparators</title>
192 <variablelist>
193 <varlistentry>
194 <term><programlisting><![CDATA[
195 bool operator==(const *array-type*& rhs);
196 bool operator!=(const *array-type*& rhs);
197 bool operator<(const *array-type*& rhs);
198 bool operator>(const *array-type*& rhs);
199 bool operator>=(const *array-type*& rhs);
200 bool operator<=(const *array-type*& rhs);]]></programlisting></term>
201
202 <listitem>
203 <para>Each comparator executes a lexicographical compare over
204 the value types of the two arrays.
205 (Required by MultiArray)
206 </para>
207 <formalpara>
208 <title>Preconditions</title>
209 <para><literal>element</literal> must support the
210 comparator corresponding to that called on
211 <literal>multi_array</literal>.</para>
212 </formalpara>
213
214 <formalpara>
215 <title>Complexity</title>
216 <para>O(<literal>num_elements()</literal>).</para>
217 </formalpara>
218
219 </listitem>
220 </varlistentry>
221
222 </variablelist>
223 </formalpara>
224
225 <formalpara>
226 <title>Modifiers</title>
227
228 <variablelist>
229
230 <varlistentry>
231 <term>
232 <programlisting>
233 <![CDATA[
234 template <typename SizeList>
235 void reshape(const SizeList& sizes)
236 ]]>
237 </programlisting>
238 </term>
239
240 <listitem>
241 <para>This changes the shape of the <literal>multi_array</literal>. The
242 number of elements and the index bases remain the same, but the number
243 of values at each level of the nested container hierarchy may
244 change.</para>
245
246 <formalpara><title><literal>SizeList</literal> Requirements</title>
247 <para><literal>SizeList</literal> must model
248 <ulink url="../../utility/Collection.html">Collection</ulink>.</para>
249 </formalpara>
250
251 <formalpara><title>Preconditions</title>
252 <para>
253 <programlisting>
254 <![CDATA[std::accumulate(sizes.begin(),sizes.end(),size_type(1),std::times<size_type>()) == this->num_elements();
255 sizes.size() == NumDims;]]>
256 </programlisting></para>
257 </formalpara>
258
259
260 <formalpara><title>Postconditions</title>
261 <para>
262 <literal>std::equal(sizes.begin(),sizes.end(),this->shape) == true;</literal>
263 </para>
264 </formalpara>
265 </listitem>
266 </varlistentry>
267
268 <varlistentry>
269 <term>
270 <programlisting>
271 <![CDATA[
272 template <typename BaseList>
273 void reindex(const BaseList& values);
274 ]]>
275 </programlisting>
276 </term>
277 <listitem>
278 <para>This changes the index bases of the <literal>multi_array</literal> to
279 correspond to the the values in <literal>values</literal>.</para>
280
281 <formalpara>
282 <title><literal>BaseList</literal> Requirements</title>
283 <para><literal>BaseList</literal> must model
284 <ulink url="../../utility/Collection.html">Collection</ulink>.</para>
285 </formalpara>
286
287 <formalpara>
288 <title>Preconditions</title>
289 <para><literal>values.size() == NumDims;</literal></para>
290 </formalpara>
291
292
293 <formalpara>
294 <title>Postconditions</title>
295 <para><literal>std::equal(values.begin(),values.end(),this->index_bases());
296 </literal></para>
297 </formalpara>
298 </listitem>
299 </varlistentry>
300
301 <varlistentry>
302 <term>
303 <programlisting>
304 <![CDATA[
305 void reindex(index value);
306 ]]>
307 </programlisting>
308 </term>
309 <listitem>
310 <para>This changes the index bases of all dimensions of the
311 <literal>multi_array</literal> to <literal>value</literal>.</para>
312
313 <formalpara>
314 <title>Postconditions</title>
315 <para>
316 <programlisting>
317 <![CDATA[
318 std::count_if(this->index_bases(),this->index_bases()+this->num_dimensions(),
319 std::bind_2nd(std::equal_to<index>(),value)) ==
320 this->num_dimensions();
321 ]]>
322 </programlisting>
323 </para>
324 </formalpara>
325 </listitem>
326 </varlistentry>
327
328 </variablelist>
329 </formalpara>
330
331 &multi_array;
332 &multi_array_ref;
333 &const_multi_array_ref;
334
335 </sect1>
336
337
338 <sect1 id="auxiliary">
339 <title>Auxiliary Components</title>
340
341 <sect2 id="multi_array_types">
342 <title><literal>multi_array_types</literal></title>
343
344 <programlisting>
345 <![CDATA[namespace multi_array_types {
346 typedef *unspecified* index;
347 typedef *unspecified* size_type;
348 typedef *unspecified* difference_type;
349 typedef *unspecified* index_range;
350 typedef *unspecified* extent_range;
351 typedef *unspecified* index_gen;
352 typedef *unspecified* extent_gen;
353 }]]>
354 </programlisting>
355
356 <para>Namespace <literal>multi_array_types</literal> defines types
357 associated with <literal>multi_array</literal>,
358 <literal>multi_array_ref</literal>, and
359 <literal>const_multi_array_ref</literal> that are not
360 dependent upon template parameters. These types find common use with
361 all Boost.Multiarray components. They are defined
362 in a namespace from which they can be accessed conveniently.
363 With the exception of <literal>extent_gen</literal> and
364 <literal>extent_range</literal>, these types fulfill the roles of the
365 same name required by MultiArray and are described in its
366 concept definition. <literal>extent_gen</literal> and
367 <literal>extent_range</literal> are described below.
368 </para>
369 </sect2>
370
371
372 <sect2 id="extent_range">
373 <title><classname>extent_range</classname></title>
374
375 <para><classname>extent_range</classname> objects define half open
376 intervals. They provide shape and index base information to
377 <literal>multi_array</literal>, <literal>multi_array_ref</literal>,
378 and <literal>const_multi_array_ref</literal> constructors.
379 <classname>extent_range</classname>s are passed in
380 aggregate to an array constructor (see
381 <classname>extent_gen</classname> for more details).
382 </para>
383
384 <formalpara>
385 <title>Synopsis</title>
386 <programlisting><![CDATA[
387 class extent_range {
388 public:
389 typedef multi_array_types::index index;
390 typedef multi_array_types::size_type size_type;
391
392 // Structors
393 extent_range(index start, index finish);
394 extent_range(index finish);
395 ~extent_range();
396
397 // Queries
398 index start();
399 index finish();
400 size_type size();
401 };]]></programlisting>
402 </formalpara>
403
404 <formalpara>
405 <title>Model Of</title>
406 <para>DefaultConstructible,CopyConstructible</para>
407 </formalpara>
408
409 <formalpara><title>Methods and Types</title>
410 <variablelist>
411 <varlistentry>
412 <term><function>extent_range(index start, index finish)</function></term>
413 <listitem>
414 <para> This constructor defines the half open interval
415 <literal>[start,finish)</literal>. The expression
416 <literal>finish</literal> must be greater than <literal>start</literal>.
417 </para>
418 </listitem>
419 </varlistentry>
420
421 <varlistentry><term><function>extent_range(index finish)</function></term>
422 <listitem>
423 <para>This constructor defines the half open interval
424 <literal>[0,finish)</literal>. The value of <literal>finish</literal>
425 must be positive.</para>
426 </listitem>
427 </varlistentry>
428
429 <varlistentry><term><function>index start()</function></term>
430 <listitem>
431 <para>This function returns the first index represented by the range</para>
432 </listitem>
433 </varlistentry>
434
435 <varlistentry><term><function>index finish()</function></term>
436 <listitem>
437 <para>This function returns the upper boundary value of the half-open
438 interval. Note that the range does not include this value.</para>
439 </listitem>
440 </varlistentry>
441
442 <varlistentry>
443 <term><function>size_type size()</function></term>
444 <listitem>
445 <para>This function returns the size of the specified range. It is
446 equivalent to <literal>finish()-start()</literal>.</para>
447 </listitem>
448 </varlistentry>
449
450 </variablelist>
451 </formalpara>
452 </sect2>
453
454 <sect2 id="extent_gen">
455 <title><classname>extent_gen</classname></title>
456 <para>The <classname>extent_gen</classname> class defines an
457 interface for aggregating array shape and indexing information to be
458 passed to a <literal>multi_array</literal>,
459 <literal>multi_array_ref</literal>, or <literal>const_multi_array_ref</literal>
460 constructor. Its interface mimics
461 the syntax used to declare built-in array types
462 in C++. For example, while a 3-dimensional array of
463 <classname>int</classname> values in C++ would be
464 declared as:
465 <programlisting>int A[3][4][5],</programlisting>
466 a similar <classname>multi_array</classname> would be declared:
467 <programlisting>multi_array&lt;int,3&gt; A(extents[3][4][5]).</programlisting>
468 </para>
469
470 <formalpara><title>Synopsis</title>
471 <programlisting><![CDATA[
472 template <std::size_t NumRanges>
473 class *implementation_defined* {
474 public:
475 typedef multi_array_types::index index;
476 typedef multi_array_types::size_type size_type;
477
478 template <std::size_t NumRanges> class gen_type;
479
480 gen_type<NumRanges+1>::type operator[](const range& a_range) const;
481 gen_type<NumRanges+1>::type operator[](index idx) const;
482 };
483
484 typedef *implementation_defined*<0> extent_gen;
485 ]]></programlisting>
486 </formalpara>
487
488 <formalpara><title>Methods and Types</title>
489 <variablelist>
490 <varlistentry>
491 <term><function>template gen_type&lt;Ranges&gt;::type</function></term>
492 <listitem>
493 <para>This type generator is used to specify the result of
494 <literal>Ranges</literal> chained calls to
495 <literal>extent_gen::operator[].</literal> The types
496 <classname>extent_gen</classname> and
497 <classname>gen_type&lt;0&gt;::type</classname> are the same.</para>
498 </listitem>
499 </varlistentry>
500
501 <varlistentry>
502 <term><function>gen_type&lt;NumRanges+1&gt;::type
503 operator[](const extent_range&amp; a_range) const;</function></term>
504 <listitem>
505 <para>This function returns a new object containing all previous
506 <classname>extent_range</classname> objects in addition to
507 <literal>a_range.</literal> <classname>extent_range</classname>
508 objects are aggregated by chained calls to
509 <function>operator[]</function>.</para>
510 </listitem>
511 </varlistentry>
512
513 <varlistentry>
514 <term><function>gen_type&lt;NumRanges+1&gt;::type
515 operator[](index idx) const;</function></term>
516 <listitem>
517 <para>This function returns a new object containing all previous
518 <classname>extent_range</classname> objects in addition to
519 <literal>extent_range(0,idx).</literal> This function gives the array
520 constructors a similar syntax to traditional C multidimensional array
521 declaration.</para>
522 </listitem>
523 </varlistentry>
524
525 </variablelist>
526 </formalpara>
527 </sect2>
528
529 <sect2>
530 <title>Global Objects</title>
531 <para>For syntactic convenience, Boost.MultiArray defines two
532 global objects as part of its
533 interface. These objects play the role of object generators;
534 expressions involving them create other objects of interest.
535 </para>
536
537 <para> Under some circumstances, the two global objects may be
538 considered excessive overhead. Their construction can be prevented by
539 defining the preprocessor symbol
540 <literal>BOOST_MULTI_ARRAY_NO_GENERATORS</literal> before including
541 <filename>boost/multi_array.hpp.</filename></para>
542
543 <sect3 id="extents">
544 <title><literal>extents</literal></title>
545
546 <programlisting>
547 <![CDATA[namespace boost {
548 multi_array_base::extent_gen extents;
549 }]]>
550 </programlisting>
551
552 <para>Boost.MultiArray's array classes use the
553 <literal>extents</literal> global object to specify
554 array shape during their construction.
555 For example,
556 a 3 by 3 by 3 <classname>multi_array</classname> is constructed as follows:
557 <programlisting>multi_array&lt;int,3&gt; A(extents[3][3][3]);</programlisting>
558 The same array could also be created by explicitly declaring an <literal>extent_gen</literal>
559 object locally,, but the global object makes this declaration unnecessary.
560 </para>
561 </sect3>
562
563 <sect3 id="indices">
564 <title><literal>indices</literal></title>
565
566 <programlisting>
567 <![CDATA[namespace boost {
568 multi_array_base::index_gen indices;
569 }]]>
570 </programlisting>
571
572 <para>The MultiArray concept specifies an
573 <literal>index_gen</literal> associated type that is used to
574 create views.
575 <literal>indices</literal> is a global object that serves the role of
576 <literal>index_gen</literal> for all array components provided by this
577 library and their associated subarrays and views.
578 </para>
579 <para>For example, using the <literal>indices</literal> object,
580 a view of an array <literal>A</literal> is constructed as follows:
581 <programlisting>
582 A[indices[index_range(0,5)][2][index_range(2,4)]];
583 </programlisting>
584 </para>
585 </sect3>
586 </sect2>
587
588 <sect2 id="generators">
589 <title>View and SubArray Generators</title>
590 <para>
591 Boost.MultiArray provides traits classes, <literal>subarray_gen</literal>,
592 <literal>const_subarray_gen</literal>,
593 <literal>array_view_gen</literal>,
594 and <literal>const_array_view_gen</literal>, for naming of
595 array associated types within function templates.
596 In general this is no more convenient to use than the nested
597 type generators, but the library author found that some C++ compilers do not
598 properly handle templates nested within function template parameter types.
599 These generators constitute a workaround for this deficit.
600 The following code snippet illustrates
601 the correspondence between the <literal>array_view_gen</literal>
602 traits class and the <literal>array_view</literal> type associated to
603 an array:
604
605 <programlisting>
606 template &lt;typename Array&gt;
607 void my_function() {
608 typedef typename Array::template array_view&lt;3&gt;::type view1_t;
609 typedef typename boost::array_view_gen&lt;Array,3&gt;::type view2_t;
610 // ...
611 }
612 </programlisting>
613
614 In the above example, <literal>view1_t</literal> and
615 <literal>view2_t</literal> have the same type.
616 </para>
617 </sect2>
618
619
620 <sect2 id="memory_layout">
621 <title>Memory Layout Specifiers</title>
622 <para>
623 While a multidimensional array represents a hierarchy of containers of
624 elements, at some point the elements must be laid out in
625 memory. As a result, a single multidimensional array
626 can be represented in memory more than one way.
627 </para>
628
629 <para>For example, consider the two dimensional array shown below in
630 matrix notation:
631
632 <graphic fileref="matrix.gif"/>
633
634 Here is how the above array is expressed in C++:
635 <programlisting>
636 int a[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
637 </programlisting>
638 This is an example of row-major storage, where elements of each row
639 are stored contiguously.
640
641 While C++ transparently handles accessing elements of an array, you
642 can also manage the array and its indexing manually. One way that
643 this may be expressed in memory is as follows:
644 <programlisting>
645 int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
646 int s[] = { 4, 1 };
647 </programlisting>
648
649 With the latter declaration of <literal>a</literal> and
650 strides <literal>s</literal>, element <literal>a(i,j)</literal>
651 of the array can be
652 accessed using the expression
653 <programlisting>*a+i*s[0]+j*s[1]</programlisting>.
654 </para>
655
656 <para>The same two dimensional array could be laid out by column as follows:
657
658 <programlisting>
659 int a[] = { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11 };
660 int s[] = { 3, 1 };
661 </programlisting>
662 Notice that the strides here are different. As a result,
663 The expression given above to access values will work with this pair
664 of data and strides as well.
665 </para>
666
667 <para>In addition to dimension order, it is also possible to
668 store any dimension in descending order. For example, returning to the
669 first example, the first dimension of the example array, the
670 rows, could be stored in
671 reverse, resulting in the following:
672
673 <programlisting>
674 int data[] = { 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 };
675 int *a = data + 8;
676 int s[] = { -4, 1 };
677 </programlisting>
678
679 Note that in this example <literal>a</literal> must be explicitly set
680 to the origin. In the previous examples, the
681 first element stored in memory was the origin; here this is no longer
682 the case.
683 </para>
684
685 <para>
686 Alternatively, the second dimension, or the columns, could be reversed
687 and the rows stored in ascending order:
688
689 <programlisting>
690 int data[] = { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8 };
691 int *a = data + 3;
692 int s[] = { 4, -1 };
693 </programlisting>
694 </para>
695
696 <para>
697 Finally, both dimensions could be stored in descending order:
698
699 <programlisting>
700 int data[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
701 int *a = data + 11;
702 int s[] = { -4, -1 };
703 </programlisting>
704 <literal>
705 </literal>
706 </para>
707
708 <para>
709 All of the above arrays are equivalent. The expression
710 given above for <literal>a(i,j)</literal> will yield the same value
711 regardless of the memory layout.
712
713 Boost.MultiArray arrays can be created with customized storage
714 parameters as described above. Thus, existing data can be adapted
715 (with <literal>multi_array_ref</literal> or
716 <literal>const_multi_array_ref</literal>) as suited to the array
717 abstraction. A common usage of this feature would be to wrap arrays
718 that must interoperate with Fortran routines so they can be
719 manipulated naturally at both the C++ and Fortran levels. The
720 following sections describe the Boost.MultiArray components used to
721 specify memory layout.
722 </para>
723
724 <sect3 id="c_storage_order">
725 <title><literal>c_storage_order</literal></title>
726 <programlisting>
727 <![CDATA[class c_storage_order {
728 c_storage_order();
729 };]]>
730 </programlisting>
731
732 <para><literal>c_storage_order</literal> is used to specify that an
733 array should store its elements using the same layout as that used by
734 primitive C++ multidimensional arrays, that is, from last dimension
735 to first. This is the default storage order for the arrays provided by
736 this library.</para>
737 </sect3>
738
739 <sect3 id="fortran_storage_order">
740 <title><literal>fortran_storage_order</literal></title>
741 <programlisting>
742 <![CDATA[class fortran_storage_order {
743 fortran_storage_order();
744 };]]>
745 </programlisting>
746
747 <para><literal>fortran_storage_order</literal> is used to specify that
748 an array should store its elements using the same memory layout as a
749 Fortran multidimensional array would, that is, from first dimension to
750 last.</para>
751 </sect3>
752
753 <sect3 id="general_storage_order">
754 <title><literal>general_storage_order</literal></title>
755 <programlisting>
756 <![CDATA[template <std::size_t NumDims>
757 class general_storage_order {
758
759 template <typename OrderingIter, typename AscendingIter>
760 general_storage_order(OrderingIter ordering, AscendingIter ascending);
761 };]]>
762 </programlisting>
763
764 <para><literal>general_storage_order</literal> allows the user to
765 specify an arbitrary memory layout for the contents of an array. The
766 constructed object is passed to the array constructor in order to
767 specify storage order.</para>
768
769 <para>
770 <literal>OrderingIter</literal> and <literal>AscendingIter</literal>
771 must model the <literal>InputIterator</literal> concept. Both
772 iterators must refer to a range of <literal>NumDims</literal>
773 elements. <literal>AscendingIter</literal> points to objects
774 convertible to <literal>bool</literal>. A value of
775 <literal>true</literal> means that a dimension is stored in ascending
776 order while <literal>false</literal> means that a dimension is stored
777 in descending order. <literal>OrderingIter</literal> specifies the
778 order in which dimensions are stored.
779 </para>
780
781 </sect3>
782 </sect2>
783
784 <sect2 id="range_checking">
785 <title>Range Checking</title>
786 <para>
787 By default, the array access methods <literal>operator()</literal> and
788 <literal>operator[]</literal> perform range
789 checking. If a supplied index is out of the range defined for an
790 array, an assertion will abort the program. To disable range
791 checking (for performance reasons in production releases), define
792 the <literal>BOOST_DISABLE_ASSERTS</literal> preprocessor macro prior to
793 including multi_array.hpp in an application.
794 </para>
795
796 </sect2>
797 </sect1>
798
799
800 </article>