//---------------------------------------------------------------------------// // 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_ITERATOR_HPP #define BOOST_COMPUTE_ITERATOR_CONSTANT_ITERATOR_HPP #include #include #include #include #include #include #include namespace boost { namespace compute { // forward declaration for constant_iterator template class constant_iterator; namespace detail { // helper class which defines the iterator_facade super-class // type for constant_iterator template class constant_iterator_base { public: typedef ::boost::iterator_facade< ::boost::compute::constant_iterator, T, ::std::random_access_iterator_tag > type; }; } // end detail namespace /// \class constant_iterator /// \brief An iterator with a constant value. /// /// The constant_iterator class provides an iterator which returns a constant /// value when dereferenced. /// /// For example, this could be used to implement the fill() algorithm in terms /// of the copy() algorithm by copying from a range of constant iterators: /// /// \snippet test/test_constant_iterator.cpp fill_with_copy /// /// \see make_constant_iterator() template class constant_iterator : public detail::constant_iterator_base::type { public: typedef typename detail::constant_iterator_base::type super_type; typedef typename super_type::reference reference; typedef typename super_type::difference_type difference_type; constant_iterator(const T &value, size_t index = 0) : m_value(value), m_index(index) { } constant_iterator(const constant_iterator &other) : m_value(other.m_value), m_index(other.m_index) { } constant_iterator& operator=(const constant_iterator &other) { if(this != &other){ m_value = other.m_value; m_index = other.m_index; } return *this; } ~constant_iterator() { } size_t get_index() const { return m_index; } /// \internal_ template detail::meta_kernel_literal operator[](const Expr &expr) const { (void) expr; return detail::meta_kernel::make_lit(m_value); } private: friend class ::boost::iterator_core_access; /// \internal_ reference dereference() const { return m_value; } /// \internal_ bool equal(const constant_iterator &other) const { return m_value == other.m_value && m_index == other.m_index; } /// \internal_ void increment() { m_index++; } /// \internal_ void decrement() { m_index--; } /// \internal_ void advance(difference_type n) { m_index = static_cast(static_cast(m_index) + n); } /// \internal_ difference_type distance_to(const constant_iterator &other) const { return static_cast(other.m_index - m_index); } private: T m_value; size_t m_index; }; /// Returns a new constant_iterator with \p value at \p index. /// /// \param value the constant value /// \param index the iterators index /// /// \return a \c constant_iterator with \p value template inline constant_iterator make_constant_iterator(const T &value, size_t index = 0) { return constant_iterator(value, index); } /// \internal_ (is_device_iterator specialization for constant_iterator) template struct is_device_iterator > : boost::true_type {}; } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_ITERATOR_CONSTANT_ITERATOR_HPP