//---------------------------------------------------------------------------// // Copyright (c) 2013 Kyle Lutz // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // // See http://boostorg.github.com/compute for more information. //---------------------------------------------------------------------------// #ifndef BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP #define BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP #include #include #include #include #include #include namespace boost { namespace compute { // forward declaration for constant_buffer_iterator template class constant_buffer_iterator; namespace detail { // helper class which defines the iterator_facade super-class // type for constant_buffer_iterator template class constant_buffer_iterator_base { public: typedef ::boost::iterator_facade< ::boost::compute::constant_buffer_iterator, T, ::std::random_access_iterator_tag, ::boost::compute::detail::buffer_value > type; }; } // end detail namespace /// \class constant_buffer_iterator /// \brief An iterator for a buffer in the \c constant memory space. /// /// The constant_buffer_iterator class provides an iterator for values in a /// buffer in the \c constant memory space. /// /// For iterating over values in the \c global memory space (the most common /// case), use the buffer_iterator class. /// /// \see buffer_iterator template class constant_buffer_iterator : public detail::constant_buffer_iterator_base::type { public: typedef typename detail::constant_buffer_iterator_base::type super_type; typedef typename super_type::reference reference; typedef typename super_type::difference_type difference_type; constant_buffer_iterator() : m_buffer(0), m_index(0) { } constant_buffer_iterator(const buffer &buffer, size_t index) : m_buffer(&buffer), m_index(index) { } constant_buffer_iterator(const constant_buffer_iterator &other) : m_buffer(other.m_buffer), m_index(other.m_index) { } constant_buffer_iterator& operator=(const constant_buffer_iterator &other) { if(this != &other){ m_buffer = other.m_buffer; m_index = other.m_index; } return *this; } ~constant_buffer_iterator() { } const buffer& get_buffer() const { return *m_buffer; } size_t get_index() const { return m_index; } T read(command_queue &queue) const { BOOST_ASSERT(m_buffer && m_buffer->get()); BOOST_ASSERT(m_index < m_buffer->size() / sizeof(T)); return detail::read_single_value(m_buffer, m_index, queue); } void write(const T &value, command_queue &queue) { BOOST_ASSERT(m_buffer && m_buffer->get()); BOOST_ASSERT(m_index < m_buffer->size() / sizeof(T)); detail::write_single_value(m_buffer, m_index, queue); } template detail::buffer_iterator_index_expr operator[](const Expr &expr) const { BOOST_ASSERT(m_buffer); BOOST_ASSERT(m_buffer->get()); return detail::buffer_iterator_index_expr( *m_buffer, m_index, memory_object::constant_memory, expr ); } private: friend class ::boost::iterator_core_access; reference dereference() const { return detail::buffer_value(*m_buffer, m_index); } bool equal(const constant_buffer_iterator &other) const { return m_buffer == other.m_buffer && m_index == other.m_index; } void increment() { m_index++; } void decrement() { m_index--; } void advance(difference_type n) { m_index = static_cast(static_cast(m_index) + n); } difference_type distance_to(const constant_buffer_iterator &other) const { return static_cast(other.m_index - m_index); } private: const buffer *m_buffer; size_t m_index; }; /// Creates a new constant_buffer_iterator for \p buffer at \p index. /// /// \param buffer the \ref buffer object /// \param index the index in the buffer /// /// \return a \c constant_buffer_iterator for \p buffer at \p index template inline constant_buffer_iterator make_constant_buffer_iterator(const buffer &buffer, size_t index = 0) { return constant_buffer_iterator(buffer, index); } /// \internal_ (is_device_iterator specialization for constant_buffer_iterator) template struct is_device_iterator > : boost::true_type {}; namespace detail { // is_buffer_iterator specialization for constant_buffer_iterator template struct is_buffer_iterator< Iterator, typename boost::enable_if< boost::is_same< constant_buffer_iterator, typename boost::remove_const::type > >::type > : public boost::true_type {}; } // end detail namespace } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_ITERATOR_CONSTANT_BUFFER_ITERATOR_HPP