1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
11 #ifndef BOOST_COMPUTE_ITERATOR_DETAIL_SWIZZLE_ITERATOR_HPP
12 #define BOOST_COMPUTE_ITERATOR_DETAIL_SWIZZLE_ITERATOR_HPP
18 #include <boost/config.hpp>
19 #include <boost/iterator/iterator_adaptor.hpp>
21 #include <boost/compute/functional.hpp>
22 #include <boost/compute/detail/meta_kernel.hpp>
23 #include <boost/compute/type_traits/make_vector_type.hpp>
24 #include <boost/compute/detail/is_buffer_iterator.hpp>
25 #include <boost/compute/detail/read_write_single_value.hpp>
26 #include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp>
27 #include <boost/compute/type_traits/is_device_iterator.hpp>
33 // forward declaration for swizzle_iterator
34 template<class InputIterator, size_t Size>
35 class swizzle_iterator;
37 // meta-function returing the value_type for a swizzle_iterator
38 template<class InputIterator, size_t Size>
39 struct make_swizzle_iterator_value_type
42 typename make_vector_type<
44 typename std::iterator_traits<InputIterator>::value_type
50 // helper class which defines the iterator_adaptor super-class
51 // type for swizzle_iterator
52 template<class InputIterator, size_t Size>
53 class swizzle_iterator_base
56 typedef ::boost::iterator_adaptor<
57 swizzle_iterator<InputIterator, Size>,
59 typename make_swizzle_iterator_value_type<InputIterator, Size>::type,
60 typename std::iterator_traits<InputIterator>::iterator_category,
61 typename make_swizzle_iterator_value_type<InputIterator, Size>::type
65 template<class InputIterator, size_t Size, class IndexExpr>
66 struct swizzle_iterator_index_expr
68 typedef typename make_swizzle_iterator_value_type<InputIterator, Size>::type result_type;
70 swizzle_iterator_index_expr(const InputIterator &input_iter,
71 const IndexExpr &index_expr,
72 const std::string &components)
73 : m_input_iter(input_iter),
74 m_index_expr(index_expr),
75 m_components(components)
79 InputIterator m_input_iter;
80 IndexExpr m_index_expr;
81 std::string m_components;
84 template<class InputIterator, size_t Size, class IndexExpr>
85 inline meta_kernel& operator<<(meta_kernel &kernel,
86 const swizzle_iterator_index_expr<InputIterator,
90 return kernel << expr.m_input_iter[expr.m_index_expr]
91 << "." << expr.m_components;
94 template<class InputIterator, size_t Size>
95 class swizzle_iterator :
96 public swizzle_iterator_base<InputIterator, Size>::type
100 swizzle_iterator_base<InputIterator, Size>::type
102 typedef typename super_type::value_type value_type;
103 typedef typename super_type::reference reference;
104 typedef typename super_type::base_type base_type;
105 typedef typename super_type::difference_type difference_type;
107 BOOST_STATIC_CONSTANT(size_t, vector_size = Size);
109 swizzle_iterator(InputIterator iterator, const std::string &components)
110 : super_type(iterator),
111 m_components(components)
113 BOOST_ASSERT(components.size() == Size);
116 swizzle_iterator(const swizzle_iterator<InputIterator, Size> &other)
117 : super_type(other.base()),
118 m_components(other.m_components)
120 BOOST_ASSERT(m_components.size() == Size);
123 swizzle_iterator<InputIterator, Size>&
124 operator=(const swizzle_iterator<InputIterator, Size> &other)
127 super_type::operator=(other);
129 m_components = other.m_components;
139 size_t get_index() const
141 return super_type::base().get_index();
144 const buffer& get_buffer() const
146 return get_base_iterator_buffer(*this);
149 template<class IndexExpression>
150 swizzle_iterator_index_expr<InputIterator, Size, IndexExpression>
151 operator[](const IndexExpression &expr) const
153 return swizzle_iterator_index_expr<InputIterator,
155 IndexExpression>(super_type::base(),
161 friend class ::boost::iterator_core_access;
163 reference dereference() const
169 std::string m_components;
172 template<size_t Size, class InputIterator>
173 inline swizzle_iterator<InputIterator, Size>
174 make_swizzle_iterator(InputIterator iterator, const std::string &components)
176 return swizzle_iterator<InputIterator, Size>(iterator, components);
179 } // end detail namespace
181 // is_device_iterator specialization for swizzle_iterator
182 template<size_t Size, class InputIterator>
183 struct is_device_iterator<detail::swizzle_iterator<InputIterator, Size> > : boost::true_type {};
185 } // end compute namespace
186 } // end boost namespace
188 #endif // BOOST_COMPUTE_ITERATOR_SWIZZLE_ITERATOR_HPP