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.

1900 lines
81 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/containers/static_array.hpp
  3. *
  4. * Purpose: Statically sized multidimensional class template.
  5. *
  6. * Created: 4th August 1998
  7. * Updated: 10th August 2009
  8. *
  9. * Thanks to: Neal Becker for suggesting the uninitialised mode.
  10. *
  11. * Home: http://stlsoft.org/
  12. *
  13. * Copyright (c) 1998-2009, Matthew Wilson and Synesis Software
  14. * All rights reserved.
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions are met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice, this
  20. * list of conditions and the following disclaimer.
  21. * - Redistributions in binary form must reproduce the above copyright notice,
  22. * this list of conditions and the following disclaimer in the documentation
  23. * and/or other materials provided with the distribution.
  24. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  25. * any contributors may be used to endorse or promote products derived from
  26. * this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  34. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  35. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  36. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  37. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * ////////////////////////////////////////////////////////////////////// */
  41. /** \file stlsoft/containers/static_array.hpp
  42. *
  43. * \brief [C++ only] Definition of the stlsoft::static_array_1d,
  44. * stlsoft::static_array_2d, stlsoft::static_array_3d, and
  45. * stlsoft::static_array_4d multidimensional array class templates
  46. * (\ref group__library__containers "Containers" Library).
  47. */
  48. #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY
  49. #define STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY
  50. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  51. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY_MAJOR 4
  52. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY_MINOR 4
  53. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY_REVISION 2
  54. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY_EDIT 188
  55. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  56. /* /////////////////////////////////////////////////////////////////////////
  57. * Compatibility
  58. */
  59. /*
  60. [Incompatibilies-start]
  61. STLSOFT_COMPILER_IS_BORLAND: __BORLANDC__<0x0564
  62. STLSOFT_COMPILER_IS_DMC: __DMC__<0x0844
  63. STLSOFT_COMPILER_IS_GCC: __GNUC__<3
  64. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  65. STLSOFT_COMPILER_IS_WATCOM:
  66. [Incompatibilies-end]
  67. */
  68. /* /////////////////////////////////////////////////////////////////////////
  69. * Includes
  70. */
  71. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  72. # include <stlsoft/stlsoft.h>
  73. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  74. #if defined(STLSOFT_COMPILER_IS_BORLAND) && \
  75. __BORLANDC__ < 0x0560
  76. # error stlsoft/containers/static_array.hpp is not compatible with Borland C/C++ prior to 5.6
  77. #elif defined(STLSOFT_COMPILER_IS_DMC) && \
  78. __DMC__ < 0x0844
  79. # error stlsoft/containers/static_array.hpp is not compatible with Digital Mars C/C++ 8.43 or earlier
  80. #elif defined(STLSOFT_COMPILER_IS_GCC) && \
  81. __GNUC__ < 3
  82. # error stlsoft/containers/static_array.hpp is not compatible with GNU C/C++ prior to 3.0
  83. #elif defined(STLSOFT_COMPILER_IS_MSVC) && \
  84. _MSC_VER < 1200
  85. # error stlsoft/containers/static_array.hpp is not compatible with Visual C++ 5.0 or earlier
  86. #endif /* compiler */
  87. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_NULL_ALLOCATOR
  88. # include <stlsoft/memory/null_allocator.hpp>
  89. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_NULL_ALLOCATOR */
  90. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  91. # include <stlsoft/util/std/iterator_helper.hpp>
  92. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  93. #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES
  94. # include <stlsoft/containers/util/array_policies.hpp> // for stlsoft::do_construction()
  95. #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES */
  96. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_POINTER_TYPE
  97. # include <stlsoft/meta/is_pointer_type.hpp>
  98. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_IS_POINTER_TYPE */
  99. #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
  100. # include <stlsoft/collections/util/collections.hpp>
  101. #endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
  102. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  103. defined(STLSOFT_CF_STD_LIBRARY_IS_STLPORT)
  104. # include <string> // for std::string - sigh!
  105. #endif /* compiler */
  106. #ifndef STLSOFT_INCL_STDEXCEPT
  107. # define STLSOFT_INCL_STDEXCEPT
  108. # include <stdexcept> // for std::out_of_range
  109. #endif /* !STLSOFT_INCL_STDEXCEPT */
  110. #ifdef STLSOFT_UNITTEST
  111. # include <algorithm>
  112. # include <numeric>
  113. #endif /* !STLSOFT_UNITTEST */
  114. /* /////////////////////////////////////////////////////////////////////////
  115. * Namespace
  116. */
  117. #ifndef _STLSOFT_NO_NAMESPACE
  118. namespace stlsoft
  119. {
  120. #endif /* _STLSOFT_NO_NAMESPACE */
  121. /* /////////////////////////////////////////////////////////////////////////
  122. * Forward declarations
  123. */
  124. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  125. template< ss_typename_param_k T
  126. , ss_size_t N0
  127. , ss_typename_param_k P
  128. , ss_typename_param_k M
  129. >
  130. class static_array_1d;
  131. template< ss_typename_param_k T
  132. , ss_size_t N0
  133. , ss_size_t N1
  134. , ss_typename_param_k P
  135. , ss_typename_param_k M
  136. >
  137. class static_array_2d;
  138. template< ss_typename_param_k T
  139. , ss_size_t N0
  140. , ss_size_t N1
  141. , ss_size_t N2
  142. , ss_typename_param_k P
  143. , ss_typename_param_k M
  144. >
  145. class static_array_3d;
  146. template< ss_typename_param_k T
  147. , ss_size_t N0
  148. , ss_size_t N1
  149. , ss_size_t N2
  150. , ss_size_t N3
  151. , ss_typename_param_k P
  152. , ss_typename_param_k M
  153. >
  154. class static_array_4d;
  155. template< ss_typename_param_k T
  156. , ss_size_t N0
  157. , ss_size_t N1
  158. , ss_size_t N2
  159. , ss_size_t N3
  160. , ss_size_t N4
  161. , ss_typename_param_k P
  162. , ss_typename_param_k M
  163. >
  164. class static_array_5d;
  165. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  166. ////////////////////////////////////////////////////////////////////////////
  167. // Classes
  168. // class static_array_1d
  169. /** \brief 1 dimensional static array
  170. *
  171. * \ingroup group__library__containers
  172. *
  173. * \param T The value type
  174. * \param N0 The first dimension extent
  175. * \param P The construction policy type
  176. */
  177. template< ss_typename_param_k T
  178. , ss_size_t N0
  179. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  180. , ss_typename_param_k P = do_construction<T>
  181. , ss_typename_param_k M = T[N0]
  182. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  183. , ss_typename_param_k P
  184. , ss_typename_param_k M
  185. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  186. >
  187. class static_array_1d
  188. : public null_allocator<T>
  189. , public stl_collection_tag
  190. {
  191. public:
  192. typedef static_array_1d<T, N0, P, M> class_type;
  193. typedef T dimension_type;
  194. typedef null_allocator<T> allocator_type;
  195. typedef P policy_type;
  196. typedef T value_type;
  197. typedef value_type& reference;
  198. typedef value_type const& const_reference;
  199. typedef value_type* pointer;
  200. typedef value_type const* const_pointer;
  201. typedef ss_size_t size_type;
  202. typedef ss_size_t index_type;
  203. typedef ss_ptrdiff_t difference_type;
  204. typedef
  205. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  206. ss_typename_type_k
  207. #endif /* compiler */
  208. pointer_iterator < value_type
  209. , pointer
  210. , reference
  211. >::type iterator;
  212. typedef
  213. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  214. ss_typename_type_k
  215. #endif /* compiler */
  216. pointer_iterator < value_type const
  217. , const_pointer
  218. , const_reference
  219. >::type const_iterator;
  220. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  221. typedef reverse_iterator_base < iterator
  222. , value_type
  223. , reference
  224. , pointer
  225. , difference_type
  226. > reverse_iterator;
  227. typedef const_reverse_iterator_base < const_iterator
  228. , value_type const
  229. , const_reference
  230. , const_pointer
  231. , difference_type
  232. > const_reverse_iterator;
  233. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  234. // Construction
  235. //protected:
  236. static_array_1d(T *data/* [N0] */);
  237. public:
  238. static_array_1d();
  239. static_array_1d(value_type const& t);
  240. static_array_1d(class_type const& rhs);
  241. ~static_array_1d() stlsoft_throw_0();
  242. // Access
  243. public:
  244. reference at(index_type i0);
  245. const_reference at(index_type i0) const;
  246. reference at_unchecked(index_type i0);
  247. const_reference at_unchecked(index_type i0) const;
  248. reference operator [](index_type i0);
  249. const_reference operator [](index_type i0) const;
  250. reference front();
  251. reference back();
  252. const_reference front() const;
  253. const_reference back() const;
  254. // State
  255. public:
  256. static index_type dimension0();
  257. static index_type size();
  258. static ss_bool_t empty();
  259. static size_type max_size();
  260. // Iteration
  261. public:
  262. iterator begin();
  263. iterator end();
  264. const_iterator begin() const;
  265. const_iterator end() const;
  266. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  267. reverse_iterator rbegin();
  268. reverse_iterator rend();
  269. const_reverse_iterator rbegin() const;
  270. const_reverse_iterator rend() const;
  271. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  272. // Access
  273. public:
  274. value_type const *data() const;
  275. // Implementation
  276. protected:
  277. pointer data_();
  278. index_type calc_index_(index_type i0) const;
  279. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  280. // Members
  281. private:
  282. M m_data;
  283. // Not to be implemented
  284. private:
  285. class_type const& operator =(class_type const& rhs);
  286. };
  287. // class static_array_2d
  288. /** \brief 2 dimensional static array
  289. *
  290. * \ingroup group__library__containers
  291. *
  292. * \param T The value type
  293. * \param N0 The first dimension extent
  294. * \param N1 The second dimension extent
  295. * \param P The construction policy type
  296. */
  297. template< ss_typename_param_k T
  298. , ss_size_t N0
  299. , ss_size_t N1
  300. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  301. , ss_typename_param_k P = do_construction<T>
  302. , ss_typename_param_k M = T[N0 * N1]
  303. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  304. , ss_typename_param_k P
  305. , ss_typename_param_k M
  306. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  307. >
  308. class static_array_2d
  309. : public null_allocator<T>
  310. , public stl_collection_tag
  311. {
  312. public:
  313. typedef static_array_2d<T, N0, N1, P, M> class_type;
  314. typedef static_array_1d<T, N1, P, T*> dimension_type;
  315. typedef null_allocator<T> allocator_type;
  316. typedef P policy_type;
  317. typedef T value_type;
  318. typedef value_type& reference;
  319. typedef value_type const& const_reference;
  320. typedef value_type* pointer;
  321. typedef value_type const* const_pointer;
  322. typedef ss_size_t size_type;
  323. typedef ss_size_t index_type;
  324. typedef ss_ptrdiff_t difference_type;
  325. typedef
  326. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  327. ss_typename_type_k
  328. #endif /* compiler */
  329. pointer_iterator < value_type
  330. , pointer
  331. , reference
  332. >::type iterator;
  333. typedef
  334. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  335. ss_typename_type_k
  336. #endif /* compiler */
  337. pointer_iterator < value_type const
  338. , const_pointer
  339. , const_reference
  340. >::type const_iterator;
  341. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  342. typedef reverse_iterator_base < iterator
  343. , value_type
  344. , reference
  345. , pointer
  346. , difference_type
  347. > reverse_iterator;
  348. typedef const_reverse_iterator_base < const_iterator
  349. , value_type const
  350. , const_reference
  351. , const_pointer
  352. , difference_type
  353. > const_reverse_iterator;
  354. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  355. // Construction
  356. //protected:
  357. // static_array_2d(T data[N0][N1]);
  358. static_array_2d(T *data);
  359. public:
  360. static_array_2d();
  361. static_array_2d(value_type const& t);
  362. static_array_2d(class_type const& rhs);
  363. ~static_array_2d() stlsoft_throw_0();
  364. // Operations
  365. public:
  366. reference at(index_type i0, index_type i1);
  367. const_reference at(index_type i0, index_type i1) const;
  368. reference at_unchecked(index_type i0, index_type i1);
  369. const_reference at_unchecked(index_type i0, index_type i1) const;
  370. dimension_type at(index_type i0);
  371. const dimension_type at(index_type i0) const;
  372. dimension_type at_unchecked(index_type i0);
  373. const dimension_type at_unchecked(index_type i0) const;
  374. dimension_type operator [](index_type i0);
  375. const dimension_type operator [](index_type i0) const;
  376. reference front();
  377. reference back();
  378. const_reference front() const;
  379. const_reference back() const;
  380. // State
  381. public:
  382. static index_type dimension0();
  383. static index_type dimension1();
  384. static index_type size();
  385. static ss_bool_t empty();
  386. static size_type max_size();
  387. // Iteration
  388. public:
  389. iterator begin();
  390. iterator end();
  391. const_iterator begin() const;
  392. const_iterator end() const;
  393. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  394. reverse_iterator rbegin();
  395. reverse_iterator rend();
  396. const_reverse_iterator rbegin() const;
  397. const_reverse_iterator rend() const;
  398. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  399. // Access
  400. public:
  401. value_type const *data() const;
  402. // Implementation
  403. protected:
  404. pointer data_();
  405. index_type calc_index_(index_type i0, index_type i1) const;
  406. void range_check_(index_type i0, index_type i1) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  407. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  408. // Members
  409. private:
  410. M m_data;
  411. // Not to be implemented
  412. private:
  413. class_type const& operator =(class_type const& rhs);
  414. };
  415. // class static_array_3d
  416. /** \brief 3 dimensional static array
  417. *
  418. * \ingroup group__library__containers
  419. *
  420. * \param T The value type
  421. * \param N0 The first dimension extent
  422. * \param N1 The second dimension extent
  423. * \param N2 The third dimension extent
  424. * \param P The construction policy type
  425. */
  426. template< ss_typename_param_k T
  427. , ss_size_t N0
  428. , ss_size_t N1
  429. , ss_size_t N2
  430. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  431. , ss_typename_param_k P = do_construction<T>
  432. , ss_typename_param_k M = T[N0 * N1 * N2]
  433. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  434. , ss_typename_param_k P
  435. , ss_typename_param_k M
  436. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  437. >
  438. class static_array_3d
  439. : public null_allocator<T>
  440. , public stl_collection_tag
  441. {
  442. public:
  443. typedef static_array_3d<T, N0, N1, N2, P, M> class_type;
  444. typedef static_array_2d<T, N1, N2, P, T*> dimension_type;
  445. typedef null_allocator<T> allocator_type;
  446. typedef P policy_type;
  447. typedef T value_type;
  448. typedef value_type& reference;
  449. typedef value_type const& const_reference;
  450. typedef value_type* pointer;
  451. typedef value_type const* const_pointer;
  452. typedef ss_size_t size_type;
  453. typedef ss_size_t index_type;
  454. typedef ss_ptrdiff_t difference_type;
  455. typedef
  456. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  457. ss_typename_type_k
  458. #endif /* compiler */
  459. pointer_iterator < value_type
  460. , pointer
  461. , reference
  462. >::type iterator;
  463. typedef
  464. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  465. ss_typename_type_k
  466. #endif /* compiler */
  467. pointer_iterator < value_type const
  468. , const_pointer
  469. , const_reference
  470. >::type const_iterator;
  471. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  472. typedef reverse_iterator_base < iterator
  473. , value_type
  474. , reference
  475. , pointer
  476. , difference_type
  477. > reverse_iterator;
  478. typedef const_reverse_iterator_base < const_iterator
  479. , value_type const
  480. , const_reference
  481. , const_pointer
  482. , difference_type
  483. > const_reverse_iterator;
  484. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  485. // Construction
  486. //protected:
  487. // static_array_3d(T data[N0][N1][N2]);
  488. static_array_3d(T *data);
  489. public:
  490. static_array_3d();
  491. static_array_3d(value_type const& t);
  492. static_array_3d(class_type const& rhs);
  493. ~static_array_3d() stlsoft_throw_0();
  494. // Operations
  495. public:
  496. reference at(index_type i0, index_type i1, index_type i2);
  497. const_reference at(index_type i0, index_type i1, index_type i2) const;
  498. reference at_unchecked(index_type i0, index_type i1, index_type i2);
  499. const_reference at_unchecked(index_type i0, index_type i1, index_type i2) const;
  500. dimension_type at(index_type i0);
  501. const dimension_type at(index_type i0) const;
  502. dimension_type at_unchecked(index_type i0);
  503. const dimension_type at_unchecked(index_type i0) const;
  504. dimension_type operator [](index_type i0);
  505. const dimension_type operator [](index_type i0) const;
  506. reference front();
  507. reference back();
  508. const_reference front() const;
  509. const_reference back() const;
  510. // State
  511. public:
  512. static index_type dimension0();
  513. static index_type dimension1();
  514. static index_type dimension2();
  515. static index_type size();
  516. static ss_bool_t empty();
  517. static size_type max_size();
  518. // Iteration
  519. public:
  520. iterator begin();
  521. iterator end();
  522. const_iterator begin() const;
  523. const_iterator end() const;
  524. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  525. reverse_iterator rbegin();
  526. reverse_iterator rend();
  527. const_reverse_iterator rbegin() const;
  528. const_reverse_iterator rend() const;
  529. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  530. // Access
  531. public:
  532. value_type const *data() const;
  533. // Implementation
  534. protected:
  535. pointer data_();
  536. index_type calc_index_(index_type i0, index_type i1, index_type i2) const;
  537. void range_check_(index_type i0, index_type i1, index_type i2) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  538. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  539. // Members
  540. private:
  541. M m_data;
  542. // Not to be implemented
  543. private:
  544. class_type const& operator =(class_type const& rhs);
  545. };
  546. // class static_array_4d
  547. /** \brief 4 dimensional static array
  548. *
  549. * \ingroup group__library__containers
  550. *
  551. * \param T The value type
  552. * \param N0 The first dimension extent
  553. * \param N1 The second dimension extent
  554. * \param N2 The third dimension extent
  555. * \param P The construction policy type
  556. */
  557. template< ss_typename_param_k T
  558. , ss_size_t N0
  559. , ss_size_t N1
  560. , ss_size_t N2
  561. , ss_size_t N3
  562. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  563. , ss_typename_param_k P = do_construction<T>
  564. , ss_typename_param_k M = T[N0 * N1 * N2 * N3]
  565. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  566. , ss_typename_param_k P
  567. , ss_typename_param_k M
  568. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  569. >
  570. class static_array_4d
  571. : public null_allocator<T>
  572. , public stl_collection_tag
  573. {
  574. public:
  575. typedef static_array_4d<T, N0, N1, N2, N3, P, M> class_type;
  576. typedef static_array_3d<T, N1, N2, N3, P, T*> dimension_type;
  577. typedef null_allocator<T> allocator_type;
  578. typedef P policy_type;
  579. typedef T value_type;
  580. typedef value_type& reference;
  581. typedef value_type const& const_reference;
  582. typedef value_type* pointer;
  583. typedef value_type const* const_pointer;
  584. typedef ss_size_t size_type;
  585. typedef ss_size_t index_type;
  586. typedef ss_ptrdiff_t difference_type;
  587. typedef
  588. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  589. ss_typename_type_k
  590. #endif /* compiler */
  591. pointer_iterator < value_type
  592. , pointer
  593. , reference
  594. >::type iterator;
  595. typedef
  596. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  597. ss_typename_type_k
  598. #endif /* compiler */
  599. pointer_iterator < value_type const
  600. , const_pointer
  601. , const_reference
  602. >::type const_iterator;
  603. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  604. typedef reverse_iterator_base < iterator
  605. , value_type
  606. , reference
  607. , pointer
  608. , difference_type
  609. > reverse_iterator;
  610. typedef const_reverse_iterator_base < const_iterator
  611. , value_type const
  612. , const_reference
  613. , const_pointer
  614. , difference_type
  615. > const_reverse_iterator;
  616. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  617. // Construction
  618. //protected:
  619. // static_array_4d(T data[N0][N1][N2][N3]);
  620. static_array_4d(T *data);
  621. public:
  622. static_array_4d();
  623. static_array_4d(value_type const& t);
  624. static_array_4d(class_type const& rhs);
  625. ~static_array_4d() stlsoft_throw_0();
  626. // Operations
  627. public:
  628. reference at(index_type i0, index_type i1, index_type i2, index_type i3);
  629. const_reference at(index_type i0, index_type i1, index_type i2, index_type i3) const;
  630. reference at_unchecked(index_type i0, index_type i1, index_type i2, index_type i3);
  631. const_reference at_unchecked(index_type i0, index_type i1, index_type i2, index_type i3) const;
  632. dimension_type at(index_type i0);
  633. const dimension_type at(index_type i0) const;
  634. dimension_type at_unchecked(index_type i0);
  635. const dimension_type at_unchecked(index_type i0) const;
  636. dimension_type operator [](index_type i0);
  637. const dimension_type operator [](index_type i0) const;
  638. reference front();
  639. reference back();
  640. const_reference front() const;
  641. const_reference back() const;
  642. // State
  643. public:
  644. static index_type dimension0();
  645. static index_type dimension1();
  646. static index_type dimension2();
  647. static index_type dimension3();
  648. static index_type size();
  649. static ss_bool_t empty();
  650. static size_type max_size();
  651. // Iteration
  652. public:
  653. iterator begin();
  654. iterator end();
  655. const_iterator begin() const;
  656. const_iterator end() const;
  657. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  658. reverse_iterator rbegin();
  659. reverse_iterator rend();
  660. const_reverse_iterator rbegin() const;
  661. const_reverse_iterator rend() const;
  662. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  663. // Access
  664. public:
  665. value_type const *data() const;
  666. // Implementation
  667. protected:
  668. pointer data_();
  669. index_type calc_index_(index_type i0, index_type i1, index_type i2, index_type i3) const;
  670. 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) );
  671. void range_check_(index_type i0, index_type i1, index_type i2) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  672. void range_check_(index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) );
  673. // Members
  674. private:
  675. M m_data;
  676. // Not to be implemented
  677. private:
  678. class_type const& operator =(class_type const& rhs);
  679. };
  680. /* /////////////////////////////////////////////////////////////////////////
  681. * Implementation
  682. */
  683. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  684. // static_array_1d
  685. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  686. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::pointer static_array_1d<T, N0, P, M>::data_()
  687. {
  688. return &m_data[0];
  689. }
  690. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  691. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::index_type static_array_1d<T, N0, P, M>::calc_index_(ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0) const
  692. {
  693. return i0;
  694. }
  695. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  696. inline void static_array_1d<T, N0, P, M>::range_check_(ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  697. {
  698. STLSOFT_SUPPRESS_UNUSED(i0);
  699. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  700. if(!(i0 < N0))
  701. {
  702. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  703. }
  704. #else
  705. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  706. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  707. }
  708. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  709. inline static_array_1d<T, N0, P, M>::static_array_1d(T *data/* [N0] */)
  710. : m_data(data)
  711. {}
  712. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  713. inline static_array_1d<T, N0, P, M>::static_array_1d()
  714. {
  715. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size());
  716. }
  717. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  718. inline static_array_1d<T, N0, P, M>::static_array_1d(value_type const& t)
  719. {
  720. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size(), t);
  721. }
  722. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  723. inline static_array_1d<T, N0, P, M>::static_array_1d(static_array_1d<T, N0, P, M> const& rhs)
  724. {
  725. array_range_initialiser<T, allocator_type, P>::copy_construct(*this, data_(), rhs.data(), size());
  726. }
  727. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  728. inline static_array_1d<T, N0, P, M>::~static_array_1d() stlsoft_throw_0()
  729. {
  730. if(!is_pointer_type<M>::value)
  731. {
  732. array_range_initialiser<T, allocator_type, P>::destroy(*this, data_(), size());
  733. }
  734. }
  735. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  736. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type &static_array_1d<T, N0, P, M>::at(ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0)
  737. {
  738. range_check_(i0);
  739. return m_data[i0];
  740. }
  741. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  742. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type const& static_array_1d<T, N0, P, M>::at(ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0) const
  743. {
  744. range_check_(i0);
  745. return m_data[i0];
  746. }
  747. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  748. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type &static_array_1d<T, N0, P, M>::at_unchecked(ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0)
  749. {
  750. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  751. return m_data[i0];
  752. }
  753. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  754. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type const& static_array_1d<T, N0, P, M>::at_unchecked(ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0) const
  755. {
  756. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  757. return m_data[i0];
  758. }
  759. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  760. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type &static_array_1d<T, N0, P, M>::operator [](ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0)
  761. {
  762. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  763. return m_data[i0];
  764. }
  765. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  766. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type const& static_array_1d<T, N0, P, M>::operator [](ss_typename_type_k static_array_1d<T, N0, P, M>::index_type i0) const
  767. {
  768. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  769. return m_data[i0];
  770. }
  771. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  772. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::reference static_array_1d<T, N0, P, M>::front()
  773. {
  774. return at(0);
  775. }
  776. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  777. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::reference static_array_1d<T, N0, P, M>::back()
  778. {
  779. return at(N0 - 1);
  780. }
  781. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  782. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::const_reference static_array_1d<T, N0, P, M>::front() const
  783. {
  784. return at(0);
  785. }
  786. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  787. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::const_reference static_array_1d<T, N0, P, M>::back() const
  788. {
  789. return at(N0 - 1);
  790. }
  791. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  792. inline /* static */ ss_typename_type_ret_k static_array_1d<T, N0, P, M>::index_type static_array_1d<T, N0, P, M>::dimension0()
  793. {
  794. return N0;
  795. }
  796. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  797. inline /* static */ ss_typename_type_ret_k static_array_1d<T, N0, P, M>::index_type static_array_1d<T, N0, P, M>::size()
  798. {
  799. return N0;
  800. }
  801. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  802. inline /* static */ ss_bool_t static_array_1d<T, N0, P, M>::empty()
  803. {
  804. return false;
  805. }
  806. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  807. inline /* static */ ss_typename_type_ret_k static_array_1d<T, N0, P, M>::index_type static_array_1d<T, N0, P, M>::max_size()
  808. {
  809. return size();
  810. }
  811. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  812. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::iterator static_array_1d<T, N0, P, M>::begin()
  813. {
  814. return m_data;
  815. }
  816. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  817. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::iterator static_array_1d<T, N0, P, M>::end()
  818. {
  819. return m_data + size();
  820. }
  821. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  822. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::const_iterator static_array_1d<T, N0, P, M>::begin() const
  823. {
  824. return m_data;
  825. }
  826. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  827. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::const_iterator static_array_1d<T, N0, P, M>::end() const
  828. {
  829. return m_data + size();
  830. }
  831. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  832. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  833. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::reverse_iterator static_array_1d<T, N0, P, M>::rbegin()
  834. {
  835. return reverse_iterator(end());
  836. }
  837. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  838. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::reverse_iterator static_array_1d<T, N0, P, M>::rend()
  839. {
  840. return reverse_iterator(begin());
  841. }
  842. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  843. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::const_reverse_iterator static_array_1d<T, N0, P, M>::rbegin() const
  844. {
  845. return const_reverse_iterator(end());
  846. }
  847. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  848. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::const_reverse_iterator static_array_1d<T, N0, P, M>::rend() const
  849. {
  850. return const_reverse_iterator(begin());
  851. }
  852. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  853. template <ss_typename_param_k T, ss_size_t N0, ss_typename_param_k P, ss_typename_param_k M>
  854. inline ss_typename_type_ret_k static_array_1d<T, N0, P, M>::value_type const* static_array_1d<T, N0, P, M>::data() const
  855. {
  856. return m_data;
  857. }
  858. // static_array_2d
  859. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  860. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::pointer static_array_2d<T, N0, N1, P, M>::data_()
  861. {
  862. return &m_data[0];
  863. }
  864. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  865. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::index_type static_array_2d<T, N0, N1, P, M>::calc_index_(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0, ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i1) const
  866. {
  867. return (i0 * N1) + i1;
  868. }
  869. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  870. inline void static_array_2d<T, N0, N1, P, M>::range_check_(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0, ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i1) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  871. {
  872. STLSOFT_SUPPRESS_UNUSED(i0); STLSOFT_SUPPRESS_UNUSED(i1);
  873. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  874. if( !(i0 < N0) ||
  875. !(i1 < N1))
  876. {
  877. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  878. }
  879. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  880. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1));
  881. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  882. }
  883. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  884. inline void static_array_2d<T, N0, N1, P, M>::range_check_(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  885. {
  886. STLSOFT_SUPPRESS_UNUSED(i0);
  887. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  888. if(!(i0 < N0))
  889. {
  890. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  891. }
  892. #else
  893. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  894. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  895. }
  896. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  897. inline static_array_2d<T, N0, N1, P, M>::static_array_2d(T *data)
  898. : m_data(data)
  899. {}
  900. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  901. inline static_array_2d<T, N0, N1, P, M>::static_array_2d()
  902. {
  903. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size());
  904. }
  905. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  906. inline static_array_2d<T, N0, N1, P, M>::static_array_2d(value_type const& t)
  907. {
  908. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size(), t);
  909. }
  910. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  911. inline static_array_2d<T, N0, N1, P, M>::static_array_2d(static_array_2d<T, N0, N1, P, M> const& rhs)
  912. {
  913. array_range_initialiser<T, allocator_type, P>::copy_construct(*this, data_(), rhs.data(), size());
  914. }
  915. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  916. inline static_array_2d<T, N0, N1, P, M>::~static_array_2d() stlsoft_throw_0()
  917. {
  918. if(!is_pointer_type<M>::value)
  919. {
  920. array_range_initialiser<T, allocator_type, P>::destroy(*this, data_(), size());
  921. }
  922. }
  923. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  924. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::reference static_array_2d<T, N0, N1, P, M>::at(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0, ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i1)
  925. {
  926. range_check_(i0, i1);
  927. return *(m_data + calc_index_(i0, i1));
  928. }
  929. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  930. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_reference static_array_2d<T, N0, N1, P, M>::at(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0, ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i1) const
  931. {
  932. range_check_(i0, i1);
  933. return *(m_data + calc_index_(i0, i1));
  934. }
  935. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  936. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::reference static_array_2d<T, N0, N1, P, M>::at_unchecked(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0, ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i1)
  937. {
  938. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1));
  939. return *(m_data + calc_index_(i0, i1));
  940. }
  941. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  942. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_reference static_array_2d<T, N0, N1, P, M>::at_unchecked(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0, ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i1) const
  943. {
  944. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1));
  945. return *(m_data + calc_index_(i0, i1));
  946. }
  947. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  948. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::dimension_type static_array_2d<T, N0, N1, P, M>::at(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0)
  949. {
  950. range_check_(i0);
  951. return dimension_type(m_data + i0 * N1);
  952. }
  953. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  954. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::dimension_type const static_array_2d<T, N0, N1, P, M>::at(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0) const
  955. {
  956. range_check_(i0);
  957. return dimension_type(m_data + i0 * N1);
  958. }
  959. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  960. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::dimension_type static_array_2d<T, N0, N1, P, M>::at_unchecked(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0)
  961. {
  962. return dimension_type(m_data + i0 * N1);
  963. }
  964. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  965. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::dimension_type const static_array_2d<T, N0, N1, P, M>::at_unchecked(ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0) const
  966. {
  967. return dimension_type(m_data + i0 * N1);
  968. }
  969. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  970. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::dimension_type static_array_2d<T, N0, N1, P, M>::operator [](ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0)
  971. {
  972. return dimension_type(m_data + i0 * N1);
  973. }
  974. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  975. inline const ss_typename_type_k static_array_2d<T, N0, N1, P, M>::dimension_type static_array_2d<T, N0, N1, P, M>::operator [](ss_typename_type_k static_array_2d<T, N0, N1, P, M>::index_type i0) const
  976. {
  977. return dimension_type(m_data + i0 * N1);
  978. }
  979. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  980. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::reference static_array_2d<T, N0, N1, P, M>::front()
  981. {
  982. return at(0, 0);
  983. }
  984. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  985. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::reference static_array_2d<T, N0, N1, P, M>::back()
  986. {
  987. return at(N0 - 1, N1 - 1);
  988. }
  989. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  990. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_reference static_array_2d<T, N0, N1, P, M>::front() const
  991. {
  992. return at(0, 0);
  993. }
  994. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  995. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_reference static_array_2d<T, N0, N1, P, M>::back() const
  996. {
  997. return at(N0 - 1, N1 - 1);
  998. }
  999. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1000. inline /* static */ ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::index_type static_array_2d<T, N0, N1, P, M>::dimension0()
  1001. {
  1002. return N0;
  1003. }
  1004. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1005. inline /* static */ ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::index_type static_array_2d<T, N0, N1, P, M>::dimension1()
  1006. {
  1007. return N1;
  1008. }
  1009. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1010. inline /* static */ ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::index_type static_array_2d<T, N0, N1, P, M>::size()
  1011. {
  1012. return N0 * N1;
  1013. }
  1014. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1015. inline /* static */ ss_bool_t static_array_2d<T, N0, N1, P, M>::empty()
  1016. {
  1017. return false;
  1018. }
  1019. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1020. inline /* static */ ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::index_type static_array_2d<T, N0, N1, P, M>::max_size()
  1021. {
  1022. return size();
  1023. }
  1024. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1025. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::iterator static_array_2d<T, N0, N1, P, M>::begin()
  1026. {
  1027. return m_data;
  1028. }
  1029. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1030. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::iterator static_array_2d<T, N0, N1, P, M>::end()
  1031. {
  1032. return m_data + size();
  1033. }
  1034. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1035. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_iterator static_array_2d<T, N0, N1, P, M>::begin() const
  1036. {
  1037. return m_data;
  1038. }
  1039. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1040. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_iterator static_array_2d<T, N0, N1, P, M>::end() const
  1041. {
  1042. return m_data + size();
  1043. }
  1044. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  1045. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1046. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::reverse_iterator static_array_2d<T, N0, N1, P, M>::rbegin()
  1047. {
  1048. return reverse_iterator(end());
  1049. }
  1050. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1051. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::reverse_iterator static_array_2d<T, N0, N1, P, M>::rend()
  1052. {
  1053. return reverse_iterator(begin());
  1054. }
  1055. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1056. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_reverse_iterator static_array_2d<T, N0, N1, P, M>::rbegin() const
  1057. {
  1058. return const_reverse_iterator(end());
  1059. }
  1060. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1061. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::const_reverse_iterator static_array_2d<T, N0, N1, P, M>::rend() const
  1062. {
  1063. return const_reverse_iterator(begin());
  1064. }
  1065. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1066. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_typename_param_k P, ss_typename_param_k M>
  1067. inline ss_typename_type_ret_k static_array_2d<T, N0, N1, P, M>::value_type const* static_array_2d<T, N0, N1, P, M>::data() const
  1068. {
  1069. return m_data;
  1070. }
  1071. // static_array_3d
  1072. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1073. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::pointer static_array_3d<T, N0, N1, N2, P, M>::data_()
  1074. {
  1075. return &m_data[0];
  1076. }
  1077. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1078. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::index_type static_array_3d<T, N0, N1, N2, P, M>::calc_index_(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i1, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i2) const
  1079. {
  1080. return ((i0 * N1) + i1) * N2 + i2;
  1081. }
  1082. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1083. inline void static_array_3d<T, N0, N1, N2, P, M>::range_check_(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i1, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i2) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1084. {
  1085. STLSOFT_SUPPRESS_UNUSED(i0); STLSOFT_SUPPRESS_UNUSED(i1); STLSOFT_SUPPRESS_UNUSED(i2);
  1086. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1087. if( !(i0 < N0) ||
  1088. !(i1 < N1) ||
  1089. !(i2 < N2))
  1090. {
  1091. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  1092. }
  1093. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1094. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1 && i2 < N2));
  1095. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1096. }
  1097. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1098. inline void static_array_3d<T, N0, N1, N2, P, M>::range_check_(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1099. {
  1100. STLSOFT_SUPPRESS_UNUSED(i0);
  1101. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1102. if(!(i0 < N0))
  1103. {
  1104. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  1105. }
  1106. #else
  1107. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  1108. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1109. }
  1110. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1111. inline static_array_3d<T, N0, N1, N2, P, M>::static_array_3d(T *data)
  1112. : m_data(data)
  1113. {}
  1114. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1115. inline static_array_3d<T, N0, N1, N2, P, M>::static_array_3d()
  1116. {
  1117. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size());
  1118. }
  1119. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1120. inline static_array_3d<T, N0, N1, N2, P, M>::static_array_3d(value_type const& t)
  1121. {
  1122. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size(), t);
  1123. }
  1124. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1125. inline static_array_3d<T, N0, N1, N2, P, M>::static_array_3d(static_array_3d<T, N0, N1, N2, P, M> const& rhs)
  1126. {
  1127. array_range_initialiser<T, allocator_type, P>::copy_construct(*this, data_(), rhs.data(), size());
  1128. }
  1129. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1130. inline static_array_3d<T, N0, N1, N2, P, M>::~static_array_3d() stlsoft_throw_0()
  1131. {
  1132. if(!is_pointer_type<M>::value)
  1133. {
  1134. array_range_initialiser<T, allocator_type, P>::destroy(*this, data_(), size());
  1135. }
  1136. }
  1137. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1138. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::value_type &static_array_3d<T, N0, N1, N2, P, M>::at(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i1, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i2)
  1139. {
  1140. range_check_(i0, i1, i2);
  1141. return *(m_data + calc_index_(i0, i1, i2));
  1142. }
  1143. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1144. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::value_type const& static_array_3d<T, N0, N1, N2, P, M>::at(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i1, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i2) const
  1145. {
  1146. range_check_(i0, i1, i2);
  1147. return *(m_data + calc_index_(i0, i1, i2));
  1148. }
  1149. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1150. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::value_type &static_array_3d<T, N0, N1, N2, P, M>::at_unchecked(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i1, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i2)
  1151. {
  1152. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1 && i2 < N2));
  1153. return *(m_data + calc_index_(i0, i1, i2));
  1154. }
  1155. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1156. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::value_type const& static_array_3d<T, N0, N1, N2, P, M>::at_unchecked(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i1, ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i2) const
  1157. {
  1158. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1 && i2 < N2));
  1159. return *(m_data + calc_index_(i0, i1, i2));
  1160. }
  1161. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1162. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::dimension_type static_array_3d<T, N0, N1, N2, P, M>::at(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0)
  1163. {
  1164. range_check_(i0);
  1165. return dimension_type(m_data + i0 * N1 * N2);
  1166. }
  1167. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1168. inline const ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::dimension_type static_array_3d<T, N0, N1, N2, P, M>::at(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0) const
  1169. {
  1170. range_check_(i0);
  1171. return dimension_type(m_data + i0 * N1 * N2);
  1172. }
  1173. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1174. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::dimension_type static_array_3d<T, N0, N1, N2, P, M>::at_unchecked(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0)
  1175. {
  1176. return dimension_type(m_data + i0 * N1 * N2);
  1177. }
  1178. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1179. inline const ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::dimension_type static_array_3d<T, N0, N1, N2, P, M>::at_unchecked(ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0) const
  1180. {
  1181. return dimension_type(m_data + i0 * N1 * N2);
  1182. }
  1183. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1184. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::dimension_type static_array_3d<T, N0, N1, N2, P, M>::operator [](ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0)
  1185. {
  1186. return dimension_type(m_data + i0 * N1 * N2);
  1187. }
  1188. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1189. inline const ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::dimension_type static_array_3d<T, N0, N1, N2, P, M>::operator [](ss_typename_type_k static_array_3d<T, N0, N1, N2, P, M>::index_type i0) const
  1190. {
  1191. return dimension_type(m_data + i0 * N1 * N2);
  1192. }
  1193. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1194. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::reference static_array_3d<T, N0, N1, N2, P, M>::front()
  1195. {
  1196. return at(0, 0, 0);
  1197. }
  1198. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1199. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::reference static_array_3d<T, N0, N1, N2, P, M>::back()
  1200. {
  1201. return at(N0 - 1, N1 - 1, N2 - 1);
  1202. }
  1203. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1204. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::const_reference static_array_3d<T, N0, N1, N2, P, M>::front() const
  1205. {
  1206. return at(0, 0, 0);
  1207. }
  1208. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1209. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::const_reference static_array_3d<T, N0, N1, N2, P, M>::back() const
  1210. {
  1211. return at(N0 - 1, N1 - 1, N2 - 1);
  1212. }
  1213. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1214. inline /* static */ ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::index_type static_array_3d<T, N0, N1, N2, P, M>::dimension0()
  1215. {
  1216. return N0;
  1217. }
  1218. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1219. inline /* static */ ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::index_type static_array_3d<T, N0, N1, N2, P, M>::dimension1()
  1220. {
  1221. return N1;
  1222. }
  1223. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1224. inline /* static */ ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::index_type static_array_3d<T, N0, N1, N2, P, M>::dimension2()
  1225. {
  1226. return N2;
  1227. }
  1228. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1229. inline /* static */ ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::index_type static_array_3d<T, N0, N1, N2, P, M>::size()
  1230. {
  1231. return N0 * N1 * N2;
  1232. }
  1233. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1234. inline /* static */ ss_bool_t static_array_3d<T, N0, N1, N2, P, M>::empty()
  1235. {
  1236. return false;
  1237. }
  1238. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1239. inline /* static */ ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::index_type static_array_3d<T, N0, N1, N2, P, M>::max_size()
  1240. {
  1241. return size();
  1242. }
  1243. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1244. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::iterator static_array_3d<T, N0, N1, N2, P, M>::begin()
  1245. {
  1246. return m_data;
  1247. }
  1248. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1249. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::iterator static_array_3d<T, N0, N1, N2, P, M>::end()
  1250. {
  1251. return m_data + size();
  1252. }
  1253. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1254. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::const_iterator static_array_3d<T, N0, N1, N2, P, M>::begin() const
  1255. {
  1256. return m_data;
  1257. }
  1258. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1259. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::const_iterator static_array_3d<T, N0, N1, N2, P, M>::end() const
  1260. {
  1261. return m_data + size();
  1262. }
  1263. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  1264. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1265. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::reverse_iterator static_array_3d<T, N0, N1, N2, P, M>::rbegin()
  1266. {
  1267. return reverse_iterator(end());
  1268. }
  1269. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1270. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::reverse_iterator static_array_3d<T, N0, N1, N2, P, M>::rend()
  1271. {
  1272. return reverse_iterator(begin());
  1273. }
  1274. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1275. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::const_reverse_iterator static_array_3d<T, N0, N1, N2, P, M>::rbegin() const
  1276. {
  1277. return const_reverse_iterator(end());
  1278. }
  1279. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1280. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::const_reverse_iterator static_array_3d<T, N0, N1, N2, P, M>::rend() const
  1281. {
  1282. return const_reverse_iterator(begin());
  1283. }
  1284. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1285. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_typename_param_k P, ss_typename_param_k M>
  1286. inline ss_typename_type_ret_k static_array_3d<T, N0, N1, N2, P, M>::value_type const* static_array_3d<T, N0, N1, N2, P, M>::data() const
  1287. {
  1288. return m_data;
  1289. }
  1290. // static_array_4d
  1291. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1292. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::pointer static_array_4d<T, N0, N1, N2, N3, P, M>::data_()
  1293. {
  1294. return &m_data[0];
  1295. }
  1296. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1297. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::calc_index_(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i1, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i2, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i3) const
  1298. {
  1299. return (((i0 * N1) + i1) * N2 + i2) * N3 + i3;
  1300. }
  1301. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1302. inline void static_array_4d<T, N0, N1, N2, N3, P, M>::range_check_(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i1, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i2, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i3) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1303. {
  1304. STLSOFT_SUPPRESS_UNUSED(i0); STLSOFT_SUPPRESS_UNUSED(i1); STLSOFT_SUPPRESS_UNUSED(i2); STLSOFT_SUPPRESS_UNUSED(i3);
  1305. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1306. if( !(i0 < N0) ||
  1307. !(i1 < N1) ||
  1308. !(i2 < N2) ||
  1309. !(i3 < N3))
  1310. {
  1311. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  1312. }
  1313. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1314. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1 && i2 < N2 && i3 < N3));
  1315. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1316. }
  1317. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1318. inline void static_array_4d<T, N0, N1, N2, N3, P, M>::range_check_(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0) const stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) )
  1319. {
  1320. STLSOFT_SUPPRESS_UNUSED(i0);
  1321. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1322. if(!(i0 < N0))
  1323. {
  1324. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("static array index out of range"));
  1325. }
  1326. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  1327. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  1328. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  1329. }
  1330. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1331. inline static_array_4d<T, N0, N1, N2, N3, P, M>::static_array_4d()
  1332. {
  1333. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size());
  1334. }
  1335. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1336. inline static_array_4d<T, N0, N1, N2, N3, P, M>::static_array_4d(value_type const& t)
  1337. {
  1338. array_range_initialiser<T, allocator_type, P>::construct(*this, data_(), size(), t);
  1339. }
  1340. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1341. inline static_array_4d<T, N0, N1, N2, N3, P, M>::static_array_4d(static_array_4d<T, N0, N1, N2, N3, P, M> const& rhs)
  1342. {
  1343. array_range_initialiser<T, allocator_type, P>::copy_construct(*this, data_(), rhs.data(), size());
  1344. }
  1345. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1346. inline static_array_4d<T, N0, N1, N2, N3, P, M>::~static_array_4d() stlsoft_throw_0()
  1347. {
  1348. if(!is_pointer_type<M>::value)
  1349. {
  1350. array_range_initialiser<T, allocator_type, P>::destroy(*this, data_(), size());
  1351. }
  1352. }
  1353. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1354. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::value_type &static_array_4d<T, N0, N1, N2, N3, P, M>::at(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i1, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i2, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i3)
  1355. {
  1356. range_check_(i0, i1, i2, i3);
  1357. return *(m_data + calc_index_(i0, i1, i2, i3));
  1358. }
  1359. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1360. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::value_type const& static_array_4d<T, N0, N1, N2, N3, P, M>::at(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i1, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i2, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i3) const
  1361. {
  1362. range_check_(i0, i1, i2, i3);
  1363. return *(m_data + calc_index_(i0, i1, i2, i3));
  1364. }
  1365. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1366. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::value_type &static_array_4d<T, N0, N1, N2, N3, P, M>::at_unchecked(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i1, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i2, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i3)
  1367. {
  1368. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1 && i2 < N2 && i3 < N3));
  1369. return *(m_data + calc_index_(i0, i1, i2, i3));
  1370. }
  1371. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1372. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::value_type const& static_array_4d<T, N0, N1, N2, N3, P, M>::at_unchecked(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i1, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i2, ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i3) const
  1373. {
  1374. STLSOFT_MESSAGE_ASSERT("static array index out of range", (i0 < N0 && i1 < N1 && i2 < N2 && i3 < N3));
  1375. return *(m_data + calc_index_(i0, i1, i2, i3));
  1376. }
  1377. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1378. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::dimension_type static_array_4d<T, N0, N1, N2, N3, P, M>::at(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0)
  1379. {
  1380. range_check_(i0);
  1381. return dimension_type(m_data + i0 * N1 * N2 * N3);
  1382. }
  1383. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1384. inline const ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::dimension_type static_array_4d<T, N0, N1, N2, N3, P, M>::at(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0) const
  1385. {
  1386. range_check_(i0);
  1387. return dimension_type(m_data + i0 * N1 * N2 * N3);
  1388. }
  1389. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1390. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::dimension_type static_array_4d<T, N0, N1, N2, N3, P, M>::at_unchecked(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0)
  1391. {
  1392. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  1393. return dimension_type(m_data + i0 * N1 * N2 * N3);
  1394. }
  1395. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1396. inline const ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::dimension_type static_array_4d<T, N0, N1, N2, N3, P, M>::at_unchecked(ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0) const
  1397. {
  1398. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  1399. return dimension_type(m_data + i0 * N1 * N2 * N3);
  1400. }
  1401. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1402. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::dimension_type static_array_4d<T, N0, N1, N2, N3, P, M>::operator [](ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0)
  1403. {
  1404. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  1405. return dimension_type(m_data + i0 * N1 * N2 * N3);
  1406. }
  1407. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1408. inline const ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::dimension_type static_array_4d<T, N0, N1, N2, N3, P, M>::operator [](ss_typename_type_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type i0) const
  1409. {
  1410. STLSOFT_MESSAGE_ASSERT("static array index out of range", i0 < N0);
  1411. return dimension_type(m_data + i0 * N1 * N2 * N3);
  1412. }
  1413. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1414. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::reference static_array_4d<T, N0, N1, N2, N3, P, M>::front()
  1415. {
  1416. return at(0, 0, 0, 0);
  1417. }
  1418. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1419. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::reference static_array_4d<T, N0, N1, N2, N3, P, M>::back()
  1420. {
  1421. return at(N0 - 1, N1 - 1, N2 - 1, N3 - 1);
  1422. }
  1423. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1424. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::const_reference static_array_4d<T, N0, N1, N2, N3, P, M>::front() const
  1425. {
  1426. return at(0, 0, 0, 0);
  1427. }
  1428. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1429. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::const_reference static_array_4d<T, N0, N1, N2, N3, P, M>::back() const
  1430. {
  1431. return at(N0 - 1, N1 - 1, N2 - 1, N3 - 1);
  1432. }
  1433. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1434. inline /* static */ ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::dimension0()
  1435. {
  1436. return N0;
  1437. }
  1438. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1439. inline /* static */ ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::dimension1()
  1440. {
  1441. return N1;
  1442. }
  1443. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1444. inline /* static */ ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::dimension2()
  1445. {
  1446. return N2;
  1447. }
  1448. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1449. inline /* static */ ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::dimension3()
  1450. {
  1451. return N3;
  1452. }
  1453. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1454. inline /* static */ ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::size()
  1455. {
  1456. return N0 * N1 * N2 * N3;
  1457. }
  1458. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1459. inline /* static */ ss_bool_t static_array_4d<T, N0, N1, N2, N3, P, M>::empty()
  1460. {
  1461. return false;
  1462. }
  1463. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1464. inline /* static */ ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::index_type static_array_4d<T, N0, N1, N2, N3, P, M>::max_size()
  1465. {
  1466. return size();
  1467. }
  1468. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1469. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::iterator static_array_4d<T, N0, N1, N2, N3, P, M>::begin()
  1470. {
  1471. return m_data;
  1472. }
  1473. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1474. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::iterator static_array_4d<T, N0, N1, N2, N3, P, M>::end()
  1475. {
  1476. return m_data + size();
  1477. }
  1478. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1479. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::const_iterator static_array_4d<T, N0, N1, N2, N3, P, M>::begin() const
  1480. {
  1481. return m_data;
  1482. }
  1483. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1484. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::const_iterator static_array_4d<T, N0, N1, N2, N3, P, M>::end() const
  1485. {
  1486. return m_data + size();
  1487. }
  1488. #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
  1489. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1490. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::reverse_iterator static_array_4d<T, N0, N1, N2, N3, P, M>::rbegin()
  1491. {
  1492. return reverse_iterator(end());
  1493. }
  1494. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1495. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::reverse_iterator static_array_4d<T, N0, N1, N2, N3, P, M>::rend()
  1496. {
  1497. return reverse_iterator(begin());
  1498. }
  1499. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1500. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::const_reverse_iterator static_array_4d<T, N0, N1, N2, N3, P, M>::rbegin() const
  1501. {
  1502. return const_reverse_iterator(end());
  1503. }
  1504. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1505. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::const_reverse_iterator static_array_4d<T, N0, N1, N2, N3, P, M>::rend() const
  1506. {
  1507. return const_reverse_iterator(begin());
  1508. }
  1509. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1510. template <ss_typename_param_k T, ss_size_t N0, ss_size_t N1, ss_size_t N2, ss_size_t N3, ss_typename_param_k P, ss_typename_param_k M>
  1511. inline ss_typename_type_ret_k static_array_4d<T, N0, N1, N2, N3, P, M>::value_type const* static_array_4d<T, N0, N1, N2, N3, P, M>::data() const
  1512. {
  1513. return m_data;
  1514. }
  1515. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1516. /* /////////////////////////////////////////////////////////////////////////
  1517. * Shims
  1518. */
  1519. # if !defined(STLSOFT_COMPILER_IS_MSVC) || \
  1520. _MSC_VER >= 1200
  1521. template< ss_typename_param_k T
  1522. , ss_size_t N0
  1523. , ss_typename_param_k P
  1524. , ss_typename_param_k M
  1525. >
  1526. inline ss_size_t array_size(static_array_1d<T, N0, P, M> const& ar)
  1527. {
  1528. STLSOFT_SUPPRESS_UNUSED(ar); // Required by VC++ 7.1
  1529. return ar.size();
  1530. }
  1531. template< ss_typename_param_k T
  1532. , ss_size_t N0
  1533. , ss_size_t N1
  1534. , ss_typename_param_k P
  1535. , ss_typename_param_k M
  1536. >
  1537. inline ss_size_t array_size(static_array_2d<T, N0, N1, P, M> const& ar)
  1538. {
  1539. STLSOFT_SUPPRESS_UNUSED(ar); // Required by VC++ 7.1
  1540. return ar.size();
  1541. }
  1542. template< ss_typename_param_k T
  1543. , ss_size_t N0
  1544. , ss_size_t N1
  1545. , ss_size_t N2
  1546. , ss_typename_param_k P
  1547. , ss_typename_param_k M
  1548. >
  1549. inline ss_size_t array_size(static_array_3d<T, N0, N1, N2, P, M> const& ar)
  1550. {
  1551. STLSOFT_SUPPRESS_UNUSED(ar); // Required by VC++ 7.1
  1552. return ar.size();
  1553. }
  1554. template< ss_typename_param_k T
  1555. , ss_size_t N0
  1556. , ss_size_t N1
  1557. , ss_size_t N2
  1558. , ss_size_t N3
  1559. , ss_typename_param_k P
  1560. , ss_typename_param_k M
  1561. >
  1562. inline ss_size_t array_size(static_array_4d<T, N0, N1, N2, N3, P, M> const& ar)
  1563. {
  1564. STLSOFT_SUPPRESS_UNUSED(ar); // Required by VC++ 7.1
  1565. return ar.size();
  1566. }
  1567. #if 0
  1568. template< ss_typename_param_k T
  1569. , ss_size_t N0
  1570. , ss_size_t N1
  1571. , ss_size_t N2
  1572. , ss_size_t N3
  1573. , ss_size_t N4
  1574. , ss_typename_param_k P
  1575. , ss_typename_param_k M
  1576. >
  1577. inline ss_size_t array_size(static_array_5d<T, N0, N1, N2, N3, N4, P, M> const& ar)
  1578. {
  1579. STLSOFT_SUPPRESS_UNUSED(ar); // Required by VC++ 7.1
  1580. return ar.size();
  1581. }
  1582. #endif /* 0 */
  1583. #endif /* compiler */
  1584. ////////////////////////////////////////////////////////////////////////////
  1585. // Unit-testing
  1586. #ifdef STLSOFT_UNITTEST
  1587. # include "./unittest/static_array_unittest_.h"
  1588. #endif /* STLSOFT_UNITTEST */
  1589. /* ////////////////////////////////////////////////////////////////////// */
  1590. #ifndef _STLSOFT_NO_NAMESPACE
  1591. } // namespace stlsoft
  1592. #endif /* _STLSOFT_NO_NAMESPACE */
  1593. /* ////////////////////////////////////////////////////////////////////// */
  1594. #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_STATIC_ARRAY */
  1595. /* ///////////////////////////// end of file //////////////////////////// */