Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:02

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
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 // forward declaration for constant_buffer_iterator<T>
0027 template<class T> class constant_buffer_iterator;
0028 
0029 namespace detail {
0030 
0031 // helper class which defines the iterator_facade super-class
0032 // type for constant_buffer_iterator<T>
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 } // end detail namespace
0046 
0047 /// \class constant_buffer_iterator
0048 /// \brief An iterator for a buffer in the \c constant memory space.
0049 ///
0050 /// The constant_buffer_iterator class provides an iterator for values in a
0051 /// buffer in the \c constant memory space.
0052 ///
0053 /// For iterating over values in the \c global memory space (the most common
0054 /// case), use the buffer_iterator class.
0055 ///
0056 /// \see buffer_iterator
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 /// Creates a new constant_buffer_iterator for \p buffer at \p index.
0175 ///
0176 /// \param buffer the \ref buffer object
0177 /// \param index the index in the buffer
0178 ///
0179 /// \return a \c constant_buffer_iterator for \p buffer at \p index
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 /// \internal_ (is_device_iterator specialization for constant_buffer_iterator)
0188 template<class T>
0189 struct is_device_iterator<constant_buffer_iterator<T> > : boost::true_type {};
0190 
0191 namespace detail {
0192 
0193 // is_buffer_iterator specialization for constant_buffer_iterator
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 } // end detail namespace
0206 } // end compute namespace
0207 } // end boost namespace
0208 
0209 #endif // BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP