MultiArray.xml 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. <sect1 id="MultiArray"><title>MultiArray Concept</title>
  2. <para>The MultiArray
  3. concept defines an interface to hierarchically nested
  4. containers. It specifies operations for accessing elements,
  5. traversing containers, and creating views
  6. of array data.
  7. MultiArray defines
  8. a flexible memory model that accomodates
  9. a variety of data layouts.
  10. </para>
  11. <para>
  12. At each level (or dimension) of a MultiArray's
  13. container hierarchy lie a set of ordered containers, each of which
  14. contains the same number and type of values. The depth of this
  15. container hierarchy is the MultiArray's <emphasis>dimensionality</emphasis>.
  16. MultiArray is recursively defined; the
  17. containers at each level of the container hierarchy model
  18. MultiArray as well. While each dimension of a MultiArray
  19. has its own size, the list of sizes for all dimensions
  20. defines the <emphasis>shape</emphasis> of the entire MultiArray.
  21. At the base of this hierarchy lie 1-dimensional
  22. MultiArrays. Their values are the contained
  23. objects of interest and not part of the container hierarchy. These are
  24. the MultiArray's elements.
  25. </para>
  26. <para>
  27. Like other container concepts, MultiArray exports
  28. iterators to traverse its values. In addition, values can be
  29. addressed directly using the familiar bracket notation.
  30. </para>
  31. <para>
  32. MultiArray also specifies
  33. routines for creating
  34. specialized views. A <emphasis>view</emphasis> lets you treat a
  35. subset of the underlying
  36. elements in a MultiArray as though it were a separate
  37. MultiArray. Since a view refers to the same underlying elements,
  38. changes made to a view's elements will be reflected in the original
  39. MultiArray. For
  40. example, given a 3-dimensional "cube" of elements, a 2-dimensional
  41. slice can be viewed as if it were an independent
  42. MultiArray.
  43. Views are created using <literal>index_gen</literal> and
  44. <literal>index_range</literal> objects.
  45. <literal>index_range</literal>s denote elements from a certain
  46. dimension that are to be included in a
  47. view. <literal>index_gen</literal> aggregates range data and performs
  48. bookkeeping to determine the view type to be returned.
  49. MultiArray's <literal>operator[]</literal>
  50. must be passed the result
  51. of <literal>N</literal> chained calls to
  52. <literal>index_gen::operator[]</literal>, i.e.
  53. <programlisting>indices[a0][a1]...[aN];
  54. </programlisting>
  55. where <literal>N</literal> is the
  56. MultiArray's dimensionality and
  57. <literal>indices</literal> an object of type <literal>index_gen</literal>.
  58. The view type is dependent upon the number of degenerate dimensions
  59. specified to <literal>index_gen</literal>. A degenerate dimension
  60. occurs when a single-index is specified to
  61. <literal>index_gen</literal> for a certain dimension. For example, if
  62. <literal>indices</literal> is an object of type
  63. <literal>index_gen</literal>, then the following example:
  64. <programlisting>indices[index_range(0,5)][2][index_range(0,4)];
  65. </programlisting>
  66. has a degenerate second dimension. The view generated from the above
  67. specification will have 2 dimensions with shape <literal>5 x 4</literal>.
  68. If the "<literal>2</literal>" above were replaced with
  69. another <literal>index_range</literal> object, for example:
  70. <programlisting>indices[index_range(0,5)][index_range(0,2)][index_range(0,4)];
  71. </programlisting>
  72. then the view would have 3 dimensions.</para>
  73. <para>
  74. MultiArray exports
  75. information regarding the memory
  76. layout of its contained elements. Its memory model for elements is
  77. completely defined by 4 properties: the origin, shape, index bases,
  78. and strides. The origin is the address in memory of the element
  79. accessed as <literal>a[0][0]...[0]</literal>, where
  80. <literal>a</literal> is a MultiArray. The shape is a list of numbers
  81. specifying the size of containers at each dimension. For example, the
  82. first extent is the size of the outermost container, the second extent
  83. is the size of its subcontainers, and so on. The index bases are a
  84. list of signed values specifying the index of the first value in a
  85. container. All containers at the same dimension share the same index
  86. base. Note that since positive index bases are
  87. possible, the origin need not exist in order to determine the location
  88. in memory of the MultiArray's elements.
  89. The strides determine how index values are mapped to memory offsets.
  90. They accomodate a
  91. number of possible element layouts. For example, the elements of a 2
  92. dimensional array can be stored by row (i.e., the elements of each row
  93. are stored contiguously) or by column (i.e., the elements of each
  94. column are stored contiguously).
  95. </para>
  96. <para>
  97. Two concept checking classes for the MultiArray concepts
  98. (<literal>ConstMultiArrayConcept</literal> and
  99. <literal>MutableMultiArrayConcept</literal>) are in the namespace
  100. <literal>boost::multi_array_concepts</literal> in
  101. <literal>&lt;boost/multi_array/concept_checks.hpp&gt;</literal>.
  102. </para>
  103. <sect2><title>Notation</title>
  104. <para>What follows are the descriptions of symbols that will be used
  105. to describe the MultiArray interface.</para>
  106. <table>
  107. <title>Notation</title>
  108. <tgroup cols="2">
  109. <tbody>
  110. <row>
  111. <entry><literal>A</literal></entry>
  112. <entry>A type that is a model of MultiArray
  113. </entry>
  114. </row>
  115. <row>
  116. <entry><literal>a,b</literal></entry>
  117. <entry>Objects of type <literal>A</literal></entry>
  118. </row>
  119. <row>
  120. <entry><literal>NumDims</literal></entry>
  121. <entry>The numeric dimension parameter associated with
  122. <literal>A</literal>.</entry>
  123. </row>
  124. <row>
  125. <entry><literal>Dims</literal></entry>
  126. <entry>Some numeric dimension parameter such that
  127. <literal>0&lt;Dims&lt;NumDims</literal>.
  128. </entry>
  129. </row>
  130. <row>
  131. <entry><literal>indices</literal></entry>
  132. <entry>An object created by some number of chained calls
  133. to <literal>index_gen::operator[](index_range)</literal>.</entry>
  134. </row>
  135. <row>
  136. <entry><literal>index_list</literal></entry>
  137. <entry>An object whose type models
  138. <ulink url="../../utility/Collection.html">Collection</ulink>
  139. </entry>
  140. </row>
  141. <row>
  142. <entry><literal>idx</literal></entry>
  143. <entry>A signed integral value.</entry>
  144. </row>
  145. <row>
  146. <entry><literal>tmp</literal></entry>
  147. <entry>An object of type
  148. <literal>boost::array&lt;index,NumDims&gt;</literal></entry>
  149. </row>
  150. </tbody>
  151. </tgroup>
  152. </table>
  153. </sect2>
  154. <sect2><title>Associated Types</title>
  155. <para>
  156. </para>
  157. <table><title>Associated Types</title>
  158. <tgroup cols="2">
  159. <thead>
  160. <row>
  161. <entry>Type</entry>
  162. <entry>Description</entry>
  163. </row>
  164. </thead>
  165. <tbody>
  166. <row>
  167. <entry><literal>value_type</literal></entry>
  168. <entry>This is the value type of the container.
  169. If <literal>NumDims == 1</literal>, then this is
  170. <literal>element</literal>. Otherwise, this is the value type of the
  171. immediately nested containers.
  172. </entry>
  173. </row>
  174. <row>
  175. <entry>
  176. <literal>reference</literal>
  177. </entry>
  178. <entry>
  179. This is the reference type of the contained value.
  180. If <literal>NumDims == 1</literal>, then this is
  181. <literal>element&amp;</literal>. Otherwise, this is the same type as
  182. <literal>template subarray&lt;NumDims-1&gt;::type</literal>.
  183. </entry>
  184. </row>
  185. <row>
  186. <entry>
  187. <literal>const_reference</literal>
  188. </entry>
  189. <entry>
  190. This is the const reference type of the contained value.
  191. If <literal>NumDims == 1</literal>, then this is
  192. <literal>const element&amp;</literal>. Otherwise, this is the same
  193. type as
  194. <literal>template const_subarray&lt;NumDims-1&gt;::type</literal>.
  195. </entry>
  196. </row>
  197. <row>
  198. <entry>
  199. <literal>size_type</literal>
  200. </entry>
  201. <entry>
  202. This is an unsigned integral type. It is primarily used to specify array shape.
  203. </entry>
  204. </row>
  205. <row>
  206. <entry>
  207. <literal>difference_type</literal>
  208. </entry>
  209. <entry>
  210. This is a signed integral type used to represent the distance between two
  211. iterators. It is the same type as
  212. <literal>std::iterator_traits&lt;iterator&gt;::difference_type</literal>.
  213. </entry>
  214. </row>
  215. <row>
  216. <entry><literal>iterator</literal></entry>
  217. <entry>
  218. This is an iterator over the values of <literal>A</literal>.
  219. If <literal>NumDims == 1</literal>, then it models
  220. <ulink url="http://www.boost.org/doc/html/RandomAccessIterator.html">
  221. <literal>Random Access Iterator</literal></ulink>.
  222. Otherwise it models
  223. <ulink url="./iterator_categories.html#concept_RandomAccessTraversalIterator">
  224. Random Access Traversal Iterator</ulink>,
  225. <ulink url="./iterator_categories.html#concept_ReadableIterator">
  226. Readable Iterator</ulink>,
  227. <ulink url="./iterator_categories.html#concept_WritableIterator">
  228. Writable Iterator</ulink>, and
  229. <ulink url="http://www.boost.org/doc/html/OutputIterator.html">
  230. <literal>Output Iterator</literal></ulink>.
  231. </entry>
  232. </row>
  233. <row>
  234. <entry>
  235. <literal>const_iterator</literal>
  236. </entry>
  237. <entry>
  238. This is the const iterator over the values of <literal>A</literal>.
  239. </entry>
  240. </row>
  241. <row>
  242. <entry>
  243. <literal>reverse_iterator</literal>
  244. </entry>
  245. <entry>
  246. This is the reversed iterator, used to iterate backwards over the values of
  247. <literal>A</literal>.
  248. </entry>
  249. </row>
  250. <row>
  251. <entry>
  252. <literal>const_reverse_iterator</literal>
  253. </entry>
  254. <entry>
  255. This is the reversed const iterator.
  256. <literal>A</literal>.
  257. </entry>
  258. </row>
  259. <row>
  260. <entry>
  261. <literal>element</literal>
  262. </entry>
  263. <entry>
  264. This is the type of objects stored at the base of the
  265. hierarchy of MultiArrays. It is the same as
  266. <literal>template subarray&lt;1&gt;::value_type</literal>
  267. </entry>
  268. </row>
  269. <row>
  270. <entry>
  271. <literal>index</literal>
  272. </entry>
  273. <entry>
  274. This is a signed integral type used for indexing into <literal>A</literal>. It
  275. is also used to represent strides and index bases.
  276. </entry>
  277. </row>
  278. <row>
  279. <entry>
  280. <literal>index_gen</literal>
  281. </entry>
  282. <entry>
  283. This type is used to create a tuple of <literal>index_range</literal>s
  284. passed to <literal>operator[]</literal> to create
  285. an <literal>array_view&lt;Dims&gt;::type</literal> object.
  286. </entry>
  287. </row>
  288. <row>
  289. <entry>
  290. <literal>index_range</literal>
  291. </entry>
  292. <entry>
  293. This type specifies a range of indices over some dimension of a
  294. MultiArray. This range will be visible through an
  295. <literal>array_view&lt;Dims&gt;::type</literal> object.
  296. </entry>
  297. </row>
  298. <row>
  299. <entry>
  300. <literal>template subarray&lt;Dims&gt;::type</literal>
  301. </entry>
  302. <entry>
  303. This is subarray type with <literal>Dims</literal> dimensions.
  304. It is the reference type of the <literal>(NumDims - Dims)</literal>
  305. dimension of <literal>A</literal> and also models
  306. MultiArray.
  307. </entry>
  308. </row>
  309. <row>
  310. <entry>
  311. <literal>template const_subarray&lt;Dims&gt;::type</literal>
  312. </entry>
  313. <entry>
  314. This is the const subarray type.
  315. </entry>
  316. </row>
  317. <row>
  318. <entry>
  319. <literal>template array_view&lt;Dims&gt;::type</literal>
  320. </entry>
  321. <entry>
  322. This is the view type with <literal>Dims</literal> dimensions. It is
  323. returned by calling <literal>operator[](<literal>indices</literal>)</literal>.
  324. It models MultiArray.
  325. </entry>
  326. </row>
  327. <row>
  328. <entry>
  329. <literal>template
  330. const_array_view&lt;Dims&gt;::type</literal>
  331. </entry>
  332. <entry>
  333. This is the const view type with <literal>Dims</literal> dimensions.
  334. </entry>
  335. </row>
  336. </tbody>
  337. </tgroup>
  338. </table>
  339. </sect2>
  340. <sect2><title>Valid expressions</title>
  341. <table><title>Valid Expressions</title>
  342. <tgroup cols="3">
  343. <thead>
  344. <row>
  345. <entry>Expression</entry>
  346. <entry>Return type</entry>
  347. <entry>Semantics</entry>
  348. </row>
  349. </thead>
  350. <tbody>
  351. <row>
  352. <entry><literal>A::dimensionality</literal></entry>
  353. <entry><literal>size_type</literal></entry>
  354. <entry>This compile-time constant represents the number of
  355. dimensions of the array (note that
  356. <literal>A::dimensionality == NumDims</literal>).</entry>
  357. </row>
  358. <row>
  359. <entry><literal>a.shape()</literal></entry>
  360. <entry><literal>const size_type*</literal></entry>
  361. <entry>
  362. This returns a list of <literal>NumDims</literal> elements specifying the
  363. extent of each array dimension.
  364. </entry>
  365. </row>
  366. <row>
  367. <entry><literal>a.strides()</literal></entry>
  368. <entry><literal>const index*</literal></entry>
  369. <entry>
  370. This returns a list of <literal>NumDims</literal> elements specifying the
  371. stride associated with each array dimension. When accessing values,
  372. strides is used to calculate an element's location in memory.
  373. </entry>
  374. </row>
  375. <row>
  376. <entry><literal>a.index_bases()</literal></entry>
  377. <entry><literal>const index*</literal></entry>
  378. <entry>
  379. This returns a list of <literal>NumDims</literal> elements specifying the
  380. numeric index of the first element for each array dimension.
  381. </entry>
  382. </row>
  383. <row>
  384. <entry><literal>a.origin()</literal></entry>
  385. <entry>
  386. <literal>element*</literal> if <literal>a</literal> is mutable,
  387. <literal>const element*</literal> otherwise.
  388. </entry>
  389. <entry>
  390. This returns the address of the element accessed by the expression
  391. <literal>a[0][0]...[0].</literal>. If the index bases are positive,
  392. this element won't exist, but the address can still be used to locate
  393. a valid element given its indices.
  394. </entry>
  395. </row>
  396. <row>
  397. <entry><literal>a.num_dimensions()</literal></entry>
  398. <entry><literal>size_type</literal></entry>
  399. <entry>This returns the number of dimensions of the array
  400. (note that <literal>a.num_dimensions() == NumDims</literal>).</entry>
  401. </row>
  402. <row>
  403. <entry><literal>a.num_elements()</literal></entry>
  404. <entry><literal>size_type</literal></entry>
  405. <entry>This returns the number of elements contained
  406. in the array. It is equivalent to the following code:
  407. <programlisting>
  408. std::accumulate(a.shape(),a.shape+a.num_dimensions(),
  409. size_type(1),std::multiplies&lt;size_type&gt;());
  410. </programlisting>
  411. </entry>
  412. </row>
  413. <row>
  414. <entry><literal>a.size()</literal></entry>
  415. <entry><literal>size_type</literal></entry>
  416. <entry>
  417. This returns the number of values contained in
  418. <literal>a</literal>. It is equivalent to <literal>a.shape()[0];</literal>
  419. </entry>
  420. </row>
  421. <row>
  422. <entry><literal>a(index_list)</literal></entry>
  423. <entry>
  424. <literal>element&amp;</literal>; if <literal>a</literal> is mutable,
  425. <literal>const element&amp;</literal> otherwise.
  426. </entry>
  427. <entry>
  428. This expression accesses a specific element of
  429. <literal>a</literal>.<literal>index_list</literal> is the unique set
  430. of indices that address the element returned. It is
  431. equivalent to the following code (disregarding intermediate temporaries):
  432. <programlisting>
  433. // multiply indices by strides
  434. std::transform(index_list.begin(), index_list.end(),
  435. a.strides(), tmp.begin(), std::multiplies&lt;index&gt;()),
  436. // add the sum of the products to the origin
  437. *std::accumulate(tmp.begin(), tmp.end(), a.origin());
  438. </programlisting>
  439. </entry>
  440. </row>
  441. <row>
  442. <entry><literal>a.begin()</literal></entry>
  443. <entry>
  444. <literal>iterator</literal> if <literal>a</literal> is mutable,
  445. <literal>const_iterator</literal> otherwise.
  446. </entry>
  447. <entry>This returns an iterator pointing to the beginning of
  448. <literal>a</literal>.</entry>
  449. </row>
  450. <row>
  451. <entry><literal>a.end()</literal></entry>
  452. <entry>
  453. <literal>iterator</literal> if <literal>a</literal> is mutable,
  454. <literal>const_iterator</literal> otherwise.
  455. </entry>
  456. <entry>This returns an iterator pointing to the end of
  457. <literal>a</literal>.</entry>
  458. </row>
  459. <row>
  460. <entry><literal>a.rbegin()</literal></entry>
  461. <entry>
  462. <literal>reverse_iterator</literal> if <literal>a</literal> is mutable,
  463. <literal>const_reverse_iterator</literal> otherwise.
  464. </entry>
  465. <entry>This returns a reverse iterator pointing to the
  466. beginning of <literal>a</literal> reversed.
  467. </entry>
  468. </row>
  469. <row>
  470. <entry><literal>a.rend()</literal></entry>
  471. <entry>
  472. <literal>reverse_iterator</literal> if <literal>a</literal> is mutable,
  473. <literal>const_reverse_iterator</literal> otherwise.
  474. </entry>
  475. <entry>
  476. This returns a reverse iterator pointing to the end of <literal>a</literal>
  477. reversed.
  478. </entry>
  479. </row>
  480. <row>
  481. <entry><literal>a[idx]</literal></entry>
  482. <entry>
  483. <literal>reference</literal> if <literal>a</literal> is mutable,
  484. <literal>const_reference</literal> otherwise.
  485. </entry>
  486. <entry>
  487. This returns a reference type that is bound to the index
  488. <literal>idx</literal> value of <literal>a</literal>. Note that if
  489. <literal>i</literal> is the index base for this dimension, the above
  490. expression returns the <literal>(idx-i)</literal>th element (counting
  491. from zero). The expression is equivalent to
  492. <literal>*(a.begin()+idx-a.index_bases()[0]);</literal>.
  493. </entry>
  494. </row>
  495. <row>
  496. <entry><literal>a[indices]</literal></entry>
  497. <entry>
  498. <literal>array_view&lt;Dims&gt;::type</literal> if
  499. <literal>a</literal> is mutable,
  500. <literal>const_array_view&lt;Dims&gt;::type</literal> otherwise.
  501. </entry>
  502. <entry>
  503. This expression generates a view of the array determined by the
  504. <literal>index_range</literal> and <literal>index</literal> values
  505. used to construct <literal>indices</literal>.
  506. </entry>
  507. </row>
  508. <row>
  509. <entry><literal>a == b</literal></entry>
  510. <entry>bool</entry>
  511. <entry>This performs a lexicographical comparison of the
  512. values of <literal>a</literal> and <literal>b</literal>. The element
  513. type must model <ulink url="https://www.boost.org/sgi/stl/EqualityComparable.html">EqualityComparable</ulink> for this
  514. expression to be valid.</entry>
  515. </row>
  516. <row>
  517. <entry><literal>a &lt; b</literal></entry>
  518. <entry>bool</entry>
  519. <entry>This performs a lexicographical comparison of the
  520. values of <literal>a</literal> and <literal>b</literal>. The element
  521. type must model <ulink url="https://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</ulink> for this
  522. expression to be valid.</entry>
  523. </row>
  524. <row>
  525. <entry><literal>a &lt;= b</literal></entry>
  526. <entry>bool</entry>
  527. <entry>This performs a lexicographical comparison of the
  528. values of <literal>a</literal> and <literal>b</literal>. The element
  529. type must model <ulink url="https://www.boost.org/sgi/stl/EqualityComparable.html">EqualityComparable</ulink> and
  530. <ulink url="https://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</ulink> for this
  531. expression to be valid.</entry>
  532. </row>
  533. <row>
  534. <entry><literal>a &gt; b</literal></entry>
  535. <entry>bool</entry>
  536. <entry>This performs a lexicographical comparison of the
  537. values of <literal>a</literal> and <literal>b</literal>. The element
  538. type must model <ulink url="https://www.boost.org/sgi/stl/EqualityComparable.html">EqualityComparable</ulink> and
  539. <ulink url="https://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</ulink> for this
  540. expression to be valid.</entry>
  541. </row>
  542. <row>
  543. <entry><literal>a &gt;= b</literal></entry>
  544. <entry>bool</entry>
  545. <entry>This performs a lexicographical comparison of the
  546. values of <literal>a</literal> and <literal>b</literal>. The element
  547. type must model <ulink url="https://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</ulink> for this
  548. expression to be valid.</entry>
  549. </row>
  550. </tbody>
  551. </tgroup>
  552. </table>
  553. </sect2>
  554. <sect2><title>Complexity guarantees</title>
  555. <literal>begin()</literal> and <literal>end()</literal> execute in amortized
  556. constant time.
  557. <literal>size()</literal> executes in at most linear time in the
  558. MultiArray's size.
  559. </sect2>
  560. <sect2>
  561. <title>Invariants</title>
  562. <table><title>Invariants</title>
  563. <tgroup cols="2">
  564. <tbody>
  565. <row>
  566. <entry>Valid range</entry>
  567. <entry><literal>[a.begin(),a.end())</literal> is a valid range.
  568. </entry>
  569. </row>
  570. <row>
  571. <entry>Range size</entry>
  572. <entry>
  573. <literal>a.size() == std::distance(a.begin(),a.end());</literal>.
  574. </entry>
  575. </row>
  576. <row>
  577. <entry>Completeness</entry>
  578. <entry>
  579. Iteration through the range
  580. <literal>[a.begin(),a.end())</literal> will traverse across every
  581. <literal>value_type</literal> of <literal>a</literal>.
  582. </entry>
  583. </row>
  584. <row>
  585. <entry>Accessor Equivalence</entry>
  586. <entry>
  587. Calling <literal>a[a1][a2]...[aN]</literal> where <literal>N==NumDims</literal>
  588. yields the same result as calling
  589. <literal>a(index_list)</literal>, where <literal>index_list</literal>
  590. is a <ulink url="../../utility/Collection.html">Collection</ulink> containing the values <literal>a1...aN</literal>.
  591. </entry>
  592. </row>
  593. </tbody>
  594. </tgroup>
  595. </table>
  596. </sect2>
  597. <sect2 id="view_types">
  598. <title>Associated Types for Views</title>
  599. <para>The following MultiArray associated
  600. types define the interface for creating views of existing
  601. MultiArrays. Their interfaces and roles in the
  602. concept are described below.</para>
  603. <sect3 id="index_range">
  604. <title><literal>index_range</literal></title>
  605. <para><literal>index_range</literal> objects represent half-open
  606. strided intervals. They are aggregated (using an
  607. <literal>index_gen</literal> object) and passed to
  608. a MultiArray's <literal>operator[]</literal>
  609. to create an array view. When creating a view,
  610. each <literal>index_range</literal> denotes a range of
  611. valid indices along one dimension of a MultiArray.
  612. Elements that are accessed through the set of ranges specified will be
  613. included in the constructed view. In some cases, an
  614. <literal>index_range</literal> is created without specifying start
  615. or finish values. In those cases, the object is interpreted to
  616. start at the beginning of a MultiArray dimension
  617. and end at its end.</para>
  618. <para>
  619. <literal>index_range</literal> objects can be constructed and modified
  620. several ways in order to allow convenient and clear expression of a
  621. range of indices. To specify ranges, <literal>index_range</literal>
  622. supports a set of constructors, mutating member functions, and a novel
  623. specification involving inequality operators. Using inequality
  624. operators, a half open range [5,10) can be specified as follows:
  625. <programlisting>5 &lt;= index_range() &lt; 10;</programlisting> or
  626. <programlisting>4 &lt; index_range() &lt;= 9;</programlisting> and so on.
  627. The following describes the
  628. <literal>index_range</literal> interface.
  629. </para>
  630. <table>
  631. <title>Notation</title>
  632. <tgroup cols="2">
  633. <tbody>
  634. <row>
  635. <entry><literal>i</literal></entry>
  636. <entry>An object of type <literal>index_range</literal>.</entry>
  637. </row>
  638. <row>
  639. <entry><literal>idx,idx1,idx2,idx3</literal></entry>
  640. <entry>Objects of type <literal>index</literal>.</entry>
  641. </row>
  642. </tbody>
  643. </tgroup>
  644. </table>
  645. <table><title>Associated Types</title>
  646. <tgroup cols="2">
  647. <thead>
  648. <row>
  649. <entry>Type</entry>
  650. <entry>Description</entry>
  651. </row>
  652. </thead>
  653. <tbody>
  654. <row>
  655. <entry><literal>index</literal></entry>
  656. <entry>This is a signed integral type. It is used to
  657. specify the start, finish, and stride values.</entry>
  658. </row>
  659. <row>
  660. <entry><literal>size_type</literal></entry>
  661. <entry>This is an unsigned integral type. It is used to
  662. report the size of the range an <literal>index_range</literal>
  663. represents.</entry>
  664. </row>
  665. </tbody>
  666. </tgroup>
  667. </table>
  668. <table><title>Valid Expressions</title>
  669. <tgroup cols="3">
  670. <thead>
  671. <row>
  672. <entry>Expression</entry>
  673. <entry>Return type</entry>
  674. <entry>Semantics</entry>
  675. </row>
  676. </thead>
  677. <tbody>
  678. <row>
  679. <entry><literal>index_range(idx1,idx2,idx3)</literal></entry>
  680. <entry><literal>index_range</literal></entry>
  681. <entry>This constructs an <literal>index_range</literal>
  682. representing the interval <literal>[idx1,idx2)</literal>
  683. with stride <literal>idx3</literal>.</entry>
  684. </row>
  685. <row>
  686. <entry><literal>index_range(idx1,idx2)</literal></entry>
  687. <entry><literal>index_range</literal></entry>
  688. <entry>This constructs an <literal>index_range</literal>
  689. representing the interval <literal>[idx1,idx2)</literal>
  690. with unit stride. It is equivalent to
  691. <literal>index_range(idx1,idx2,1)</literal>.</entry>
  692. </row>
  693. <row>
  694. <entry><literal>index_range()</literal></entry>
  695. <entry><literal>index_range</literal></entry>
  696. <entry>This construct an <literal>index_range</literal>
  697. with unspecified start and finish values.</entry>
  698. </row>
  699. <row>
  700. <entry><literal>i.start(idx1)</literal></entry>
  701. <entry><literal>index&amp;</literal></entry>
  702. <entry>This sets the start index of <literal>i</literal> to
  703. <literal>idx</literal>.</entry>
  704. </row>
  705. <row>
  706. <entry><literal>i.finish(idx)</literal></entry>
  707. <entry><literal>index&amp;</literal></entry>
  708. <entry>This sets the finish index of <literal>i</literal> to
  709. <literal>idx</literal>.</entry>
  710. </row>
  711. <row>
  712. <entry><literal>i.stride(idx)</literal></entry>
  713. <entry><literal>index&amp;</literal></entry>
  714. <entry>This sets the stride length of <literal>i</literal> to
  715. <literal>idx</literal>.</entry>
  716. </row>
  717. <row>
  718. <entry><literal>i.start()</literal></entry>
  719. <entry><literal>index</literal></entry>
  720. <entry>This returns the start index of <literal>i</literal>.</entry>
  721. </row>
  722. <row>
  723. <entry><literal>i.finish()</literal></entry>
  724. <entry><literal>index</literal></entry>
  725. <entry>This returns the finish index of <literal>i</literal>.</entry>
  726. </row>
  727. <row>
  728. <entry><literal>i.stride()</literal></entry>
  729. <entry><literal>index</literal></entry>
  730. <entry>This returns the stride length of <literal>i</literal>.</entry>
  731. </row>
  732. <row>
  733. <entry><literal>i.get_start(idx)</literal></entry>
  734. <entry><literal>index</literal></entry>
  735. <entry>If <literal>i</literal> specifies a start
  736. value, this is equivalent to <literal>i.start()</literal>. Otherwise it
  737. returns <literal>idx</literal>.</entry>
  738. </row>
  739. <row>
  740. <entry><literal>i.get_finish(idx)</literal></entry>
  741. <entry><literal>index</literal></entry>
  742. <entry>If <literal>i</literal> specifies a finish
  743. value, this is equivalent to <literal>i.finish()</literal>. Otherwise it
  744. returns <literal>idx</literal>.</entry>
  745. </row>
  746. <row>
  747. <entry><literal>i.size(idx)</literal></entry>
  748. <entry><literal>size_type</literal></entry>
  749. <entry>If <literal>i</literal> specifies a both finish and
  750. start values, this is equivalent to
  751. <literal>(i.finish()-i.start())/i.stride()</literal>. Otherwise it
  752. returns <literal>idx</literal>.</entry>
  753. </row>
  754. <row>
  755. <entry><literal>i &lt; idx</literal></entry>
  756. <entry><literal>index</literal></entry>
  757. <entry>This is another syntax for specifying the finish
  758. value. This notation does not include
  759. <literal>idx</literal> in the range of valid indices. It is equivalent to
  760. <literal>index_range(r.start(), idx, r.stride())</literal></entry>
  761. </row>
  762. <row>
  763. <entry><literal>i &lt;= idx</literal></entry>
  764. <entry><literal>index</literal></entry>
  765. <entry>This is another syntax for specifying the finish
  766. value. This notation includes
  767. <literal>idx</literal> in the range of valid indices. It is equivalent to
  768. <literal>index_range(r.start(), idx + 1, r.stride())</literal></entry>
  769. </row>
  770. <row>
  771. <entry><literal>idx &lt; i</literal></entry>
  772. <entry><literal>index</literal></entry>
  773. <entry>This is another syntax for specifying the start
  774. value. This notation does not include
  775. <literal>idx</literal> in the range of valid indices. It is equivalent to
  776. <literal>index_range(idx + 1, i.finish(), i.stride())</literal>.</entry>
  777. </row>
  778. <row>
  779. <entry><literal>idx &lt;= i</literal></entry>
  780. <entry><literal>index</literal></entry>
  781. <entry>This is another syntax for specifying the start
  782. value. This notation includes
  783. <literal>idx1</literal> in the range of valid indices. It is equivalent to
  784. <literal>index_range(idx, i.finish(), i.stride())</literal>.</entry>
  785. </row>
  786. <row>
  787. <entry><literal>i + idx</literal></entry>
  788. <entry><literal>index</literal></entry>
  789. <entry>This expression shifts the start and finish values
  790. of <literal>i</literal> up by <literal>idx</literal>. It is equivalent to
  791. <literal>index_range(r.start()+idx1, r.finish()+idx, r.stride())</literal></entry>
  792. </row>
  793. <row>
  794. <entry><literal>i - idx</literal></entry>
  795. <entry><literal>index</literal></entry>
  796. <entry>This expression shifts the start and finish values
  797. of <literal>i</literal> up by <literal>idx</literal>. It is equivalent to
  798. <literal>index_range(r.start()-idx1, r.finish()-idx, r.stride())</literal></entry>
  799. </row>
  800. </tbody>
  801. </tgroup>
  802. </table>
  803. </sect3>
  804. <sect3 id="index_gen">
  805. <title><literal>index_gen</literal></title>
  806. <para> <literal>index_gen</literal> aggregates
  807. <literal>index_range</literal> objects in order to specify view
  808. parameters. Chained calls to <literal>operator[]</literal> store
  809. range and dimension information used to
  810. instantiate a new view into a MultiArray.
  811. </para>
  812. <table>
  813. <title>Notation</title>
  814. <tgroup cols="2">
  815. <tbody>
  816. <row>
  817. <entry><literal>Dims,Ranges</literal></entry>
  818. <entry>Unsigned integral values.</entry>
  819. </row>
  820. <row>
  821. <entry><literal>x</literal></entry>
  822. <entry>An object of type
  823. <literal>template gen_type&lt;Dims,Ranges&gt;::type</literal>.</entry>
  824. </row>
  825. <row>
  826. <entry><literal>i</literal></entry>
  827. <entry>An object of type
  828. <literal>index_range</literal>.</entry>
  829. </row>
  830. <row>
  831. <entry><literal>idx</literal></entry>
  832. <entry>Objects of type <literal>index</literal>.</entry>
  833. </row>
  834. </tbody>
  835. </tgroup>
  836. </table>
  837. <table><title>Associated Types</title>
  838. <tgroup cols="2">
  839. <thead>
  840. <row>
  841. <entry>Type</entry>
  842. <entry>Description</entry>
  843. </row>
  844. </thead>
  845. <tbody>
  846. <row>
  847. <entry><literal>index</literal></entry>
  848. <entry>This is a signed integral type. It is used to
  849. specify degenerate dimensions.</entry>
  850. </row>
  851. <row>
  852. <entry><literal>size_type</literal></entry>
  853. <entry>This is an unsigned integral type. It is used to
  854. report the size of the range an <literal>index_range</literal>
  855. represents.</entry>
  856. </row>
  857. <row>
  858. <entry>
  859. <literal>template gen_type::&lt;Dims,Ranges&gt;::type</literal></entry>
  860. <entry>This type generator names the result of
  861. <literal>Dims</literal> chained calls to
  862. <literal>index_gen::operator[]</literal>. The
  863. <literal>Ranges</literal> parameter is determined by the number of
  864. degenerate ranges specified (i.e. calls to
  865. <literal>operator[](index)</literal>). Note that
  866. <classname>index_gen</classname> and
  867. <classname>gen_type&lt;0,0&gt;::type</classname> are the same type.</entry>
  868. </row>
  869. </tbody>
  870. </tgroup>
  871. </table>
  872. <table><title>Valid Expressions</title>
  873. <tgroup cols="3">
  874. <thead>
  875. <row>
  876. <entry>Expression</entry>
  877. <entry>Return type</entry>
  878. <entry>Semantics</entry>
  879. </row>
  880. </thead>
  881. <tbody>
  882. <row>
  883. <entry><literal>index_gen()</literal></entry>
  884. <entry><literal>gen_type&lt;0,0&gt;::type</literal></entry>
  885. <entry>This constructs an <literal>index_gen</literal>
  886. object. This object can then be used to generate tuples of
  887. <literal>index_range</literal> values.</entry>
  888. </row>
  889. <row>
  890. <entry><literal>x[i]</literal></entry>
  891. <entry><literal>gen_type&lt;Dims+1,Ranges+1&gt;::type</literal>
  892. </entry>
  893. <entry>Returns a new object containing all previous
  894. <classname>index_range</classname> objects in addition to
  895. <literal>i.</literal> Chained calls to
  896. <function>operator[]</function> are the means by which
  897. <classname>index_range</classname> objects are aggregated.</entry>
  898. </row>
  899. <row>
  900. <entry><literal>x[idx]</literal></entry>
  901. <entry><literal>gen_type&lt;Dims,Ranges+1&gt;::type</literal>
  902. </entry>
  903. <entry>Returns a new object containing all previous
  904. <classname>index_range</classname> objects in addition to a degenerate
  905. range, <literal>index_range(idx,idx).</literal> Note that this is NOT
  906. equivalent to <literal>x[index_range(idx,idx)].</literal>, which will
  907. return an object of type
  908. <literal>gen_type&lt;Dims+1,Ranges+1&gt;::type</literal>.
  909. </entry>
  910. </row>
  911. </tbody>
  912. </tgroup>
  913. </table>
  914. </sect3>
  915. </sect2>
  916. <sect2>
  917. <title>Models</title>
  918. <itemizedlist>
  919. <listitem> <literal>multi_array</literal> </listitem>
  920. <listitem> <literal>multi_array_ref</literal> </listitem>
  921. <listitem> <literal>const_multi_array_ref</literal> </listitem>
  922. <listitem>
  923. <literal>template array_view&lt;Dims&gt;::type</literal>
  924. </listitem>
  925. <listitem>
  926. <literal>template const_array_view&lt;Dims&gt;::type</literal>
  927. </listitem>
  928. <listitem>
  929. <literal>template subarray&lt;Dims&gt;::type</literal>
  930. </listitem>
  931. <listitem>
  932. <literal>template const_subarray&lt;Dims&gt;::type</literal>
  933. </listitem>
  934. </itemizedlist>
  935. </sect2>
  936. </sect1>