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