constant_buffer_iterator.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 Kyle Lutz <[email protected]>
  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_CONSTANT_BUFFER_ITERATOR_HPP
  11. #define BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP
  12. #include <cstddef>
  13. #include <iterator>
  14. #include <boost/iterator/iterator_facade.hpp>
  15. #include <boost/compute/buffer.hpp>
  16. #include <boost/compute/iterator/buffer_iterator.hpp>
  17. #include <boost/compute/type_traits/is_device_iterator.hpp>
  18. namespace boost {
  19. namespace compute {
  20. // forward declaration for constant_buffer_iterator<T>
  21. template<class T> class constant_buffer_iterator;
  22. namespace detail {
  23. // helper class which defines the iterator_facade super-class
  24. // type for constant_buffer_iterator<T>
  25. template<class T>
  26. class constant_buffer_iterator_base
  27. {
  28. public:
  29. typedef ::boost::iterator_facade<
  30. ::boost::compute::constant_buffer_iterator<T>,
  31. T,
  32. ::std::random_access_iterator_tag,
  33. ::boost::compute::detail::buffer_value<T>
  34. > type;
  35. };
  36. } // end detail namespace
  37. /// \class constant_buffer_iterator
  38. /// \brief An iterator for a buffer in the \c constant memory space.
  39. ///
  40. /// The constant_buffer_iterator class provides an iterator for values in a
  41. /// buffer in the \c constant memory space.
  42. ///
  43. /// For iterating over values in the \c global memory space (the most common
  44. /// case), use the buffer_iterator class.
  45. ///
  46. /// \see buffer_iterator
  47. template<class T>
  48. class constant_buffer_iterator :
  49. public detail::constant_buffer_iterator_base<T>::type
  50. {
  51. public:
  52. typedef typename detail::constant_buffer_iterator_base<T>::type super_type;
  53. typedef typename super_type::reference reference;
  54. typedef typename super_type::difference_type difference_type;
  55. constant_buffer_iterator()
  56. : m_buffer(0),
  57. m_index(0)
  58. {
  59. }
  60. constant_buffer_iterator(const buffer &buffer, size_t index)
  61. : m_buffer(&buffer),
  62. m_index(index)
  63. {
  64. }
  65. constant_buffer_iterator(const constant_buffer_iterator<T> &other)
  66. : m_buffer(other.m_buffer),
  67. m_index(other.m_index)
  68. {
  69. }
  70. constant_buffer_iterator<T>& operator=(const constant_buffer_iterator<T> &other)
  71. {
  72. if(this != &other){
  73. m_buffer = other.m_buffer;
  74. m_index = other.m_index;
  75. }
  76. return *this;
  77. }
  78. ~constant_buffer_iterator()
  79. {
  80. }
  81. const buffer& get_buffer() const
  82. {
  83. return *m_buffer;
  84. }
  85. size_t get_index() const
  86. {
  87. return m_index;
  88. }
  89. T read(command_queue &queue) const
  90. {
  91. BOOST_ASSERT(m_buffer && m_buffer->get());
  92. BOOST_ASSERT(m_index < m_buffer->size() / sizeof(T));
  93. return detail::read_single_value<T>(m_buffer, m_index, queue);
  94. }
  95. void write(const T &value, command_queue &queue)
  96. {
  97. BOOST_ASSERT(m_buffer && m_buffer->get());
  98. BOOST_ASSERT(m_index < m_buffer->size() / sizeof(T));
  99. detail::write_single_value<T>(m_buffer, m_index, queue);
  100. }
  101. template<class Expr>
  102. detail::buffer_iterator_index_expr<T, Expr>
  103. operator[](const Expr &expr) const
  104. {
  105. BOOST_ASSERT(m_buffer);
  106. BOOST_ASSERT(m_buffer->get());
  107. return detail::buffer_iterator_index_expr<T, Expr>(
  108. *m_buffer, m_index, memory_object::constant_memory, expr
  109. );
  110. }
  111. private:
  112. friend class ::boost::iterator_core_access;
  113. reference dereference() const
  114. {
  115. return detail::buffer_value<T>(*m_buffer, m_index);
  116. }
  117. bool equal(const constant_buffer_iterator<T> &other) const
  118. {
  119. return m_buffer == other.m_buffer && m_index == other.m_index;
  120. }
  121. void increment()
  122. {
  123. m_index++;
  124. }
  125. void decrement()
  126. {
  127. m_index--;
  128. }
  129. void advance(difference_type n)
  130. {
  131. m_index = static_cast<size_t>(static_cast<difference_type>(m_index) + n);
  132. }
  133. difference_type distance_to(const constant_buffer_iterator<T> &other) const
  134. {
  135. return static_cast<difference_type>(other.m_index - m_index);
  136. }
  137. private:
  138. const buffer *m_buffer;
  139. size_t m_index;
  140. };
  141. /// Creates a new constant_buffer_iterator for \p buffer at \p index.
  142. ///
  143. /// \param buffer the \ref buffer object
  144. /// \param index the index in the buffer
  145. ///
  146. /// \return a \c constant_buffer_iterator for \p buffer at \p index
  147. template<class T>
  148. inline constant_buffer_iterator<T>
  149. make_constant_buffer_iterator(const buffer &buffer, size_t index = 0)
  150. {
  151. return constant_buffer_iterator<T>(buffer, index);
  152. }
  153. /// \internal_ (is_device_iterator specialization for constant_buffer_iterator)
  154. template<class T>
  155. struct is_device_iterator<constant_buffer_iterator<T> > : boost::true_type {};
  156. namespace detail {
  157. // is_buffer_iterator specialization for constant_buffer_iterator
  158. template<class Iterator>
  159. struct is_buffer_iterator<
  160. Iterator,
  161. typename boost::enable_if<
  162. boost::is_same<
  163. constant_buffer_iterator<typename Iterator::value_type>,
  164. typename boost::remove_const<Iterator>::type
  165. >
  166. >::type
  167. > : public boost::true_type {};
  168. } // end detail namespace
  169. } // end compute namespace
  170. } // end boost namespace
  171. #endif // BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP