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_PERMUTATION_ITERATOR_HPP
0012 #define BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
0013 
0014 #include <string>
0015 #include <cstddef>
0016 #include <iterator>
0017 
0018 #include <boost/config.hpp>
0019 #include <boost/iterator/iterator_adaptor.hpp>
0020 
0021 #include <boost/compute/functional.hpp>
0022 #include <boost/compute/detail/meta_kernel.hpp>
0023 #include <boost/compute/detail/is_buffer_iterator.hpp>
0024 #include <boost/compute/detail/read_write_single_value.hpp>
0025 #include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp>
0026 #include <boost/compute/type_traits/is_device_iterator.hpp>
0027 
0028 namespace boost {
0029 namespace compute {
0030 
0031 // forward declaration for transform_iterator
0032 template<class ElementIterator, class IndexIterator>
0033 class permutation_iterator;
0034 
0035 namespace detail {
0036 
0037 // helper class which defines the iterator_adaptor super-class
0038 // type for permutation_iterator
0039 template<class ElementIterator, class IndexIterator>
0040 class permutation_iterator_base
0041 {
0042 public:
0043     typedef ::boost::iterator_adaptor<
0044         ::boost::compute::permutation_iterator<ElementIterator, IndexIterator>,
0045         ElementIterator
0046     > type;
0047 };
0048 
0049 template<class ElementIterator, class IndexIterator, class IndexExpr>
0050 struct permutation_iterator_access_expr
0051 {
0052     typedef typename std::iterator_traits<ElementIterator>::value_type result_type;
0053 
0054     permutation_iterator_access_expr(const ElementIterator &e,
0055                                      const IndexIterator &i,
0056                                      const IndexExpr &expr)
0057         : m_element_iter(e),
0058           m_index_iter(i),
0059           m_expr(expr)
0060     {
0061     }
0062 
0063     const ElementIterator m_element_iter;
0064     const IndexIterator m_index_iter;
0065     const IndexExpr m_expr;
0066 };
0067 
0068 template<class ElementIterator, class IndexIterator, class IndexExpr>
0069 inline meta_kernel& operator<<(meta_kernel &kernel,
0070                                const permutation_iterator_access_expr<ElementIterator,
0071                                                                       IndexIterator,
0072                                                                       IndexExpr> &expr)
0073 {
0074     return kernel << expr.m_element_iter[expr.m_index_iter[expr.m_expr]];
0075 }
0076 
0077 } // end detail namespace
0078 
0079 /// \class permutation_iterator
0080 /// \brief The permutation_iterator class provides a permuation iterator
0081 ///
0082 /// A permutation iterator iterates over a value range and an index range. When
0083 /// dereferenced, it returns the value from the value range using the current
0084 /// index from the index range.
0085 ///
0086 /// For example, to reverse a range using the copy() algorithm and a permutation
0087 /// sequence:
0088 ///
0089 /// \snippet test/test_permutation_iterator.cpp reverse_range
0090 ///
0091 /// \see make_permutation_iterator()
0092 template<class ElementIterator, class IndexIterator>
0093 class permutation_iterator
0094     : public detail::permutation_iterator_base<ElementIterator,
0095                                                IndexIterator>::type
0096 {
0097 public:
0098     typedef typename
0099         detail::permutation_iterator_base<ElementIterator,
0100                                           IndexIterator>::type super_type;
0101     typedef typename super_type::value_type value_type;
0102     typedef typename super_type::reference reference;
0103     typedef typename super_type::base_type base_type;
0104     typedef typename super_type::difference_type difference_type;
0105     typedef IndexIterator index_iterator;
0106 
0107     permutation_iterator(ElementIterator e, IndexIterator i)
0108         : super_type(e),
0109           m_map(i)
0110     {
0111     }
0112 
0113     permutation_iterator(const permutation_iterator<ElementIterator,
0114                                                     IndexIterator> &other)
0115         : super_type(other),
0116           m_map(other.m_map)
0117     {
0118     }
0119 
0120     permutation_iterator<ElementIterator, IndexIterator>&
0121     operator=(const permutation_iterator<ElementIterator,
0122                                          IndexIterator> &other)
0123     {
0124         if(this != &other){
0125             super_type::operator=(other);
0126             m_map = other.m_map;
0127         }
0128 
0129         return *this;
0130     }
0131 
0132     ~permutation_iterator()
0133     {
0134     }
0135 
0136     size_t get_index() const
0137     {
0138         return super_type::base().get_index();
0139     }
0140 
0141     const buffer& get_buffer() const
0142     {
0143         return detail::get_base_iterator_buffer(*this);
0144     }
0145 
0146     template<class IndexExpr>
0147     detail::permutation_iterator_access_expr<ElementIterator,
0148                                              IndexIterator,
0149                                              IndexExpr>
0150     operator[](const IndexExpr &expr) const
0151     {
0152         return detail::permutation_iterator_access_expr<ElementIterator,
0153                                                         IndexIterator,
0154                                                         IndexExpr>(super_type::base(),
0155                                                                    m_map,
0156                                                                    expr);
0157     }
0158 
0159 private:
0160     friend class ::boost::iterator_core_access;
0161 
0162     reference dereference() const
0163     {
0164         return reference();
0165     }
0166 
0167 private:
0168     IndexIterator m_map;
0169 };
0170 
0171 /// Returns a permutation_iterator for \p e using indices from \p i.
0172 ///
0173 /// \param e the element range iterator
0174 /// \param i the index range iterator
0175 ///
0176 /// \return a \c permutation_iterator for \p e using \p i
0177 template<class ElementIterator, class IndexIterator>
0178 inline permutation_iterator<ElementIterator, IndexIterator>
0179 make_permutation_iterator(ElementIterator e, IndexIterator i)
0180 {
0181     return permutation_iterator<ElementIterator, IndexIterator>(e, i);
0182 }
0183 
0184 /// \internal_ (is_device_iterator specialization for permutation_iterator)
0185 template<class ElementIterator, class IndexIterator>
0186 struct is_device_iterator<
0187     permutation_iterator<ElementIterator, IndexIterator> > : boost::true_type {};
0188 
0189 } // end compute namespace
0190 } // end boost namespace
0191 
0192 #endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP