permutation_iterator.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #ifndef BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
  11. #define BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
  12. #include <string>
  13. #include <cstddef>
  14. #include <iterator>
  15. #include <boost/config.hpp>
  16. #include <boost/iterator/iterator_adaptor.hpp>
  17. #include <boost/compute/functional.hpp>
  18. #include <boost/compute/detail/meta_kernel.hpp>
  19. #include <boost/compute/detail/is_buffer_iterator.hpp>
  20. #include <boost/compute/detail/read_write_single_value.hpp>
  21. #include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp>
  22. #include <boost/compute/type_traits/is_device_iterator.hpp>
  23. namespace boost {
  24. namespace compute {
  25. // forward declaration for transform_iterator
  26. template<class ElementIterator, class IndexIterator>
  27. class permutation_iterator;
  28. namespace detail {
  29. // helper class which defines the iterator_adaptor super-class
  30. // type for permutation_iterator
  31. template<class ElementIterator, class IndexIterator>
  32. class permutation_iterator_base
  33. {
  34. public:
  35. typedef ::boost::iterator_adaptor<
  36. ::boost::compute::permutation_iterator<ElementIterator, IndexIterator>,
  37. ElementIterator
  38. > type;
  39. };
  40. template<class ElementIterator, class IndexIterator, class IndexExpr>
  41. struct permutation_iterator_access_expr
  42. {
  43. typedef typename std::iterator_traits<ElementIterator>::value_type result_type;
  44. permutation_iterator_access_expr(const ElementIterator &e,
  45. const IndexIterator &i,
  46. const IndexExpr &expr)
  47. : m_element_iter(e),
  48. m_index_iter(i),
  49. m_expr(expr)
  50. {
  51. }
  52. const ElementIterator m_element_iter;
  53. const IndexIterator m_index_iter;
  54. const IndexExpr m_expr;
  55. };
  56. template<class ElementIterator, class IndexIterator, class IndexExpr>
  57. inline meta_kernel& operator<<(meta_kernel &kernel,
  58. const permutation_iterator_access_expr<ElementIterator,
  59. IndexIterator,
  60. IndexExpr> &expr)
  61. {
  62. return kernel << expr.m_element_iter[expr.m_index_iter[expr.m_expr]];
  63. }
  64. } // end detail namespace
  65. /// \class permutation_iterator
  66. /// \brief The permutation_iterator class provides a permuation iterator
  67. ///
  68. /// A permutation iterator iterates over a value range and an index range. When
  69. /// dereferenced, it returns the value from the value range using the current
  70. /// index from the index range.
  71. ///
  72. /// For example, to reverse a range using the copy() algorithm and a permutation
  73. /// sequence:
  74. ///
  75. /// \snippet test/test_permutation_iterator.cpp reverse_range
  76. ///
  77. /// \see make_permutation_iterator()
  78. template<class ElementIterator, class IndexIterator>
  79. class permutation_iterator
  80. : public detail::permutation_iterator_base<ElementIterator,
  81. IndexIterator>::type
  82. {
  83. public:
  84. typedef typename
  85. detail::permutation_iterator_base<ElementIterator,
  86. IndexIterator>::type super_type;
  87. typedef typename super_type::value_type value_type;
  88. typedef typename super_type::reference reference;
  89. typedef typename super_type::base_type base_type;
  90. typedef typename super_type::difference_type difference_type;
  91. typedef IndexIterator index_iterator;
  92. permutation_iterator(ElementIterator e, IndexIterator i)
  93. : super_type(e),
  94. m_map(i)
  95. {
  96. }
  97. permutation_iterator(const permutation_iterator<ElementIterator,
  98. IndexIterator> &other)
  99. : super_type(other),
  100. m_map(other.m_map)
  101. {
  102. }
  103. permutation_iterator<ElementIterator, IndexIterator>&
  104. operator=(const permutation_iterator<ElementIterator,
  105. IndexIterator> &other)
  106. {
  107. if(this != &other){
  108. super_type::operator=(other);
  109. m_map = other.m_map;
  110. }
  111. return *this;
  112. }
  113. ~permutation_iterator()
  114. {
  115. }
  116. size_t get_index() const
  117. {
  118. return super_type::base().get_index();
  119. }
  120. const buffer& get_buffer() const
  121. {
  122. return detail::get_base_iterator_buffer(*this);
  123. }
  124. template<class IndexExpr>
  125. detail::permutation_iterator_access_expr<ElementIterator,
  126. IndexIterator,
  127. IndexExpr>
  128. operator[](const IndexExpr &expr) const
  129. {
  130. return detail::permutation_iterator_access_expr<ElementIterator,
  131. IndexIterator,
  132. IndexExpr>(super_type::base(),
  133. m_map,
  134. expr);
  135. }
  136. private:
  137. friend class ::boost::iterator_core_access;
  138. reference dereference() const
  139. {
  140. return reference();
  141. }
  142. private:
  143. IndexIterator m_map;
  144. };
  145. /// Returns a permutation_iterator for \p e using indices from \p i.
  146. ///
  147. /// \param e the element range iterator
  148. /// \param i the index range iterator
  149. ///
  150. /// \return a \c permutation_iterator for \p e using \p i
  151. template<class ElementIterator, class IndexIterator>
  152. inline permutation_iterator<ElementIterator, IndexIterator>
  153. make_permutation_iterator(ElementIterator e, IndexIterator i)
  154. {
  155. return permutation_iterator<ElementIterator, IndexIterator>(e, i);
  156. }
  157. /// \internal_ (is_device_iterator specialization for permutation_iterator)
  158. template<class ElementIterator, class IndexIterator>
  159. struct is_device_iterator<
  160. permutation_iterator<ElementIterator, IndexIterator> > : boost::true_type {};
  161. } // end compute namespace
  162. } // end boost namespace
  163. #endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP