193 lines
6.3 KiB
Plaintext
193 lines
6.3 KiB
Plaintext
|
//---------------------------------------------------------------------------//
|
||
|
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
|
||
|
//
|
||
|
// 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 <string>
|
||
|
#include <cstddef>
|
||
|
#include <iterator>
|
||
|
|
||
|
#include <boost/config.hpp>
|
||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||
|
|
||
|
#include <boost/compute/functional.hpp>
|
||
|
#include <boost/compute/detail/meta_kernel.hpp>
|
||
|
#include <boost/compute/detail/is_buffer_iterator.hpp>
|
||
|
#include <boost/compute/detail/read_write_single_value.hpp>
|
||
|
#include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp>
|
||
|
#include <boost/compute/type_traits/is_device_iterator.hpp>
|
||
|
|
||
|
namespace boost {
|
||
|
namespace compute {
|
||
|
|
||
|
// forward declaration for transform_iterator
|
||
|
template<class ElementIterator, class IndexIterator>
|
||
|
class permutation_iterator;
|
||
|
|
||
|
namespace detail {
|
||
|
|
||
|
// helper class which defines the iterator_adaptor super-class
|
||
|
// type for permutation_iterator
|
||
|
template<class ElementIterator, class IndexIterator>
|
||
|
class permutation_iterator_base
|
||
|
{
|
||
|
public:
|
||
|
typedef ::boost::iterator_adaptor<
|
||
|
::boost::compute::permutation_iterator<ElementIterator, IndexIterator>,
|
||
|
ElementIterator
|
||
|
> type;
|
||
|
};
|
||
|
|
||
|
template<class ElementIterator, class IndexIterator, class IndexExpr>
|
||
|
struct permutation_iterator_access_expr
|
||
|
{
|
||
|
typedef typename std::iterator_traits<ElementIterator>::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)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ElementIterator m_element_iter;
|
||
|
IndexIterator m_index_iter;
|
||
|
IndexExpr m_expr;
|
||
|
};
|
||
|
|
||
|
template<class ElementIterator, class IndexIterator, class IndexExpr>
|
||
|
inline meta_kernel& operator<<(meta_kernel &kernel,
|
||
|
const permutation_iterator_access_expr<ElementIterator,
|
||
|
IndexIterator,
|
||
|
IndexExpr> &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 ElementIterator, class IndexIterator>
|
||
|
class permutation_iterator
|
||
|
: public detail::permutation_iterator_base<ElementIterator,
|
||
|
IndexIterator>::type
|
||
|
{
|
||
|
public:
|
||
|
typedef typename
|
||
|
detail::permutation_iterator_base<ElementIterator,
|
||
|
IndexIterator>::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<ElementIterator,
|
||
|
IndexIterator> &other)
|
||
|
: super_type(other),
|
||
|
m_map(other.m_map)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
permutation_iterator<ElementIterator, IndexIterator>&
|
||
|
operator=(const permutation_iterator<ElementIterator,
|
||
|
IndexIterator> &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<class IndexExpr>
|
||
|
detail::permutation_iterator_access_expr<ElementIterator,
|
||
|
IndexIterator,
|
||
|
IndexExpr>
|
||
|
operator[](const IndexExpr &expr) const
|
||
|
{
|
||
|
return detail::permutation_iterator_access_expr<ElementIterator,
|
||
|
IndexIterator,
|
||
|
IndexExpr>(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<class ElementIterator, class IndexIterator>
|
||
|
inline permutation_iterator<ElementIterator, IndexIterator>
|
||
|
make_permutation_iterator(ElementIterator e, IndexIterator i)
|
||
|
{
|
||
|
return permutation_iterator<ElementIterator, IndexIterator>(e, i);
|
||
|
}
|
||
|
|
||
|
/// \internal_ (is_device_iterator specialization for permutation_iterator)
|
||
|
template<class ElementIterator, class IndexIterator>
|
||
|
struct is_device_iterator<
|
||
|
permutation_iterator<ElementIterator, IndexIterator> > : boost::true_type {};
|
||
|
|
||
|
} // end compute namespace
|
||
|
} // end boost namespace
|
||
|
|
||
|
#endif // BOOST_COMPUTE_ITERATOR_PERMUTATION_ITERATOR_HPP
|