//---------------------------------------------------------------------------// // 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_PERMUTATION_ITERATOR_HPP #define BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace compute { // forward declaration for transform_iterator template class permutation_iterator; namespace detail { // helper class which defines the iterator_adaptor super-class // type for permutation_iterator template class permutation_iterator_base { public: typedef ::boost::iterator_adaptor< ::boost::compute::permutation_iterator, ElementIterator > type; }; template struct permutation_iterator_access_expr { typedef typename std::iterator_traits::value_type result_type; permutation_iterator_access_expr(const ElementIterator &e, const IndexIterator &i, const IndexExpr &expr) : m_element_iter(e), m_index_iter(i), m_expr(expr) { } const ElementIterator m_element_iter; const IndexIterator m_index_iter; const IndexExpr m_expr; }; template inline meta_kernel& operator<<(meta_kernel &kernel, const permutation_iterator_access_expr &expr) { return kernel << expr.m_element_iter[expr.m_index_iter[expr.m_expr]]; } } // end detail namespace /// \class permutation_iterator /// \brief The permutation_iterator class provides a permuation iterator /// /// A permutation iterator iterates over a value range and an index range. When /// dereferenced, it returns the value from the value range using the current /// index from the index range. /// /// For example, to reverse a range using the copy() algorithm and a permutation /// sequence: /// /// \snippet test/test_permutation_iterator.cpp reverse_range /// /// \see make_permutation_iterator() template class permutation_iterator : public detail::permutation_iterator_base::type { public: typedef typename detail::permutation_iterator_base::type super_type; typedef typename super_type::value_type value_type; typedef typename super_type::reference reference; typedef typename super_type::base_type base_type; typedef typename super_type::difference_type difference_type; typedef IndexIterator index_iterator; permutation_iterator(ElementIterator e, IndexIterator i) : super_type(e), m_map(i) { } permutation_iterator(const permutation_iterator &other) : super_type(other), m_map(other.m_map) { } permutation_iterator& operator=(const permutation_iterator &other) { if(this != &other){ super_type::operator=(other); m_map = other.m_map; } return *this; } ~permutation_iterator() { } size_t get_index() const { return super_type::base().get_index(); } const buffer& get_buffer() const { return detail::get_base_iterator_buffer(*this); } template detail::permutation_iterator_access_expr operator[](const IndexExpr &expr) const { return detail::permutation_iterator_access_expr(super_type::base(), m_map, expr); } private: friend class ::boost::iterator_core_access; reference dereference() const { return reference(); } private: IndexIterator m_map; }; /// Returns a permutation_iterator for \p e using indices from \p i. /// /// \param e the element range iterator /// \param i the index range iterator /// /// \return a \c permutation_iterator for \p e using \p i template inline permutation_iterator make_permutation_iterator(ElementIterator e, IndexIterator i) { return permutation_iterator(e, i); } /// \internal_ (is_device_iterator specialization for permutation_iterator) template struct is_device_iterator< permutation_iterator > : boost::true_type {}; } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP