You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2458 lines
101 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/containers/fixed_array.hpp
  3. *
  4. * Purpose: Contains the fixed_array_1d, fixed_array_2d, fixed_array_3d,
  5. * fixed_array_4d template classes.
  6. *
  7. * Created: 4th August 1998
  8. * Updated: 10th August 2009
  9. *
  10. * Thanks to: Neal Becker for suggesting the uninitialised mode,
  11. * requesting the function call operator, and for requesting
  12. * the with-allocator constructor overloads.
  13. *
  14. * Thorsten Ottosen for suggesting swap() and mutating data(),
  15. * and for providing suggested implementations.
  16. *
  17. * Home: http://stlsoft.org/
  18. *
  19. * Copyright (c) 1998-2009, Matthew Wilson and Synesis Software
  20. * All rights reserved.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions are
  24. * met:
  25. *
  26. * - Redistributions of source code must retain the above copyright notice,
  27. * this list of conditions and the following disclaimer.
  28. * - Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the
  32. * names of any contributors may be used to endorse or promote products
  33. * derived from this software without specific prior written permission.
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  36. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  37. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  39. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  40. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  41. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  42. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  43. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  44. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46. *
  47. * ////////////////////////////////////////////////////////////////////// */
  48. /** \file stlsoft/containers/fixed_array.hpp
  49. *
  50. * \brief [C++ only] Definition of the stlsoft::fixed_array_1d,
  51. * stlsoft::fixed_array_2d, stlsoft::fixed_array_3d, and
  52. * stlsoft::fixed_array_4d multidimensional array class templates
  53. * (\ref group__library__containers "Containers" Library).
  54. */
  55. #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY
  56. #define STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY
  57. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  58. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY_MAJOR 4
  59. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY_MINOR 9
  60. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY_REVISION 5
  61. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY_EDIT 191
  62. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  63. /* /////////////////////////////////////////////////////////////////////////
  64. * Compatibility
  65. */
  66. /*
  67. [Incompatibilies-start]
  68. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  69. STLSOFT_COMPILER_IS_WATCOM:
  70. [Incompatibilies-end]
  71. */
  72. /* /////////////////////////////////////////////////////////////////////////
  73. * Includes
  74. */
  75. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  76. # include <stlsoft/stlsoft.h>
  77. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  78. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  79. _MSC_VER < 1200
  80. # error stlsoft/containers/fixed_array.hpp is not compatible with Visual C++ 5.0 or earlier
  81. #endif /* compiler */
  82. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
  83. # include <stlsoft/memory/allocator_selector.hpp>
  84. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
  85. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  86. # include <stlsoft/util/std/iterator_helper.hpp>
  87. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  88. #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES
  89. # include <stlsoft/containers/util/array_policies.hpp> // for stlsoft::do_construction()
  90. #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES */
  91. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
  92. # include <stlsoft/meta/capabilities.hpp>
  93. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES */
  94. #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
  95. # include <stlsoft/collections/util/collections.hpp>
  96. #endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
  97. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
  98. # include <stlsoft/util/std_swap.hpp>
  99. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
  100. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  101. defined(STLSOFT_CF_STD_LIBRARY_IS_STLPORT)
  102. # ifndef STLSOFT_INCL_STRING
  103. # define STLSOFT_INCL_STRING
  104. # include <string> // for std::string - sigh!
  105. # endif /* !STLSOFT_INCL_STRING */
  106. #endif /* compiler */
  107. #ifndef STLSOFT_INCL_STDEXCEPT
  108. # define STLSOFT_INCL_STDEXCEPT
  109. # include <stdexcept> // for std::out_of_range
  110. #endif /* !STLSOFT_INCL_STDEXCEPT */
  111. /* /////////////////////////////////////////////////////////////////////////
  112. * Namespace
  113. */
  114. #ifndef _STLSOFT_NO_NAMESPACE
  115. namespace stlsoft
  116. {
  117. #endif /* _STLSOFT_NO_NAMESPACE */
  118. /* /////////////////////////////////////////////////////////////////////////
  119. * Forward declarations
  120. */
  121. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  122. template< ss_typename_param_k T
  123. , ss_typename_param_k A
  124. , ss_typename_param_k P
  125. , ss_bool_t R
  126. >
  127. class fixed_array_1d;
  128. template< ss_typename_param_k T
  129. , ss_typename_param_k A
  130. , ss_typename_param_k P
  131. , ss_bool_t R
  132. >
  133. class fixed_array_2d;
  134. template< ss_typename_param_k T
  135. , ss_typename_param_k A
  136. , ss_typename_param_k P
  137. , ss_bool_t R
  138. >
  139. class fixed_array_3d;
  140. template< ss_typename_param_k T
  141. , ss_typename_param_k A
  142. , ss_typename_param_k P
  143. , ss_bool_t R
  144. >
  145. class fixed_array_4d;
  146. template< ss_typename_param_k T
  147. , ss_typename_param_k A
  148. , ss_typename_param_k P
  149. , ss_bool_t R
  150. >
  151. class fixed_array_5d;
  152. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  153. /* /////////////////////////////////////////////////////////////////////////
  154. * Classes
  155. */
  156. /** \brief 1 dimensional fixed array
  157. *
  158. * \ingroup group__library__containers
  159. *
  160. * \param T The value type
  161. * \param A The allocator type
  162. * \param P The construction policy type
  163. */
  164. template< ss_typename_param_k T
  165. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  166. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
  167. , ss_typename_param_k P = do_construction<T>
  168. , ss_bool_t R = true
  169. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  170. , ss_typename_param_k A
  171. , ss_typename_param_k P
  172. , ss_typename_param_k R
  173. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  174. >
  175. // class fixed_array_1d
  176. class fixed_array_1d
  177. : protected A
  178. , public stl_collection_tag
  179. {
  180. public:
  181. typedef fixed_array_1d<T, A, P, R> class_type;
  182. typedef T dimension_element_type;
  183. typedef /* const */ dimension_element_type const_dimension_element_type;
  184. typedef A allocator_type;
  185. typedef T value_type;
  186. typedef value_type& reference;
  187. typedef value_type const& const_reference;
  188. typedef value_type* pointer;
  189. typedef value_type const* const_pointer;
  190. typedef ss_size_t size_type;
  191. typedef ss_size_t index_type;
  192. typedef ss_ptrdiff_t difference_type;
  193. typedef ss_bool_t bool_type;
  194. typedef
  195. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  196. ss_typename_type_k
  197. #endif /* compiler */
  198. pointer_iterator < value_type
  199. , pointer
  200. , reference
  201. >::type iterator;
  202. typedef
  203. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  204. ss_typename_type_k
  205. #endif /* compiler */
  206. pointer_iterator < value_type const
  207. , const_pointer
  208. , const_reference
  209. >::type const_iterator;
  210. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  211. typedef reverse_iterator_base < iterator
  212. , value_type
  213. , reference
  214. , pointer
  215. , difference_type
  216. > reverse_iterator;
  217. typedef const_reverse_iterator_base < const_iterator
  218. , value_type const
  219. , const_reference
  220. , const_pointer
  221. , difference_type
  222. > const_reverse_iterator;
  223. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  224. // Construction
  225. private:
  226. fixed_array_1d(T *data, index_type d0);
  227. public:
  228. ss_explicit_k fixed_array_1d(index_type d0);
  229. fixed_array_1d(index_type d0, allocator_type const& ator);
  230. fixed_array_1d(index_type d0, value_type const& t);
  231. fixed_array_1d(index_type d0, value_type const& t, allocator_type const& ator);
  232. fixed_array_1d(class_type const& rhs);
  233. ~fixed_array_1d() stlsoft_throw_0();
  234. allocator_type get_allocator() const;
  235. void swap(class_type& rhs) stlsoft_throw_0();
  236. // Access
  237. public:
  238. reference at(index_type i0);
  239. const_reference at(index_type i0) const;
  240. reference at_unchecked(index_type i0);
  241. const_reference at_unchecked(index_type i0) const;
  242. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  243. reference operator ()(index_type i0);
  244. const_reference operator ()(index_type i0) const;
  245. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  246. reference operator [](index_type i0);
  247. const_reference operator [](index_type i0) const;
  248. /// Providing the evil operator, in order to support &ar[0]
  249. // pointer operator &();
  250. /// Providing the evil operator, in order to support &ar[0]
  251. // const_pointer operator &() const;
  252. reference front();
  253. reference back();
  254. const_reference front() const;
  255. const_reference back() const;
  256. // State
  257. public:
  258. index_type dimension0() const;
  259. index_type size() const;
  260. bool_type empty() const;
  261. static size_type max_size();
  262. // Iteration
  263. public:
  264. iterator begin();
  265. iterator end();
  266. const_iterator begin() const;
  267. const_iterator end() const;
  268. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  269. reverse_iterator rbegin();
  270. reverse_iterator rend();
  271. const_reverse_iterator rbegin() const;
  272. const_reverse_iterator rend() const;
  273. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  274. // Access
  275. public:
  276. pointer data();
  277. const_pointer data() const;
  278. // Implementation
  279. private:
  280. pointer allocate_(size_type n);
  281. void deallocate_(pointer p, size_type n);
  282. pointer data_();
  283. index_type calc_index_(index_type i0) const;
  284. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  285. allocator_type& get_allocator_();
  286. // Members
  287. private:
  288. T* m_data;
  289. index_type m_d0;
  290. friend class fixed_array_2d<T, A, P, true>;
  291. friend class fixed_array_2d<T, A, P, false>;
  292. // Not to be implemented
  293. private:
  294. class_type const& operator =(class_type const& rhs);
  295. };
  296. /** \brief 2 dimensional fixed array
  297. *
  298. * \ingroup group__library__containers
  299. *
  300. * \param T The value type
  301. * \param A The allocator type
  302. * \param P The construction policy type
  303. */
  304. template< ss_typename_param_k T
  305. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  306. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
  307. , ss_typename_param_k P = do_construction<T>
  308. , ss_bool_t R = true
  309. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  310. , ss_typename_param_k A
  311. , ss_typename_param_k P
  312. , ss_bool_t R
  313. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  314. >
  315. // class fixed_array_2d
  316. class fixed_array_2d
  317. : protected A
  318. , public stl_collection_tag
  319. {
  320. public:
  321. typedef fixed_array_2d<T, A, P, R> class_type;
  322. typedef fixed_array_1d<T, A, P, false> dimension_element_type;
  323. typedef /* const */ dimension_element_type const_dimension_element_type;
  324. typedef A allocator_type;
  325. typedef T value_type;
  326. typedef value_type& reference;
  327. typedef value_type const& const_reference;
  328. typedef value_type* pointer;
  329. typedef value_type const* const_pointer;
  330. typedef ss_size_t size_type;
  331. typedef ss_size_t index_type;
  332. typedef ss_ptrdiff_t difference_type;
  333. typedef ss_bool_t bool_type;
  334. typedef
  335. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  336. ss_typename_type_k
  337. #endif /* compiler */
  338. pointer_iterator < value_type
  339. , pointer
  340. , reference
  341. >::type iterator;
  342. typedef
  343. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  344. ss_typename_type_k
  345. #endif /* compiler */
  346. pointer_iterator < value_type const
  347. , const_pointer
  348. , const_reference
  349. >::type const_iterator;
  350. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  351. typedef reverse_iterator_base < iterator
  352. , value_type
  353. , reference
  354. , pointer
  355. , difference_type
  356. > reverse_iterator;
  357. typedef const_reverse_iterator_base < const_iterator
  358. , value_type const
  359. , const_reference
  360. , const_pointer
  361. , difference_type
  362. > const_reverse_iterator;
  363. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  364. // Construction
  365. private:
  366. fixed_array_2d(T *data, index_type d0, index_type d1);
  367. public:
  368. fixed_array_2d(index_type d0, index_type d1);
  369. fixed_array_2d(index_type d0, index_type d1, allocator_type const& ator);
  370. fixed_array_2d(index_type d0, index_type d1, value_type const& t);
  371. fixed_array_2d(index_type d0, index_type d1, value_type const& t, allocator_type const& ator);
  372. fixed_array_2d(class_type const& rhs);
  373. ~fixed_array_2d() stlsoft_throw_0();
  374. allocator_type get_allocator() const;
  375. void swap(class_type& rhs) stlsoft_throw_0();
  376. // Access
  377. public:
  378. reference at(index_type i0, index_type i1);
  379. const_reference at(index_type i0, index_type i1) const;
  380. reference at_unchecked(index_type i0, index_type i1);
  381. const_reference at_unchecked(index_type i0, index_type i1) const;
  382. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  383. reference operator ()(index_type i0, index_type i1);
  384. const_reference operator ()(index_type i0, index_type i1) const;
  385. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  386. dimension_element_type at(index_type i0);
  387. const_dimension_element_type at(index_type i0) const;
  388. dimension_element_type at_unchecked(index_type i0);
  389. const_dimension_element_type at_unchecked(index_type i0) const;
  390. dimension_element_type operator [](index_type i0);
  391. const_dimension_element_type operator [](index_type i0) const;
  392. /// A reference to the first element in the array
  393. reference front();
  394. reference back();
  395. const_reference front() const;
  396. const_reference back() const;
  397. // State
  398. public:
  399. index_type dimension0() const;
  400. index_type dimension1() const;
  401. index_type size() const;
  402. bool_type empty() const;
  403. static size_type max_size();
  404. // Iteration
  405. public:
  406. iterator begin();
  407. iterator end();
  408. const_iterator begin() const;
  409. const_iterator end() const;
  410. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  411. reverse_iterator rbegin();
  412. reverse_iterator rend();
  413. const_reverse_iterator rbegin() const;
  414. const_reverse_iterator rend() const;
  415. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  416. // Access
  417. public:
  418. pointer data();
  419. const_pointer data() const;
  420. // Implementation
  421. private:
  422. pointer allocate_(size_type n);
  423. void deallocate_(pointer p, size_type n);
  424. pointer data_();
  425. index_type calc_index_(index_type i0, index_type i1) const;
  426. void range_check_(index_type i0, index_type i1) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  427. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  428. allocator_type& get_allocator_();
  429. // Members
  430. private:
  431. T* m_data;
  432. index_type m_d0;
  433. index_type m_d1;
  434. size_type m_size;
  435. friend class fixed_array_3d<T, A, P, true>;
  436. friend class fixed_array_3d<T, A, P, false>;
  437. // Not to be implemented
  438. private:
  439. class_type const& operator =(class_type const& rhs);
  440. };
  441. /** \brief 3 dimensional fixed array
  442. *
  443. * \ingroup group__library__containers
  444. *
  445. * \param T The value type
  446. * \param A The allocator type
  447. * \param P The construction policy type
  448. */
  449. template< ss_typename_param_k T
  450. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  451. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
  452. , ss_typename_param_k P = do_construction<T>
  453. , ss_bool_t R = true
  454. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  455. , ss_typename_param_k A
  456. , ss_typename_param_k P
  457. , ss_bool_t R
  458. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  459. >
  460. // class fixed_array_3d
  461. class fixed_array_3d
  462. : protected A
  463. , public stl_collection_tag
  464. {
  465. public:
  466. typedef fixed_array_3d<T, A, P, R> class_type;
  467. typedef fixed_array_2d<T, A, P, false> dimension_element_type;
  468. typedef /* const */ dimension_element_type const_dimension_element_type;
  469. typedef A allocator_type;
  470. typedef T value_type;
  471. typedef value_type& reference;
  472. typedef value_type const& const_reference;
  473. typedef value_type* pointer;
  474. typedef value_type const* const_pointer;
  475. typedef ss_size_t size_type;
  476. typedef ss_size_t index_type;
  477. typedef ss_ptrdiff_t difference_type;
  478. typedef ss_bool_t bool_type;
  479. typedef
  480. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  481. ss_typename_type_k
  482. #endif /* compiler */
  483. pointer_iterator < value_type
  484. , pointer
  485. , reference
  486. >::type iterator;
  487. typedef
  488. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  489. ss_typename_type_k
  490. #endif /* compiler */
  491. pointer_iterator < value_type const
  492. , const_pointer
  493. , const_reference
  494. >::type const_iterator;
  495. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  496. typedef reverse_iterator_base < iterator
  497. , value_type
  498. , reference
  499. , pointer
  500. , difference_type
  501. > reverse_iterator;
  502. typedef const_reverse_iterator_base < const_iterator
  503. , value_type const
  504. , const_reference
  505. , const_pointer
  506. , difference_type
  507. > const_reverse_iterator;
  508. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  509. // Construction
  510. private:
  511. fixed_array_3d(pointer data, index_type d0, index_type d1, index_type d2);
  512. public:
  513. fixed_array_3d(index_type d0, index_type d1, index_type d2);
  514. fixed_array_3d(index_type d0, index_type d1, index_type d2, allocator_type const& ator);
  515. fixed_array_3d(index_type d0, index_type d1, index_type d2, value_type const& t);
  516. fixed_array_3d(index_type d0, index_type d1, index_type d2, value_type const& t, allocator_type const& ator);
  517. fixed_array_3d(class_type const& rhs);
  518. ~fixed_array_3d() stlsoft_throw_0();
  519. allocator_type get_allocator() const;
  520. void swap(class_type& rhs) stlsoft_throw_0();
  521. // Access
  522. public:
  523. reference at(index_type i0, index_type i1, index_type i2);
  524. const_reference at(index_type i0, index_type i1, index_type i3) const;
  525. reference at_unchecked(index_type i0, index_type i1, index_type i2);
  526. const_reference at_unchecked(index_type i0, index_type i1, index_type i2) const;
  527. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  528. reference operator ()(index_type i0, index_type i1, index_type i2);
  529. const_reference operator ()(index_type i0, index_type i1, index_type i2) const;
  530. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  531. dimension_element_type at(index_type i0);
  532. const_dimension_element_type at(index_type i0) const;
  533. dimension_element_type at_unchecked(index_type i0);
  534. const_dimension_element_type at_unchecked(index_type i0) const;
  535. dimension_element_type operator [](index_type i0);
  536. const_dimension_element_type operator [](index_type i0) const;
  537. reference front();
  538. reference back();
  539. const_reference front() const;
  540. const_reference back() const;
  541. // State
  542. public:
  543. index_type dimension0() const;
  544. index_type dimension1() const;
  545. index_type dimension2() const;
  546. index_type size() const;
  547. bool_type empty() const;
  548. static size_type max_size();
  549. // Iteration
  550. public:
  551. iterator begin();
  552. iterator end();
  553. const_iterator begin() const;
  554. const_iterator end() const;
  555. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  556. reverse_iterator rbegin();
  557. reverse_iterator rend();
  558. const_reverse_iterator rbegin() const;
  559. const_reverse_iterator rend() const;
  560. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  561. // Access
  562. public:
  563. pointer data();
  564. const_pointer data() const;
  565. // Implementation
  566. private:
  567. pointer allocate_(size_type n);
  568. void deallocate_(pointer p, size_type n);
  569. pointer data_();
  570. index_type calc_index_(index_type i0, index_type i1, index_type i2) const;
  571. void range_check_(index_type i0, index_type i1, index_type i2) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  572. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  573. allocator_type& get_allocator_();
  574. // Members
  575. private:
  576. T* m_data;
  577. index_type m_d0;
  578. index_type m_d1;
  579. index_type m_d2;
  580. friend class fixed_array_4d<T, A, P, true>;
  581. friend class fixed_array_4d<T, A, P, false>;
  582. // Not to be implemented
  583. private:
  584. class_type const& operator =(class_type const& rhs);
  585. };
  586. /** \brief 4 dimensional fixed array
  587. *
  588. * \ingroup group__library__containers
  589. *
  590. * \param T The value type
  591. * \param A The allocator type
  592. * \param P The construction policy type
  593. */
  594. template< ss_typename_param_k T
  595. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  596. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
  597. , ss_typename_param_k P = do_construction<T>
  598. , ss_bool_t R = true
  599. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  600. , ss_typename_param_k A
  601. , ss_typename_param_k P
  602. , ss_bool_t R
  603. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  604. >
  605. // class fixed_array_4d
  606. class fixed_array_4d
  607. : protected A
  608. , public stl_collection_tag
  609. {
  610. public:
  611. typedef fixed_array_4d<T, A, P, R> class_type;
  612. typedef fixed_array_3d<T, A, P, false> dimension_element_type;
  613. typedef /* const */ dimension_element_type const_dimension_element_type;
  614. typedef A allocator_type;
  615. typedef T value_type;
  616. typedef value_type& reference;
  617. typedef value_type const& const_reference;
  618. typedef value_type* pointer;
  619. typedef value_type const* const_pointer;
  620. typedef ss_size_t size_type;
  621. typedef ss_size_t index_type;
  622. typedef ss_ptrdiff_t difference_type;
  623. typedef ss_bool_t bool_type;
  624. typedef
  625. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  626. ss_typename_type_k
  627. #endif /* compiler */
  628. pointer_iterator < value_type
  629. , pointer
  630. , reference
  631. >::type iterator;
  632. typedef
  633. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  634. ss_typename_type_k
  635. #endif /* compiler */
  636. pointer_iterator < value_type const
  637. , const_pointer
  638. , const_reference
  639. >::type const_iterator;
  640. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  641. typedef reverse_iterator_base < iterator
  642. , value_type
  643. , reference
  644. , pointer
  645. , difference_type
  646. > reverse_iterator;
  647. typedef const_reverse_iterator_base < const_iterator
  648. , value_type const
  649. , const_reference
  650. , const_pointer
  651. , difference_type
  652. > const_reverse_iterator;
  653. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  654. // Construction
  655. private:
  656. fixed_array_4d(T *data, index_type d0, index_type d1, index_type d2, index_type d3);
  657. public:
  658. fixed_array_4d(index_type d0, index_type d1, index_type d2, index_type d3);
  659. fixed_array_4d(index_type d0, index_type d1, index_type d2, index_type d3, allocator_type const& ator);
  660. fixed_array_4d(index_type d0, index_type d1, index_type d2, index_type d3, value_type const& t);
  661. fixed_array_4d(index_type d0, index_type d1, index_type d2, index_type d3, value_type const& t, allocator_type const& ator);
  662. fixed_array_4d(class_type const& rhs);
  663. ~fixed_array_4d() stlsoft_throw_0();
  664. allocator_type get_allocator() const;
  665. void swap(class_type& rhs) stlsoft_throw_0();
  666. // Access
  667. public:
  668. reference at(index_type i0, index_type i1, index_type i2, index_type i3);
  669. const_reference at(index_type i0, index_type i1, index_type i2, index_type i3) const;
  670. reference at_unchecked(index_type i0, index_type i1, index_type i2, index_type i3);
  671. const_reference at_unchecked(index_type i0, index_type i1, index_type i2, index_type i3) const;
  672. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  673. reference operator ()(index_type i0, index_type i1, index_type i2, index_type i3);
  674. const_reference operator ()(index_type i0, index_type i1, index_type i2, index_type i3) const;
  675. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  676. dimension_element_type at(index_type i0);
  677. const_dimension_element_type at(index_type i0) const;
  678. dimension_element_type at_unchecked(index_type i0);
  679. const_dimension_element_type at_unchecked(index_type i0) const;
  680. dimension_element_type operator [](index_type i0);
  681. const_dimension_element_type operator [](index_type i0) const;
  682. reference front();
  683. reference back();
  684. const_reference front() const;
  685. const_reference back() const;
  686. // State
  687. public:
  688. index_type dimension0() const;
  689. index_type dimension1() const;
  690. index_type dimension2() const;
  691. index_type dimension3() const;
  692. index_type size() const;
  693. bool_type empty() const;
  694. static size_type max_size();
  695. // Iteration
  696. public:
  697. iterator begin();
  698. iterator end();
  699. const_iterator begin() const;
  700. const_iterator end() const;
  701. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  702. reverse_iterator rbegin();
  703. reverse_iterator rend();
  704. const_reverse_iterator rbegin() const;
  705. const_reverse_iterator rend() const;
  706. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  707. // Access
  708. public:
  709. pointer data();
  710. const_pointer data() const;
  711. // Implementation
  712. private:
  713. pointer allocate_(size_type n);
  714. void deallocate_(pointer p, size_type n);
  715. pointer data_();
  716. index_type calc_index_(index_type i0, index_type i1, index_type i2, index_type i3) const;
  717. void range_check_(index_type i0, index_type i1, index_type i2, index_type i3) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  718. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  719. allocator_type& get_allocator_();
  720. // Members
  721. private:
  722. T* m_data;
  723. index_type m_d0;
  724. index_type m_d1;
  725. index_type m_d2;
  726. index_type m_d3;
  727. friend class fixed_array_5d<T, A, P, true>;
  728. friend class fixed_array_5d<T, A, P, false>;
  729. // Not to be implemented
  730. private:
  731. class_type const& operator =(class_type const& rhs);
  732. };
  733. ////////////////////////////////////////////////////////////////////////////
  734. // Unit-testing
  735. #ifdef STLSOFT_UNITTEST
  736. # include "./unittest/fixed_array_unittest_.h"
  737. #endif /* STLSOFT_UNITTEST */
  738. /* /////////////////////////////////////////////////////////////////////////
  739. * Implementation
  740. */
  741. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  742. // fixed_array_1d
  743. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  744. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::pointer fixed_array_1d<T, A, P, R>::allocate_(ss_typename_type_k fixed_array_1d<T, A, P, R>::size_type n)
  745. {
  746. allocator_type &ator = *this;
  747. return ator.allocate(n, NULL);
  748. }
  749. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  750. inline void fixed_array_1d<T, A, P, R>::deallocate_(ss_typename_type_k fixed_array_1d<T, A, P, R>::pointer p, ss_typename_type_k fixed_array_1d<T, A, P, R>::size_type n)
  751. {
  752. allocator_type &ator = *this;
  753. ator.deallocate(p, n);
  754. }
  755. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  756. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::pointer fixed_array_1d<T, A, P, R>::data_()
  757. {
  758. return m_data;
  759. }
  760. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  761. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::index_type fixed_array_1d<T, A, P, R>::calc_index_(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0) const
  762. {
  763. return i0;
  764. }
  765. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  766. inline void fixed_array_1d<T, A, P, R>::range_check_(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  767. {
  768. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  769. if(!(i0 < m_d0))
  770. {
  771. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  772. }
  773. #else
  774. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  775. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  776. }
  777. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  778. inline ss_typename_type_k fixed_array_1d<T, A, P, R>::allocator_type& fixed_array_1d<T, A, P, R>::get_allocator_()
  779. {
  780. return *this;
  781. }
  782. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  783. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(T* src, ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type d0)
  784. : m_data(src)
  785. , m_d0(d0)
  786. {
  787. STLSOFT_STATIC_ASSERT(!R);
  788. }
  789. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  790. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type d0)
  791. : m_data(allocate_(d0))
  792. , m_d0(d0)
  793. {
  794. STLSOFT_STATIC_ASSERT(R);
  795. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  796. }
  797. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  798. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_1d<T, A, P, R>::allocator_type const& ator)
  799. : allocator_type(ator)
  800. , m_data(allocate_(d0))
  801. , m_d0(d0)
  802. {
  803. STLSOFT_STATIC_ASSERT(R);
  804. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  805. }
  806. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  807. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type d0, value_type const& t)
  808. : m_data(allocate_(d0))
  809. , m_d0(d0)
  810. {
  811. STLSOFT_STATIC_ASSERT(R);
  812. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  813. }
  814. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  815. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type d0, value_type const& t, ss_typename_type_k fixed_array_1d<T, A, P, R>::allocator_type const& ator)
  816. : allocator_type(ator)
  817. , m_data(allocate_(d0))
  818. , m_d0(d0)
  819. {
  820. STLSOFT_STATIC_ASSERT(R);
  821. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  822. }
  823. #ifdef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  824. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  825. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(fixed_array_1d<T, A, P, R> const& rhs)
  826. : m_data(R ? allocate_(rhs.dimension0()) : rhs.m_data)
  827. , m_d0(rhs.dimension0())
  828. {
  829. if(R)
  830. {
  831. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  832. }
  833. }
  834. #else /* ? STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  835. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  836. inline fixed_array_1d<T, A, P, R>::fixed_array_1d(fixed_array_1d<T, A, P, R> const& rhs)
  837. : m_data(allocate_(rhs.dimension0()))
  838. , m_d0(rhs.dimension0())
  839. {
  840. STLSOFT_STATIC_ASSERT(R);
  841. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  842. }
  843. #endif /* STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  844. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  845. inline fixed_array_1d<T, A, P, R>::~fixed_array_1d() stlsoft_throw_0()
  846. {
  847. if(R)
  848. {
  849. array_range_initialiser<T, A, P>::destroy(*this, data_(), size());
  850. deallocate_(m_data, size());
  851. }
  852. }
  853. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  854. inline ss_typename_type_k fixed_array_1d<T, A, P, R>::allocator_type fixed_array_1d<T, A, P, R>::get_allocator() const
  855. {
  856. return *this;
  857. }
  858. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  859. inline void fixed_array_1d<T, A, P, R>::swap(ss_typename_type_k fixed_array_1d<T, A, P, R>::class_type& rhs) stlsoft_throw_0()
  860. {
  861. // We don't need to do any construct and swap here, because all the
  862. // variables that are being swapped are simple types (integers and
  863. // pointers).
  864. std_swap(get_allocator_(), rhs.get_allocator_());
  865. std_swap(m_data, rhs.m_data);
  866. std_swap(m_d0, rhs.m_d0);
  867. }
  868. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  869. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reference fixed_array_1d<T, A, P, R>::at(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0)
  870. {
  871. range_check_(i0);
  872. return m_data[i0];
  873. }
  874. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  875. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reference fixed_array_1d<T, A, P, R>::at(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0) const
  876. {
  877. range_check_(i0);
  878. return m_data[i0];
  879. }
  880. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  881. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reference fixed_array_1d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0)
  882. {
  883. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  884. return m_data[i0];
  885. }
  886. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  887. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reference fixed_array_1d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0) const
  888. {
  889. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  890. return m_data[i0];
  891. }
  892. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  893. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  894. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reference fixed_array_1d<T, A, P, R>::operator ()(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0)
  895. {
  896. return at_unchecked(i0);
  897. }
  898. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  899. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reference fixed_array_1d<T, A, P, R>::operator ()(ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0) const
  900. {
  901. return at_unchecked(i0);
  902. }
  903. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  904. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  905. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reference fixed_array_1d<T, A, P, R>::operator [](ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0)
  906. {
  907. return at_unchecked(i0);
  908. }
  909. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  910. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reference fixed_array_1d<T, A, P, R>::operator [](ss_typename_type_k fixed_array_1d<T, A, P, R>::index_type i0) const
  911. {
  912. return at_unchecked(i0);
  913. }
  914. #if 0
  915. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  916. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::pointer fixed_array_1d<T, A, P, R>::operator &()
  917. {
  918. return &m_data[0];
  919. }
  920. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  921. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_pointer fixed_array_1d<T, A, P, R>::operator &() const
  922. {
  923. return &m_data[0];
  924. }
  925. #endif /* 0 */
  926. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  927. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reference fixed_array_1d<T, A, P, R>::front()
  928. {
  929. return at(0);
  930. }
  931. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  932. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reference fixed_array_1d<T, A, P, R>::back()
  933. {
  934. return at(m_d0 - 1);
  935. }
  936. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  937. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reference fixed_array_1d<T, A, P, R>::front() const
  938. {
  939. return at(0);
  940. }
  941. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  942. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reference fixed_array_1d<T, A, P, R>::back() const
  943. {
  944. return at(m_d0 - 1);
  945. }
  946. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  947. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::index_type fixed_array_1d<T, A, P, R>::dimension0() const
  948. {
  949. return m_d0;
  950. }
  951. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  952. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::index_type fixed_array_1d<T, A, P, R>::size() const
  953. {
  954. return m_d0;
  955. }
  956. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  957. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::bool_type fixed_array_1d<T, A, P, R>::empty() const
  958. {
  959. return 0 == size();
  960. }
  961. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  962. inline /* static */ ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::size_type fixed_array_1d<T, A, P, R>::max_size()
  963. {
  964. return static_cast<size_type>(-1) / sizeof(T);
  965. }
  966. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  967. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::iterator fixed_array_1d<T, A, P, R>::begin()
  968. {
  969. return m_data;
  970. }
  971. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  972. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::iterator fixed_array_1d<T, A, P, R>::end()
  973. {
  974. return m_data + size();
  975. }
  976. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  977. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_iterator fixed_array_1d<T, A, P, R>::begin() const
  978. {
  979. return m_data;
  980. }
  981. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  982. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_iterator fixed_array_1d<T, A, P, R>::end() const
  983. {
  984. return m_data + size();
  985. }
  986. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  987. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  988. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reverse_iterator fixed_array_1d<T, A, P, R>::rbegin()
  989. {
  990. return reverse_iterator(end());
  991. }
  992. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  993. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::reverse_iterator fixed_array_1d<T, A, P, R>::rend()
  994. {
  995. return reverse_iterator(begin());
  996. }
  997. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  998. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reverse_iterator fixed_array_1d<T, A, P, R>::rbegin() const
  999. {
  1000. return const_reverse_iterator(end());
  1001. }
  1002. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1003. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_reverse_iterator fixed_array_1d<T, A, P, R>::rend() const
  1004. {
  1005. return const_reverse_iterator(begin());
  1006. }
  1007. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1008. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1009. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::pointer fixed_array_1d<T, A, P, R>::data()
  1010. {
  1011. return m_data;
  1012. }
  1013. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1014. inline ss_typename_type_ret_k fixed_array_1d<T, A, P, R>::const_pointer fixed_array_1d<T, A, P, R>::data() const
  1015. {
  1016. return m_data;
  1017. }
  1018. // fixed_array_2d
  1019. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1020. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::pointer fixed_array_2d<T, A, P, R>::allocate_(ss_typename_type_k fixed_array_2d<T, A, P, R>::size_type n)
  1021. {
  1022. allocator_type &ator = *this;
  1023. return ator.allocate(n, NULL);
  1024. }
  1025. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1026. inline void fixed_array_2d<T, A, P, R>::deallocate_(ss_typename_type_k fixed_array_2d<T, A, P, R>::pointer p, ss_typename_type_k fixed_array_2d<T, A, P, R>::size_type n)
  1027. {
  1028. allocator_type &ator = *this;
  1029. ator.deallocate(p, n);
  1030. }
  1031. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1032. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::pointer fixed_array_2d<T, A, P, R>::data_()
  1033. {
  1034. return m_data;
  1035. }
  1036. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1037. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::index_type fixed_array_2d<T, A, P, R>::calc_index_(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1) const
  1038. {
  1039. return (i0 * m_d1) + i1;
  1040. }
  1041. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1042. inline void fixed_array_2d<T, A, P, R>::range_check_(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1043. {
  1044. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1045. if( !(i0 < m_d0) ||
  1046. !(i1 < m_d1))
  1047. {
  1048. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  1049. }
  1050. #else
  1051. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1));
  1052. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1053. }
  1054. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1055. inline ss_typename_type_k fixed_array_2d<T, A, P, R>::allocator_type& fixed_array_2d<T, A, P, R>::get_allocator_()
  1056. {
  1057. return *this;
  1058. }
  1059. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1060. inline void fixed_array_2d<T, A, P, R>::range_check_(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1061. {
  1062. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1063. if(!(i0 < m_d0))
  1064. {
  1065. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  1066. }
  1067. #else
  1068. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1069. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1070. }
  1071. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1072. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(T* src, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d1)
  1073. : m_data(src)
  1074. , m_d0(d0)
  1075. , m_d1(d1)
  1076. , m_size(d0 * d1)
  1077. {
  1078. STLSOFT_STATIC_ASSERT(!R);
  1079. }
  1080. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1081. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d1)
  1082. : m_data(allocate_(d0 * d1))
  1083. , m_d0(d0)
  1084. , m_d1(d1)
  1085. , m_size(d0 * d1)
  1086. {
  1087. STLSOFT_STATIC_ASSERT(R);
  1088. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  1089. }
  1090. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1091. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d1, ss_typename_type_k fixed_array_2d<T, A, P, R>::allocator_type const& ator)
  1092. : allocator_type(ator)
  1093. , m_data(allocate_(d0 * d1))
  1094. , m_d0(d0)
  1095. , m_d1(d1)
  1096. , m_size(d0 * d1)
  1097. {
  1098. STLSOFT_STATIC_ASSERT(R);
  1099. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  1100. }
  1101. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1102. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d1, value_type const& t)
  1103. : m_data(allocate_(d0 * d1))
  1104. , m_d0(d0)
  1105. , m_d1(d1)
  1106. , m_size(d0 * d1)
  1107. {
  1108. STLSOFT_STATIC_ASSERT(R);
  1109. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  1110. }
  1111. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1112. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type d1, value_type const& t, ss_typename_type_k fixed_array_2d<T, A, P, R>::allocator_type const& ator)
  1113. : allocator_type(ator)
  1114. , m_data(allocate_(d0 * d1))
  1115. , m_d0(d0)
  1116. , m_d1(d1)
  1117. , m_size(d0 * d1)
  1118. {
  1119. STLSOFT_STATIC_ASSERT(R);
  1120. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  1121. }
  1122. #ifdef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  1123. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1124. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(fixed_array_2d<T, A, P, R> const& rhs)
  1125. : m_data(R ? allocate_(rhs.dimension0() * rhs.dimension1()) : rhs.m_data)
  1126. , m_d0(rhs.dimension0())
  1127. , m_d1(rhs.dimension1())
  1128. , m_size(rhs.dimension0() * rhs.dimension1())
  1129. {
  1130. if(R)
  1131. {
  1132. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  1133. }
  1134. }
  1135. #else /* ? STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  1136. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1137. inline fixed_array_2d<T, A, P, R>::fixed_array_2d(fixed_array_2d<T, A, P, R> const& rhs)
  1138. : m_data(allocate_(rhs.dimension0() * rhs.dimension1()))
  1139. , m_d0(rhs.dimension0())
  1140. , m_d1(rhs.dimension1())
  1141. , m_size(rhs.dimension0() * rhs.dimension1())
  1142. {
  1143. STLSOFT_STATIC_ASSERT(R);
  1144. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  1145. }
  1146. #endif /* STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  1147. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1148. inline fixed_array_2d<T, A, P, R>::~fixed_array_2d() stlsoft_throw_0()
  1149. {
  1150. if(R)
  1151. {
  1152. array_range_initialiser<T, A, P>::destroy(*this, data_(), size());
  1153. deallocate_(m_data, size());
  1154. }
  1155. }
  1156. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1157. inline ss_typename_type_k fixed_array_2d<T, A, P, R>::allocator_type fixed_array_2d<T, A, P, R>::get_allocator() const
  1158. {
  1159. return *this;
  1160. }
  1161. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1162. inline void fixed_array_2d<T, A, P, R>::swap(ss_typename_type_k fixed_array_2d<T, A, P, R>::class_type& rhs) stlsoft_throw_0()
  1163. {
  1164. // We don't need to do any construct and swap here, because all the
  1165. // variables that are being swapped are simple types (integers and
  1166. // pointers).
  1167. std_swap(get_allocator_(), rhs.get_allocator_());
  1168. std_swap(m_data, rhs.m_data);
  1169. std_swap(m_d0, rhs.m_d0);
  1170. std_swap(m_d1, rhs.m_d1);
  1171. std_swap(m_size, rhs.m_size);
  1172. }
  1173. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1174. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reference fixed_array_2d<T, A, P, R>::at(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1)
  1175. {
  1176. range_check_(i0, i1);
  1177. return *(m_data + calc_index_(i0, i1));
  1178. }
  1179. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1180. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reference fixed_array_2d<T, A, P, R>::at(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1) const
  1181. {
  1182. range_check_(i0, i1);
  1183. return *(m_data + calc_index_(i0, i1));
  1184. }
  1185. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1186. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reference fixed_array_2d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1)
  1187. {
  1188. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1));
  1189. return *(m_data + calc_index_(i0, i1));
  1190. }
  1191. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1192. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reference fixed_array_2d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1) const
  1193. {
  1194. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1));
  1195. return *(m_data + calc_index_(i0, i1));
  1196. }
  1197. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  1198. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1199. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reference fixed_array_2d<T, A, P, R>::operator ()(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1)
  1200. {
  1201. return at_unchecked(i0, i1);
  1202. }
  1203. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1204. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reference fixed_array_2d<T, A, P, R>::operator ()(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i1) const
  1205. {
  1206. return at_unchecked(i0, i1);
  1207. }
  1208. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  1209. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1210. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::dimension_element_type fixed_array_2d<T, A, P, R>::at(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0)
  1211. {
  1212. range_check_(i0);
  1213. return dimension_element_type(m_data + i0 * m_d1, m_d1);
  1214. }
  1215. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1216. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_dimension_element_type fixed_array_2d<T, A, P, R>::at(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0) const
  1217. {
  1218. range_check_(i0);
  1219. return dimension_element_type(m_data + i0 * m_d1, m_d1);
  1220. }
  1221. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1222. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::dimension_element_type fixed_array_2d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0)
  1223. {
  1224. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1225. return dimension_element_type(m_data + i0 * m_d1, m_d1);
  1226. }
  1227. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1228. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_dimension_element_type fixed_array_2d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0) const
  1229. {
  1230. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1231. return dimension_element_type(m_data + i0 * m_d1, m_d1);
  1232. }
  1233. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1234. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::dimension_element_type fixed_array_2d<T, A, P, R>::operator [](ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0)
  1235. {
  1236. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1237. return dimension_element_type(m_data + i0 * m_d1, m_d1);
  1238. }
  1239. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1240. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_dimension_element_type fixed_array_2d<T, A, P, R>::operator [](ss_typename_type_k fixed_array_2d<T, A, P, R>::index_type i0) const
  1241. {
  1242. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1243. return dimension_element_type(m_data + i0 * m_d1, m_d1);
  1244. }
  1245. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1246. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reference fixed_array_2d<T, A, P, R>::front()
  1247. {
  1248. return at(0, 0);
  1249. }
  1250. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1251. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reference fixed_array_2d<T, A, P, R>::back()
  1252. {
  1253. return at(m_d0 - 1, m_d1 - 1);
  1254. }
  1255. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1256. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reference fixed_array_2d<T, A, P, R>::front() const
  1257. {
  1258. return at(0, 0);
  1259. }
  1260. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1261. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reference fixed_array_2d<T, A, P, R>::back() const
  1262. {
  1263. return at(m_d0 - 1, m_d1 - 1);
  1264. }
  1265. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1266. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::index_type fixed_array_2d<T, A, P, R>::dimension0() const
  1267. {
  1268. return m_d0;
  1269. }
  1270. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1271. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::index_type fixed_array_2d<T, A, P, R>::dimension1() const
  1272. {
  1273. return m_d1;
  1274. }
  1275. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1276. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::index_type fixed_array_2d<T, A, P, R>::size() const
  1277. {
  1278. STLSOFT_ASSERT(m_size == m_d0 * m_d1);
  1279. return m_size;
  1280. }
  1281. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1282. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::bool_type fixed_array_2d<T, A, P, R>::empty() const
  1283. {
  1284. return 0 == size();
  1285. }
  1286. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1287. inline /* static */ ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::size_type fixed_array_2d<T, A, P, R>::max_size()
  1288. {
  1289. return static_cast<size_type>(-1) / sizeof(T);
  1290. }
  1291. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1292. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::iterator fixed_array_2d<T, A, P, R>::begin()
  1293. {
  1294. return m_data;
  1295. }
  1296. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1297. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::iterator fixed_array_2d<T, A, P, R>::end()
  1298. {
  1299. return m_data + size();
  1300. }
  1301. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1302. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_iterator fixed_array_2d<T, A, P, R>::begin() const
  1303. {
  1304. return m_data;
  1305. }
  1306. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1307. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_iterator fixed_array_2d<T, A, P, R>::end() const
  1308. {
  1309. return m_data + size();
  1310. }
  1311. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  1312. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1313. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reverse_iterator fixed_array_2d<T, A, P, R>::rbegin()
  1314. {
  1315. return reverse_iterator(end());
  1316. }
  1317. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1318. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::reverse_iterator fixed_array_2d<T, A, P, R>::rend()
  1319. {
  1320. return reverse_iterator(begin());
  1321. }
  1322. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1323. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reverse_iterator fixed_array_2d<T, A, P, R>::rbegin() const
  1324. {
  1325. return const_reverse_iterator(end());
  1326. }
  1327. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1328. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_reverse_iterator fixed_array_2d<T, A, P, R>::rend() const
  1329. {
  1330. return const_reverse_iterator(begin());
  1331. }
  1332. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1333. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1334. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::pointer fixed_array_2d<T, A, P, R>::data()
  1335. {
  1336. return m_data;
  1337. }
  1338. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1339. inline ss_typename_type_ret_k fixed_array_2d<T, A, P, R>::const_pointer fixed_array_2d<T, A, P, R>::data() const
  1340. {
  1341. return m_data;
  1342. }
  1343. // fixed_array_3d
  1344. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1345. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::pointer fixed_array_3d<T, A, P, R>::allocate_(ss_typename_type_k fixed_array_3d<T, A, P, R>::size_type n)
  1346. {
  1347. allocator_type &ator = *this;
  1348. return ator.allocate(n, NULL);
  1349. }
  1350. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1351. inline void fixed_array_3d<T, A, P, R>::deallocate_(ss_typename_type_k fixed_array_3d<T, A, P, R>::pointer p, ss_typename_type_k fixed_array_3d<T, A, P, R>::size_type n)
  1352. {
  1353. allocator_type &ator = *this;
  1354. ator.deallocate(p, n);
  1355. }
  1356. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1357. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::pointer fixed_array_3d<T, A, P, R>::data_()
  1358. {
  1359. return m_data;
  1360. }
  1361. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1362. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::index_type fixed_array_3d<T, A, P, R>::calc_index_(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2) const
  1363. {
  1364. return ((i0 * m_d1) + i1) * m_d2 + i2;
  1365. }
  1366. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1367. inline void fixed_array_3d<T, A, P, R>::range_check_(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1368. {
  1369. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1370. if( !(i0 < m_d0) ||
  1371. !(i1 < m_d1) ||
  1372. !(i2 < m_d2))
  1373. {
  1374. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  1375. }
  1376. #else
  1377. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1 && i2 < m_d2));
  1378. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1379. }
  1380. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1381. inline ss_typename_type_k fixed_array_3d<T, A, P, R>::allocator_type& fixed_array_3d<T, A, P, R>::get_allocator_()
  1382. {
  1383. return *this;
  1384. }
  1385. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1386. inline void fixed_array_3d<T, A, P, R>::range_check_(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1387. {
  1388. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1389. if(!(i0 < m_d0))
  1390. {
  1391. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  1392. }
  1393. #else
  1394. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1395. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1396. }
  1397. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1398. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(ss_typename_type_k fixed_array_3d<T, A, P, R>::pointer src, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d2)
  1399. : m_data(src)
  1400. , m_d0(d0)
  1401. , m_d1(d1)
  1402. , m_d2(d2)
  1403. {
  1404. STLSOFT_STATIC_ASSERT(!R);
  1405. }
  1406. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1407. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d2)
  1408. : m_data(allocate_(d0 * d1 * d2))
  1409. , m_d0(d0)
  1410. , m_d1(d1)
  1411. , m_d2(d2)
  1412. {
  1413. STLSOFT_STATIC_ASSERT(R);
  1414. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  1415. }
  1416. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1417. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d2, ss_typename_type_k fixed_array_3d<T, A, P, R>::allocator_type const& ator)
  1418. : allocator_type(ator)
  1419. , m_data(allocate_(d0 * d1 * d2))
  1420. , m_d0(d0)
  1421. , m_d1(d1)
  1422. , m_d2(d2)
  1423. {
  1424. STLSOFT_STATIC_ASSERT(R);
  1425. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  1426. }
  1427. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1428. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d2, ss_typename_type_k fixed_array_3d<T, A, P, R>::value_type const& t)
  1429. : m_data(allocate_(d0 * d1 * d2))
  1430. , m_d0(d0)
  1431. , m_d1(d1)
  1432. , m_d2(d2)
  1433. {
  1434. STLSOFT_STATIC_ASSERT(R);
  1435. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  1436. }
  1437. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1438. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type d2, ss_typename_type_k fixed_array_3d<T, A, P, R>::value_type const& t, ss_typename_type_k fixed_array_3d<T, A, P, R>::allocator_type const& ator)
  1439. : allocator_type(ator)
  1440. , m_data(allocate_(d0 * d1 * d2))
  1441. , m_d0(d0)
  1442. , m_d1(d1)
  1443. , m_d2(d2)
  1444. {
  1445. STLSOFT_STATIC_ASSERT(R);
  1446. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  1447. }
  1448. #ifdef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  1449. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1450. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(fixed_array_3d<T, A, P, R> const& rhs)
  1451. : m_data(R ? allocate_(rhs.dimension0() * rhs.dimension1() * rhs.dimension2()) : rhs.m_data)
  1452. , m_d0(rhs.dimension0())
  1453. , m_d1(rhs.dimension1())
  1454. , m_d2(rhs.dimension2())
  1455. {
  1456. if(R)
  1457. {
  1458. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  1459. }
  1460. }
  1461. #else /* ? STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  1462. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1463. inline fixed_array_3d<T, A, P, R>::fixed_array_3d(fixed_array_3d<T, A, P, R> const& rhs)
  1464. : m_data(allocate_(rhs.dimension0() * rhs.dimension1() * rhs.dimension2()))
  1465. , m_d0(rhs.dimension0())
  1466. , m_d1(rhs.dimension1())
  1467. , m_d2(rhs.dimension2())
  1468. {
  1469. STLSOFT_STATIC_ASSERT(R);
  1470. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  1471. }
  1472. #endif /* STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  1473. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1474. inline fixed_array_3d<T, A, P, R>::~fixed_array_3d() stlsoft_throw_0()
  1475. {
  1476. if(R)
  1477. {
  1478. array_range_initialiser<T, A, P>::destroy(*this, data_(), size());
  1479. deallocate_(m_data, size());
  1480. }
  1481. }
  1482. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1483. inline ss_typename_type_k fixed_array_3d<T, A, P, R>::allocator_type fixed_array_3d<T, A, P, R>::get_allocator() const
  1484. {
  1485. return *this;
  1486. }
  1487. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1488. inline void fixed_array_3d<T, A, P, R>::swap(ss_typename_type_k fixed_array_3d<T, A, P, R>::class_type& rhs) stlsoft_throw_0()
  1489. {
  1490. // We don't need to do any construct and swap here, because all the
  1491. // variables that are being swapped are simple types (integers and
  1492. // pointers).
  1493. std_swap(get_allocator_(), rhs.get_allocator_());
  1494. std_swap(m_data, rhs.m_data);
  1495. std_swap(m_d0, rhs.m_d0);
  1496. std_swap(m_d1, rhs.m_d1);
  1497. std_swap(m_d2, rhs.m_d2);
  1498. }
  1499. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1500. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reference fixed_array_3d<T, A, P, R>::at(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2)
  1501. {
  1502. range_check_(i0, i1, i2);
  1503. return *(m_data + calc_index_(i0, i1, i2));
  1504. }
  1505. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1506. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reference fixed_array_3d<T, A, P, R>::at(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2) const
  1507. {
  1508. range_check_(i0, i1, i2);
  1509. return *(m_data + calc_index_(i0, i1, i2));
  1510. }
  1511. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1512. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reference fixed_array_3d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2)
  1513. {
  1514. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1 && i2 < m_d2));
  1515. return *(m_data + calc_index_(i0, i1, i2));
  1516. }
  1517. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1518. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reference fixed_array_3d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2) const
  1519. {
  1520. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1 && i2 < m_d2));
  1521. return *(m_data + calc_index_(i0, i1, i2));
  1522. }
  1523. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  1524. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1525. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reference fixed_array_3d<T, A, P, R>::operator ()(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2)
  1526. {
  1527. return at_unchecked(i0, i1, i2);
  1528. }
  1529. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1530. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reference fixed_array_3d<T, A, P, R>::operator ()(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i1, ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i2) const
  1531. {
  1532. return at_unchecked(i0, i1, i2);
  1533. }
  1534. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  1535. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1536. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::dimension_element_type fixed_array_3d<T, A, P, R>::at(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0)
  1537. {
  1538. range_check_(i0);
  1539. return dimension_element_type(m_data + i0 * m_d1 * m_d2, m_d1, m_d2);
  1540. }
  1541. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1542. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_dimension_element_type fixed_array_3d<T, A, P, R>::at(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0) const
  1543. {
  1544. range_check_(i0);
  1545. return dimension_element_type(m_data + i0 * m_d1 * m_d2, m_d1, m_d2);
  1546. }
  1547. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1548. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::dimension_element_type fixed_array_3d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0)
  1549. {
  1550. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1551. return dimension_element_type(m_data + i0 * m_d1 * m_d2, m_d1, m_d2);
  1552. }
  1553. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1554. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_dimension_element_type fixed_array_3d<T, A, P, R>::at_unchecked(ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0) const
  1555. {
  1556. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1557. return dimension_element_type(m_data + i0 * m_d1 * m_d2, m_d1, m_d2);
  1558. }
  1559. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1560. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::dimension_element_type fixed_array_3d<T, A, P, R>::operator [](ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0)
  1561. {
  1562. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1563. return dimension_element_type(m_data + i0 * m_d1 * m_d2, m_d1, m_d2);
  1564. }
  1565. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1566. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_dimension_element_type fixed_array_3d<T, A, P, R>::operator [](ss_typename_type_k fixed_array_3d<T, A, P, R>::index_type i0) const
  1567. {
  1568. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1569. return dimension_element_type(m_data + i0 * m_d1 * m_d2, m_d1, m_d2);
  1570. }
  1571. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1572. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reference fixed_array_3d<T, A, P, R>::front()
  1573. {
  1574. return at(0, 0, 0);
  1575. }
  1576. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1577. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reference fixed_array_3d<T, A, P, R>::back()
  1578. {
  1579. return at(m_d0 - 1, m_d1 - 1, m_d2 - 1);
  1580. }
  1581. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1582. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reference fixed_array_3d<T, A, P, R>::front() const
  1583. {
  1584. return at(0, 0, 0);
  1585. }
  1586. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1587. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reference fixed_array_3d<T, A, P, R>::back() const
  1588. {
  1589. return at(m_d0 - 1, m_d1 - 1, m_d2 - 1);
  1590. }
  1591. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1592. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::index_type fixed_array_3d<T, A, P, R>::dimension0() const
  1593. {
  1594. return m_d0;
  1595. }
  1596. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1597. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::index_type fixed_array_3d<T, A, P, R>::dimension1() const
  1598. {
  1599. return m_d1;
  1600. }
  1601. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1602. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::index_type fixed_array_3d<T, A, P, R>::dimension2() const
  1603. {
  1604. return m_d2;
  1605. }
  1606. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1607. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::index_type fixed_array_3d<T, A, P, R>::size() const
  1608. {
  1609. return m_d0 * m_d1 * m_d2;
  1610. }
  1611. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1612. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::bool_type fixed_array_3d<T, A, P, R>::empty() const
  1613. {
  1614. return 0 == size();
  1615. }
  1616. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1617. inline /* static */ ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::size_type fixed_array_3d<T, A, P, R>::max_size()
  1618. {
  1619. return static_cast<size_type>(-1) / sizeof(T);
  1620. }
  1621. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1622. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::iterator fixed_array_3d<T, A, P, R>::begin()
  1623. {
  1624. return m_data;
  1625. }
  1626. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1627. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::iterator fixed_array_3d<T, A, P, R>::end()
  1628. {
  1629. return m_data + size();
  1630. }
  1631. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1632. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_iterator fixed_array_3d<T, A, P, R>::begin() const
  1633. {
  1634. return m_data;
  1635. }
  1636. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1637. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_iterator fixed_array_3d<T, A, P, R>::end() const
  1638. {
  1639. return m_data + size();
  1640. }
  1641. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  1642. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1643. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reverse_iterator fixed_array_3d<T, A, P, R>::rbegin()
  1644. {
  1645. return reverse_iterator(end());
  1646. }
  1647. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1648. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::reverse_iterator fixed_array_3d<T, A, P, R>::rend()
  1649. {
  1650. return reverse_iterator(begin());
  1651. }
  1652. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1653. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reverse_iterator fixed_array_3d<T, A, P, R>::rbegin() const
  1654. {
  1655. return const_reverse_iterator(end());
  1656. }
  1657. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1658. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_reverse_iterator fixed_array_3d<T, A, P, R>::rend() const
  1659. {
  1660. return const_reverse_iterator(begin());
  1661. }
  1662. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1663. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1664. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::pointer fixed_array_3d<T, A, P, R>::data()
  1665. {
  1666. return m_data;
  1667. }
  1668. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1669. inline ss_typename_type_ret_k fixed_array_3d<T, A, P, R>::const_pointer fixed_array_3d<T, A, P, R>::data() const
  1670. {
  1671. return m_data;
  1672. }
  1673. // fixed_array_4d
  1674. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1675. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::pointer fixed_array_4d<T, A, P, R>::allocate_(ss_typename_type_k fixed_array_4d<T, A, P, R>::size_type n)
  1676. {
  1677. allocator_type &ator = *this;
  1678. return ator.allocate(n, NULL);
  1679. }
  1680. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1681. inline void fixed_array_4d<T, A, P, R>::deallocate_(ss_typename_type_k fixed_array_4d<T, A, P, R>::pointer p, ss_typename_type_k fixed_array_4d<T, A, P, R>::size_type n)
  1682. {
  1683. allocator_type &ator = *this;
  1684. ator.deallocate(p, n);
  1685. }
  1686. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1687. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::pointer fixed_array_4d<T, A, P, R>::data_()
  1688. {
  1689. return m_data;
  1690. }
  1691. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1692. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::index_type fixed_array_4d<T, A, P, R>::calc_index_(ss_typename_type_k fixed_array_4d<T, A, P, R>::index_type i0, index_type i1, index_type i2, index_type i3) const
  1693. {
  1694. return (((i0 * m_d1) + i1) * m_d2 + i2) * m_d3 + i3;
  1695. }
  1696. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1697. inline void fixed_array_4d<T, A, P, R>::range_check_(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1698. {
  1699. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1700. if( !(i0 < m_d0) ||
  1701. !(i1 < m_d1) ||
  1702. !(i2 < m_d2) ||
  1703. !(i3 < m_d3))
  1704. {
  1705. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  1706. }
  1707. #else
  1708. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1 && i2 < m_d2 && i3 < m_d3));
  1709. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1710. }
  1711. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1712. inline ss_typename_type_k fixed_array_4d<T, A, P, R>::allocator_type& fixed_array_4d<T, A, P, R>::get_allocator_()
  1713. {
  1714. return *this;
  1715. }
  1716. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1717. inline void fixed_array_4d<T, A, P, R>::range_check_(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1718. {
  1719. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1720. if(!(i0 < m_d0))
  1721. {
  1722. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("fixed array index out of range"));
  1723. }
  1724. #else
  1725. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1726. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1727. }
  1728. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1729. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(T* src, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d3)
  1730. : m_data(src)
  1731. , m_d0(d0)
  1732. , m_d1(d1)
  1733. , m_d2(d2)
  1734. , m_d3(d3)
  1735. {
  1736. STLSOFT_STATIC_ASSERT(!R);
  1737. }
  1738. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1739. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d3)
  1740. : m_data(allocate_(d0 * d1 * d2 * d3))
  1741. , m_d0(d0)
  1742. , m_d1(d1)
  1743. , m_d2(d2)
  1744. , m_d3(d3)
  1745. {
  1746. STLSOFT_STATIC_ASSERT(R);
  1747. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  1748. }
  1749. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1750. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d3, ss_typename_param_k fixed_array_4d<T, A, P, R>::allocator_type const& ator)
  1751. : allocator_type(ator)
  1752. , m_data(allocate_(d0 * d1 * d2 * d3))
  1753. , m_d0(d0)
  1754. , m_d1(d1)
  1755. , m_d2(d2)
  1756. , m_d3(d3)
  1757. {
  1758. STLSOFT_STATIC_ASSERT(R);
  1759. array_range_initialiser<T, A, P>::construct(*this, data_(), size());
  1760. }
  1761. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1762. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d3, ss_typename_param_k fixed_array_4d<T, A, P, R>::value_type const& t)
  1763. : m_data(allocate_(d0 * d1 * d2 * d3))
  1764. , m_d0(d0)
  1765. , m_d1(d1)
  1766. , m_d2(d2)
  1767. , m_d3(d3)
  1768. {
  1769. STLSOFT_STATIC_ASSERT(R);
  1770. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  1771. }
  1772. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1773. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type d3, ss_typename_param_k fixed_array_4d<T, A, P, R>::value_type const& t, ss_typename_param_k fixed_array_4d<T, A, P, R>::allocator_type const& ator)
  1774. : allocator_type(ator)
  1775. , m_data(allocate_(d0 * d1 * d2 * d3))
  1776. , m_d0(d0)
  1777. , m_d1(d1)
  1778. , m_d2(d2)
  1779. , m_d3(d3)
  1780. {
  1781. STLSOFT_STATIC_ASSERT(R);
  1782. array_range_initialiser<T, A, P>::construct(*this, data_(), size(), t);
  1783. }
  1784. #ifdef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  1785. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1786. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(fixed_array_4d<T, A, P, R> const& rhs)
  1787. : m_data(R ? allocate_(rhs.dimension0() * rhs.dimension1() * rhs.dimension2() * rhs.dimension3()) : rhs.m_data)
  1788. , m_d0(rhs.dimension0())
  1789. , m_d1(rhs.dimension1())
  1790. , m_d2(rhs.dimension2())
  1791. , m_d3(rhs.dimension3())
  1792. {
  1793. if(R)
  1794. {
  1795. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  1796. }
  1797. }
  1798. #else /* ? STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  1799. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1800. inline fixed_array_4d<T, A, P, R>::fixed_array_4d(fixed_array_4d<T, A, P, R> const& rhs)
  1801. : m_data(allocate_(rhs.dimension0() * rhs.dimension1() * rhs.dimension2() * rhs.dimension3()))
  1802. , m_d0(rhs.dimension0())
  1803. , m_d1(rhs.dimension1())
  1804. , m_d2(rhs.dimension2())
  1805. , m_d3(rhs.dimension3())
  1806. {
  1807. STLSOFT_STATIC_ASSERT(R);
  1808. array_range_initialiser<T, A, P>::copy_construct(*this, data_(), rhs.data(), size());
  1809. }
  1810. #endif /* STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  1811. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1812. inline fixed_array_4d<T, A, P, R>::~fixed_array_4d() stlsoft_throw_0()
  1813. {
  1814. if(R)
  1815. {
  1816. array_range_initialiser<T, A, P>::destroy(*this, data_(), size());
  1817. deallocate_(m_data, size());
  1818. }
  1819. }
  1820. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1821. inline ss_typename_type_k fixed_array_4d<T, A, P, R>::allocator_type fixed_array_4d<T, A, P, R>::get_allocator() const
  1822. {
  1823. return *this;
  1824. }
  1825. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1826. inline void fixed_array_4d<T, A, P, R>::swap(ss_typename_type_k fixed_array_4d<T, A, P, R>::class_type& rhs) stlsoft_throw_0()
  1827. {
  1828. // We don't need to do any construct and swap here, because all the
  1829. // variables that are being swapped are simple types (integers and
  1830. // pointers).
  1831. std_swap(get_allocator_(), rhs.get_allocator_());
  1832. std_swap(m_data, rhs.m_data);
  1833. std_swap(m_d0, rhs.m_d0);
  1834. std_swap(m_d1, rhs.m_d1);
  1835. std_swap(m_d2, rhs.m_d2);
  1836. std_swap(m_d3, rhs.m_d3);
  1837. }
  1838. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1839. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reference fixed_array_4d<T, A, P, R>::at(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3)
  1840. {
  1841. range_check_(i0, i1, i2, i3);
  1842. return *(m_data + calc_index_(i0, i1, i2, i3));
  1843. }
  1844. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1845. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reference fixed_array_4d<T, A, P, R>::at(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3) const
  1846. {
  1847. range_check_(i0, i1, i2, i3);
  1848. return *(m_data + calc_index_(i0, i1, i2, i3));
  1849. }
  1850. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1851. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reference fixed_array_4d<T, A, P, R>::at_unchecked(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3)
  1852. {
  1853. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1 && i2 < m_d2 && i3 < m_d3));
  1854. return *(m_data + calc_index_(i0, i1, i2, i3));
  1855. }
  1856. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1857. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reference fixed_array_4d<T, A, P, R>::at_unchecked(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3) const
  1858. {
  1859. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", (i0 < m_d0 && i1 < m_d1 && i2 < m_d2 && i3 < m_d3));
  1860. return *(m_data + calc_index_(i0, i1, i2, i3));
  1861. }
  1862. #ifndef STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP
  1863. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1864. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reference fixed_array_4d<T, A, P, R>::operator ()(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3)
  1865. {
  1866. return at_unchecked(i0, i1, i2, i3);
  1867. }
  1868. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1869. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reference fixed_array_4d<T, A, P, R>::operator ()(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i1, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i2, ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i3) const
  1870. {
  1871. return at_unchecked(i0, i1, i2, i3);
  1872. }
  1873. #endif /* !STLSOFT_FIXED_ARRAY_NO_FUNCTION_OP */
  1874. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1875. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::dimension_element_type fixed_array_4d<T, A, P, R>::at(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0)
  1876. {
  1877. range_check_(i0);
  1878. return dimension_element_type(m_data + i0 * m_d1 * m_d2 * m_d3, m_d1, m_d2, m_d3);
  1879. }
  1880. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1881. inline ss_typename_type_k fixed_array_4d<T, A, P, R>::const_dimension_element_type fixed_array_4d<T, A, P, R>::at(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0) const
  1882. {
  1883. range_check_(i0);
  1884. return dimension_element_type(m_data + i0 * m_d1 * m_d2 * m_d3, m_d1, m_d2, m_d3);
  1885. }
  1886. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1887. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::dimension_element_type fixed_array_4d<T, A, P, R>::at_unchecked(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0)
  1888. {
  1889. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1890. return dimension_element_type(m_data + i0 * m_d1 * m_d2 * m_d3, m_d1, m_d2, m_d3);
  1891. }
  1892. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1893. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_dimension_element_type fixed_array_4d<T, A, P, R>::at_unchecked(ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0) const
  1894. {
  1895. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1896. return dimension_element_type(m_data + i0 * m_d1 * m_d2 * m_d3, m_d1, m_d2, m_d3);
  1897. }
  1898. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1899. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::dimension_element_type fixed_array_4d<T, A, P, R>::operator [](ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0)
  1900. {
  1901. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1902. return dimension_element_type(m_data + i0 * m_d1 * m_d2 * m_d3, m_d1, m_d2, m_d3);
  1903. }
  1904. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1905. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_dimension_element_type fixed_array_4d<T, A, P, R>::operator [](ss_typename_param_k fixed_array_4d<T, A, P, R>::index_type i0) const
  1906. {
  1907. STLSOFT_MESSAGE_ASSERT("fixed array index out of range", i0 < m_d0);
  1908. return dimension_element_type(m_data + i0 * m_d1 * m_d2 * m_d3, m_d1, m_d2, m_d3);
  1909. }
  1910. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1911. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reference fixed_array_4d<T, A, P, R>::front()
  1912. {
  1913. return at(0, 0, 0, 0);
  1914. }
  1915. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1916. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reference fixed_array_4d<T, A, P, R>::back()
  1917. {
  1918. return at(m_d0 - 1, m_d1 - 1, m_d2 - 1, m_d3 - 1);
  1919. }
  1920. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1921. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reference fixed_array_4d<T, A, P, R>::front() const
  1922. {
  1923. return at(0, 0, 0, 0);
  1924. }
  1925. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1926. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reference fixed_array_4d<T, A, P, R>::back() const
  1927. {
  1928. return at(m_d0 - 1, m_d1 - 1, m_d2 - 1, m_d3 - 1);
  1929. }
  1930. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1931. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::index_type fixed_array_4d<T, A, P, R>::dimension0() const
  1932. {
  1933. return m_d0;
  1934. }
  1935. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1936. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::index_type fixed_array_4d<T, A, P, R>::dimension1() const
  1937. {
  1938. return m_d1;
  1939. }
  1940. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1941. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::index_type fixed_array_4d<T, A, P, R>::dimension2() const
  1942. {
  1943. return m_d2;
  1944. }
  1945. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1946. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::index_type fixed_array_4d<T, A, P, R>::dimension3() const
  1947. {
  1948. return m_d3;
  1949. }
  1950. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1951. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::index_type fixed_array_4d<T, A, P, R>::size() const
  1952. {
  1953. return m_d0 * m_d1 * m_d2 * m_d3;
  1954. }
  1955. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1956. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::bool_type fixed_array_4d<T, A, P, R>::empty() const
  1957. {
  1958. return 0 == size();
  1959. }
  1960. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1961. inline /* static */ ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::size_type fixed_array_4d<T, A, P, R>::max_size()
  1962. {
  1963. return static_cast<size_type>(-1) / sizeof(T);
  1964. }
  1965. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1966. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::iterator fixed_array_4d<T, A, P, R>::begin()
  1967. {
  1968. return m_data;
  1969. }
  1970. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1971. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::iterator fixed_array_4d<T, A, P, R>::end()
  1972. {
  1973. return m_data + size();
  1974. }
  1975. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1976. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_iterator fixed_array_4d<T, A, P, R>::begin() const
  1977. {
  1978. return m_data;
  1979. }
  1980. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1981. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_iterator fixed_array_4d<T, A, P, R>::end() const
  1982. {
  1983. return m_data + size();
  1984. }
  1985. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  1986. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1987. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reverse_iterator fixed_array_4d<T, A, P, R>::rbegin()
  1988. {
  1989. return reverse_iterator(end());
  1990. }
  1991. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1992. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::reverse_iterator fixed_array_4d<T, A, P, R>::rend()
  1993. {
  1994. return reverse_iterator(begin());
  1995. }
  1996. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  1997. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reverse_iterator fixed_array_4d<T, A, P, R>::rbegin() const
  1998. {
  1999. return const_reverse_iterator(end());
  2000. }
  2001. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  2002. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_reverse_iterator fixed_array_4d<T, A, P, R>::rend() const
  2003. {
  2004. return const_reverse_iterator(begin());
  2005. }
  2006. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  2007. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  2008. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::pointer fixed_array_4d<T, A, P, R>::data()
  2009. {
  2010. return m_data;
  2011. }
  2012. template <ss_typename_param_k T, ss_typename_param_k A, ss_typename_param_k P, ss_bool_t R>
  2013. inline ss_typename_type_ret_k fixed_array_4d<T, A, P, R>::const_pointer fixed_array_4d<T, A, P, R>::data() const
  2014. {
  2015. return m_data;
  2016. }
  2017. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  2018. /* /////////////////////////////////////////////////////////////////////////
  2019. * Shims
  2020. */
  2021. template< ss_typename_param_k T
  2022. , ss_typename_param_k A
  2023. , ss_typename_param_k P
  2024. , ss_bool_t R
  2025. >
  2026. inline ss_size_t array_size(fixed_array_1d<T, A, P, R> const& ar)
  2027. {
  2028. return ar.size();
  2029. }
  2030. template< ss_typename_param_k T
  2031. , ss_typename_param_k A
  2032. , ss_typename_param_k P
  2033. , ss_bool_t R
  2034. >
  2035. inline ss_size_t array_size(fixed_array_2d<T, A, P, R> const& ar)
  2036. {
  2037. return ar.size();
  2038. }
  2039. template< ss_typename_param_k T
  2040. , ss_typename_param_k A
  2041. , ss_typename_param_k P
  2042. , ss_bool_t R
  2043. >
  2044. inline ss_size_t array_size(fixed_array_3d<T, A, P, R> const& ar)
  2045. {
  2046. return ar.size();
  2047. }
  2048. template< ss_typename_param_k T
  2049. , ss_typename_param_k A
  2050. , ss_typename_param_k P
  2051. , ss_bool_t R
  2052. >
  2053. inline ss_size_t array_size(fixed_array_4d<T, A, P, R> const& ar)
  2054. {
  2055. return ar.size();
  2056. }
  2057. #if 0
  2058. template< ss_typename_param_k T
  2059. , ss_typename_param_k A
  2060. , ss_typename_param_k P
  2061. , ss_bool_t R
  2062. >
  2063. inline ss_size_t array_size(fixed_array_5d<T, A, P, R> const& ar)
  2064. {
  2065. return ar.size();
  2066. }
  2067. #endif /* 0 */
  2068. /* ////////////////////////////////////////////////////////////////////// */
  2069. #ifndef _STLSOFT_NO_NAMESPACE
  2070. } // namespace stlsoft
  2071. #endif /* _STLSOFT_NO_NAMESPACE */
  2072. /* ////////////////////////////////////////////////////////////////////// */
  2073. #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_FIXED_ARRAY */
  2074. /* ///////////////////////////// end of file //////////////////////////// */