/Src/Dependencies/Boost/boost/multi_array/subarray.hpp

http://hadesmem.googlecode.com/ · C++ Header · 399 lines · 295 code · 60 blank · 44 comment · 11 complexity · 35eef657811fe892a74d270bc8753f1e MD5 · raw file

  1. // Copyright 2002 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Boost.MultiArray Library
  6. // Authors: Ronald Garcia
  7. // Jeremy Siek
  8. // Andrew Lumsdaine
  9. // See http://www.boost.org/libs/multi_array for documentation.
  10. #ifndef SUBARRAY_RG071801_HPP
  11. #define SUBARRAY_RG071801_HPP
  12. //
  13. // subarray.hpp - used to implement standard operator[] on
  14. // multi_arrays
  15. //
  16. #include "boost/multi_array/base.hpp"
  17. #include "boost/multi_array/concept_checks.hpp"
  18. #include "boost/limits.hpp"
  19. #include "boost/type.hpp"
  20. #include <algorithm>
  21. #include <cstddef>
  22. #include <functional>
  23. namespace boost {
  24. namespace detail {
  25. namespace multi_array {
  26. //
  27. // const_sub_array
  28. // multi_array's proxy class to allow multiple overloads of
  29. // operator[] in order to provide a clean multi-dimensional array
  30. // interface.
  31. template <typename T, std::size_t NumDims, typename TPtr>
  32. class const_sub_array :
  33. public boost::detail::multi_array::multi_array_impl_base<T,NumDims>
  34. {
  35. typedef boost::detail::multi_array::multi_array_impl_base<T,NumDims> super_type;
  36. public:
  37. typedef typename super_type::value_type value_type;
  38. typedef typename super_type::const_reference const_reference;
  39. typedef typename super_type::const_iterator const_iterator;
  40. typedef typename super_type::const_reverse_iterator const_reverse_iterator;
  41. typedef typename super_type::element element;
  42. typedef typename super_type::size_type size_type;
  43. typedef typename super_type::difference_type difference_type;
  44. typedef typename super_type::index index;
  45. typedef typename super_type::extent_range extent_range;
  46. // template typedefs
  47. template <std::size_t NDims>
  48. struct const_array_view {
  49. typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
  50. };
  51. template <std::size_t NDims>
  52. struct array_view {
  53. typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
  54. };
  55. // Allow default copy constructor as well.
  56. template <typename OPtr>
  57. const_sub_array (const const_sub_array<T,NumDims,OPtr>& rhs) :
  58. base_(rhs.base_), extents_(rhs.extents_), strides_(rhs.strides_),
  59. index_base_(rhs.index_base_) {
  60. }
  61. // const_sub_array always returns const types, regardless of its own
  62. // constness.
  63. const_reference operator[](index idx) const {
  64. return super_type::access(boost::type<const_reference>(),
  65. idx,base_,shape(),strides(),index_bases());
  66. }
  67. template <typename IndexList>
  68. const element& operator()(const IndexList& indices) const {
  69. boost::function_requires<
  70. CollectionConcept<IndexList> >();
  71. return super_type::access_element(boost::type<const element&>(),
  72. indices,origin(),
  73. shape(),strides(),index_bases());
  74. }
  75. // see generate_array_view in base.hpp
  76. #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
  77. template <int NDims>
  78. #else
  79. template <int NumDims, int NDims> // else ICE
  80. #endif // BOOST_MSVC
  81. typename const_array_view<NDims>::type
  82. operator[](const boost::detail::multi_array::
  83. index_gen<NumDims,NDims>& indices)
  84. const {
  85. typedef typename const_array_view<NDims>::type return_type;
  86. return
  87. super_type::generate_array_view(boost::type<return_type>(),
  88. indices,
  89. shape(),
  90. strides(),
  91. index_bases(),
  92. base_);
  93. }
  94. template <typename OPtr>
  95. bool operator<(const const_sub_array<T,NumDims,OPtr>& rhs) const {
  96. return std::lexicographical_compare(begin(),end(),rhs.begin(),rhs.end());
  97. }
  98. template <typename OPtr>
  99. bool operator==(const const_sub_array<T,NumDims,OPtr>& rhs) const {
  100. if(std::equal(shape(),shape()+num_dimensions(),rhs.shape()))
  101. return std::equal(begin(),end(),rhs.begin());
  102. else return false;
  103. }
  104. template <typename OPtr>
  105. bool operator!=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
  106. return !(*this == rhs);
  107. }
  108. template <typename OPtr>
  109. bool operator>(const const_sub_array<T,NumDims,OPtr>& rhs) const {
  110. return rhs < *this;
  111. }
  112. template <typename OPtr>
  113. bool operator<=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
  114. return !(*this > rhs);
  115. }
  116. template <typename OPtr>
  117. bool operator>=(const const_sub_array<T,NumDims,OPtr>& rhs) const {
  118. return !(*this < rhs);
  119. }
  120. const_iterator begin() const {
  121. return const_iterator(*index_bases(),origin(),
  122. shape(),strides(),index_bases());
  123. }
  124. const_iterator end() const {
  125. return const_iterator(*index_bases()+(index)*shape(),origin(),
  126. shape(),strides(),index_bases());
  127. }
  128. const_reverse_iterator rbegin() const {
  129. return const_reverse_iterator(end());
  130. }
  131. const_reverse_iterator rend() const {
  132. return const_reverse_iterator(begin());
  133. }
  134. TPtr origin() const { return base_; }
  135. size_type size() const { return extents_[0]; }
  136. size_type max_size() const { return num_elements(); }
  137. bool empty() const { return size() == 0; }
  138. size_type num_dimensions() const { return NumDims; }
  139. const size_type* shape() const { return extents_; }
  140. const index* strides() const { return strides_; }
  141. const index* index_bases() const { return index_base_; }
  142. size_type num_elements() const {
  143. return std::accumulate(shape(),shape() + num_dimensions(),
  144. size_type(1), std::multiplies<size_type>());
  145. }
  146. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  147. protected:
  148. template <typename,std::size_t> friend class value_accessor_n;
  149. template <typename,std::size_t,typename> friend class const_sub_array;
  150. #else
  151. public: // Should be protected
  152. #endif
  153. const_sub_array (TPtr base,
  154. const size_type* extents,
  155. const index* strides,
  156. const index* index_base) :
  157. base_(base), extents_(extents), strides_(strides),
  158. index_base_(index_base) {
  159. }
  160. TPtr base_;
  161. const size_type* extents_;
  162. const index* strides_;
  163. const index* index_base_;
  164. private:
  165. // const_sub_array cannot be assigned to (no deep copies!)
  166. const_sub_array& operator=(const const_sub_array&);
  167. };
  168. //
  169. // sub_array
  170. // multi_array's proxy class to allow multiple overloads of
  171. // operator[] in order to provide a clean multi-dimensional array
  172. // interface.
  173. template <typename T, std::size_t NumDims>
  174. class sub_array : public const_sub_array<T,NumDims,T*>
  175. {
  176. typedef const_sub_array<T,NumDims,T*> super_type;
  177. public:
  178. typedef typename super_type::element element;
  179. typedef typename super_type::reference reference;
  180. typedef typename super_type::index index;
  181. typedef typename super_type::size_type size_type;
  182. typedef typename super_type::iterator iterator;
  183. typedef typename super_type::reverse_iterator reverse_iterator;
  184. typedef typename super_type::const_reference const_reference;
  185. typedef typename super_type::const_iterator const_iterator;
  186. typedef typename super_type::const_reverse_iterator const_reverse_iterator;
  187. // template typedefs
  188. template <std::size_t NDims>
  189. struct const_array_view {
  190. typedef boost::detail::multi_array::const_multi_array_view<T,NDims> type;
  191. };
  192. template <std::size_t NDims>
  193. struct array_view {
  194. typedef boost::detail::multi_array::multi_array_view<T,NDims> type;
  195. };
  196. // Assignment from other ConstMultiArray types.
  197. template <typename ConstMultiArray>
  198. sub_array& operator=(const ConstMultiArray& other) {
  199. function_requires< boost::multi_array_concepts::ConstMultiArrayConcept<
  200. ConstMultiArray, NumDims> >();
  201. // make sure the dimensions agree
  202. BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
  203. BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
  204. this->shape()));
  205. // iterator-based copy
  206. std::copy(other.begin(),other.end(),begin());
  207. return *this;
  208. }
  209. sub_array& operator=(const sub_array& other) {
  210. if (&other != this) {
  211. // make sure the dimensions agree
  212. BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
  213. BOOST_ASSERT(std::equal(other.shape(),
  214. other.shape()+this->num_dimensions(),
  215. this->shape()));
  216. // iterator-based copy
  217. std::copy(other.begin(),other.end(),begin());
  218. }
  219. return *this;
  220. }
  221. T* origin() { return this->base_; }
  222. const T* origin() const { return this->base_; }
  223. reference operator[](index idx) {
  224. return super_type::access(boost::type<reference>(),
  225. idx,this->base_,this->shape(),this->strides(),
  226. this->index_bases());
  227. }
  228. // see generate_array_view in base.hpp
  229. #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
  230. template <int NDims>
  231. #else
  232. template <int NumDims, int NDims> // else ICE
  233. #endif // BOOST_MSVC
  234. typename array_view<NDims>::type
  235. operator[](const boost::detail::multi_array::
  236. index_gen<NumDims,NDims>& indices) {
  237. typedef typename array_view<NDims>::type return_type;
  238. return
  239. super_type::generate_array_view(boost::type<return_type>(),
  240. indices,
  241. this->shape(),
  242. this->strides(),
  243. this->index_bases(),
  244. origin());
  245. }
  246. template <class IndexList>
  247. element& operator()(const IndexList& indices) {
  248. boost::function_requires<
  249. CollectionConcept<IndexList> >();
  250. return super_type::access_element(boost::type<element&>(),
  251. indices,origin(),
  252. this->shape(),this->strides(),
  253. this->index_bases());
  254. }
  255. iterator begin() {
  256. return iterator(*this->index_bases(),origin(),
  257. this->shape(),this->strides(),this->index_bases());
  258. }
  259. iterator end() {
  260. return iterator(*this->index_bases()+(index)*this->shape(),origin(),
  261. this->shape(),this->strides(),this->index_bases());
  262. }
  263. // RG - rbegin() and rend() written naively to thwart MSVC ICE.
  264. reverse_iterator rbegin() {
  265. reverse_iterator ri(end());
  266. return ri;
  267. }
  268. reverse_iterator rend() {
  269. reverse_iterator ri(begin());
  270. return ri;
  271. }
  272. //
  273. // proxies
  274. //
  275. template <class IndexList>
  276. const element& operator()(const IndexList& indices) const {
  277. boost::function_requires<
  278. CollectionConcept<IndexList> >();
  279. return super_type::operator()(indices);
  280. }
  281. const_reference operator[](index idx) const {
  282. return super_type::operator[](idx);
  283. }
  284. // see generate_array_view in base.hpp
  285. #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
  286. template <int NDims>
  287. #else
  288. template <int NumDims, int NDims> // else ICE
  289. #endif // BOOST_MSVC
  290. typename const_array_view<NDims>::type
  291. operator[](const boost::detail::multi_array::
  292. index_gen<NumDims,NDims>& indices)
  293. const {
  294. return super_type::operator[](indices);
  295. }
  296. const_iterator begin() const {
  297. return super_type::begin();
  298. }
  299. const_iterator end() const {
  300. return super_type::end();
  301. }
  302. const_reverse_iterator rbegin() const {
  303. return super_type::rbegin();
  304. }
  305. const_reverse_iterator rend() const {
  306. return super_type::rend();
  307. }
  308. #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
  309. private:
  310. template <typename,std::size_t> friend class value_accessor_n;
  311. #else
  312. public: // should be private
  313. #endif
  314. sub_array (T* base,
  315. const size_type* extents,
  316. const index* strides,
  317. const index* index_base) :
  318. super_type(base,extents,strides,index_base) {
  319. }
  320. };
  321. } // namespace multi_array
  322. } // namespace detail
  323. //
  324. // traits classes to get sub_array types
  325. //
  326. template <typename Array, int N>
  327. class subarray_gen {
  328. typedef typename Array::element element;
  329. public:
  330. typedef boost::detail::multi_array::sub_array<element,N> type;
  331. };
  332. template <typename Array, int N>
  333. class const_subarray_gen {
  334. typedef typename Array::element element;
  335. public:
  336. typedef boost::detail::multi_array::const_sub_array<element,N> type;
  337. };
  338. } // namespace boost
  339. #endif // SUBARRAY_RG071801_HPP