File indexing completed on 2025-01-18 09:30:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP
0012 #define BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP
0013
0014 #include <cstddef>
0015 #include <iterator>
0016
0017 #include <boost/iterator/iterator_facade.hpp>
0018
0019 #include <boost/compute/buffer.hpp>
0020 #include <boost/compute/iterator/buffer_iterator.hpp>
0021 #include <boost/compute/type_traits/is_device_iterator.hpp>
0022
0023 namespace boost {
0024 namespace compute {
0025
0026
0027 template<class T> class constant_buffer_iterator;
0028
0029 namespace detail {
0030
0031
0032
0033 template<class T>
0034 class constant_buffer_iterator_base
0035 {
0036 public:
0037 typedef ::boost::iterator_facade<
0038 ::boost::compute::constant_buffer_iterator<T>,
0039 T,
0040 ::std::random_access_iterator_tag,
0041 ::boost::compute::detail::buffer_value<T>
0042 > type;
0043 };
0044
0045 }
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 template<class T>
0058 class constant_buffer_iterator :
0059 public detail::constant_buffer_iterator_base<T>::type
0060 {
0061 public:
0062 typedef typename detail::constant_buffer_iterator_base<T>::type super_type;
0063 typedef typename super_type::reference reference;
0064 typedef typename super_type::difference_type difference_type;
0065
0066 constant_buffer_iterator()
0067 : m_buffer(0),
0068 m_index(0)
0069 {
0070 }
0071
0072 constant_buffer_iterator(const buffer &buffer, size_t index)
0073 : m_buffer(&buffer),
0074 m_index(index)
0075 {
0076 }
0077
0078 constant_buffer_iterator(const constant_buffer_iterator<T> &other)
0079 : m_buffer(other.m_buffer),
0080 m_index(other.m_index)
0081 {
0082 }
0083
0084 constant_buffer_iterator<T>& operator=(const constant_buffer_iterator<T> &other)
0085 {
0086 if(this != &other){
0087 m_buffer = other.m_buffer;
0088 m_index = other.m_index;
0089 }
0090
0091 return *this;
0092 }
0093
0094 ~constant_buffer_iterator()
0095 {
0096 }
0097
0098 const buffer& get_buffer() const
0099 {
0100 return *m_buffer;
0101 }
0102
0103 size_t get_index() const
0104 {
0105 return m_index;
0106 }
0107
0108 T read(command_queue &queue) const
0109 {
0110 BOOST_ASSERT(m_buffer && m_buffer->get());
0111 BOOST_ASSERT(m_index < m_buffer->size() / sizeof(T));
0112
0113 return detail::read_single_value<T>(m_buffer, m_index, queue);
0114 }
0115
0116 void write(const T &value, command_queue &queue)
0117 {
0118 BOOST_ASSERT(m_buffer && m_buffer->get());
0119 BOOST_ASSERT(m_index < m_buffer->size() / sizeof(T));
0120
0121 detail::write_single_value<T>(m_buffer, m_index, queue);
0122 }
0123
0124 template<class Expr>
0125 detail::buffer_iterator_index_expr<T, Expr>
0126 operator[](const Expr &expr) const
0127 {
0128 BOOST_ASSERT(m_buffer);
0129 BOOST_ASSERT(m_buffer->get());
0130
0131 return detail::buffer_iterator_index_expr<T, Expr>(
0132 *m_buffer, m_index, memory_object::constant_memory, expr
0133 );
0134 }
0135
0136 private:
0137 friend class ::boost::iterator_core_access;
0138
0139 reference dereference() const
0140 {
0141 return detail::buffer_value<T>(*m_buffer, m_index);
0142 }
0143
0144 bool equal(const constant_buffer_iterator<T> &other) const
0145 {
0146 return m_buffer == other.m_buffer && m_index == other.m_index;
0147 }
0148
0149 void increment()
0150 {
0151 m_index++;
0152 }
0153
0154 void decrement()
0155 {
0156 m_index--;
0157 }
0158
0159 void advance(difference_type n)
0160 {
0161 m_index = static_cast<size_t>(static_cast<difference_type>(m_index) + n);
0162 }
0163
0164 difference_type distance_to(const constant_buffer_iterator<T> &other) const
0165 {
0166 return static_cast<difference_type>(other.m_index - m_index);
0167 }
0168
0169 private:
0170 const buffer *m_buffer;
0171 size_t m_index;
0172 };
0173
0174
0175
0176
0177
0178
0179
0180 template<class T>
0181 inline constant_buffer_iterator<T>
0182 make_constant_buffer_iterator(const buffer &buffer, size_t index = 0)
0183 {
0184 return constant_buffer_iterator<T>(buffer, index);
0185 }
0186
0187
0188 template<class T>
0189 struct is_device_iterator<constant_buffer_iterator<T> > : boost::true_type {};
0190
0191 namespace detail {
0192
0193
0194 template<class Iterator>
0195 struct is_buffer_iterator<
0196 Iterator,
0197 typename boost::enable_if<
0198 boost::is_same<
0199 constant_buffer_iterator<typename Iterator::value_type>,
0200 typename boost::remove_const<Iterator>::type
0201 >
0202 >::type
0203 > : public boost::true_type {};
0204
0205 }
0206 }
0207 }
0208
0209 #endif