File indexing completed on 2025-01-18 09:30:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_ITERATOR_DETAIL_SWIZZLE_ITERATOR_HPP
0012 #define BOOST_COMPUTE_ITERATOR_DETAIL_SWIZZLE_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/type_traits/make_vector_type.hpp>
0024 #include <boost/compute/detail/is_buffer_iterator.hpp>
0025 #include <boost/compute/detail/read_write_single_value.hpp>
0026 #include <boost/compute/iterator/detail/get_base_iterator_buffer.hpp>
0027 #include <boost/compute/type_traits/is_device_iterator.hpp>
0028
0029 namespace boost {
0030 namespace compute {
0031 namespace detail {
0032
0033
0034 template<class InputIterator, size_t Size>
0035 class swizzle_iterator;
0036
0037
0038 template<class InputIterator, size_t Size>
0039 struct make_swizzle_iterator_value_type
0040 {
0041 typedef
0042 typename make_vector_type<
0043 typename scalar_type<
0044 typename std::iterator_traits<InputIterator>::value_type
0045 >::type,
0046 Size
0047 >::type type;
0048 };
0049
0050
0051
0052 template<class InputIterator, size_t Size>
0053 class swizzle_iterator_base
0054 {
0055 public:
0056 typedef ::boost::iterator_adaptor<
0057 swizzle_iterator<InputIterator, Size>,
0058 InputIterator,
0059 typename make_swizzle_iterator_value_type<InputIterator, Size>::type,
0060 typename std::iterator_traits<InputIterator>::iterator_category,
0061 typename make_swizzle_iterator_value_type<InputIterator, Size>::type
0062 > type;
0063 };
0064
0065 template<class InputIterator, size_t Size, class IndexExpr>
0066 struct swizzle_iterator_index_expr
0067 {
0068 typedef typename make_swizzle_iterator_value_type<InputIterator, Size>::type result_type;
0069
0070 swizzle_iterator_index_expr(const InputIterator &input_iter,
0071 const IndexExpr &index_expr,
0072 const std::string &components)
0073 : m_input_iter(input_iter),
0074 m_index_expr(index_expr),
0075 m_components(components)
0076 {
0077 }
0078
0079 InputIterator m_input_iter;
0080 IndexExpr m_index_expr;
0081 std::string m_components;
0082 };
0083
0084 template<class InputIterator, size_t Size, class IndexExpr>
0085 inline meta_kernel& operator<<(meta_kernel &kernel,
0086 const swizzle_iterator_index_expr<InputIterator,
0087 Size,
0088 IndexExpr> &expr)
0089 {
0090 return kernel << expr.m_input_iter[expr.m_index_expr]
0091 << "." << expr.m_components;
0092 }
0093
0094 template<class InputIterator, size_t Size>
0095 class swizzle_iterator :
0096 public swizzle_iterator_base<InputIterator, Size>::type
0097 {
0098 public:
0099 typedef typename
0100 swizzle_iterator_base<InputIterator, Size>::type
0101 super_type;
0102 typedef typename super_type::value_type value_type;
0103 typedef typename super_type::reference reference;
0104 typedef typename super_type::base_type base_type;
0105 typedef typename super_type::difference_type difference_type;
0106
0107 BOOST_STATIC_CONSTANT(size_t, vector_size = Size);
0108
0109 swizzle_iterator(InputIterator iterator, const std::string &components)
0110 : super_type(iterator),
0111 m_components(components)
0112 {
0113 BOOST_ASSERT(components.size() == Size);
0114 }
0115
0116 swizzle_iterator(const swizzle_iterator<InputIterator, Size> &other)
0117 : super_type(other.base()),
0118 m_components(other.m_components)
0119 {
0120 BOOST_ASSERT(m_components.size() == Size);
0121 }
0122
0123 swizzle_iterator<InputIterator, Size>&
0124 operator=(const swizzle_iterator<InputIterator, Size> &other)
0125 {
0126 if(this != &other){
0127 super_type::operator=(other);
0128
0129 m_components = other.m_components;
0130 }
0131
0132 return *this;
0133 }
0134
0135 ~swizzle_iterator()
0136 {
0137 }
0138
0139 size_t get_index() const
0140 {
0141 return super_type::base().get_index();
0142 }
0143
0144 const buffer& get_buffer() const
0145 {
0146 return get_base_iterator_buffer(*this);
0147 }
0148
0149 template<class IndexExpression>
0150 swizzle_iterator_index_expr<InputIterator, Size, IndexExpression>
0151 operator[](const IndexExpression &expr) const
0152 {
0153 return swizzle_iterator_index_expr<InputIterator,
0154 Size,
0155 IndexExpression>(super_type::base(),
0156 expr,
0157 m_components);
0158 }
0159
0160 private:
0161 friend class ::boost::iterator_core_access;
0162
0163 reference dereference() const
0164 {
0165 return reference();
0166 }
0167
0168 private:
0169 std::string m_components;
0170 };
0171
0172 template<size_t Size, class InputIterator>
0173 inline swizzle_iterator<InputIterator, Size>
0174 make_swizzle_iterator(InputIterator iterator, const std::string &components)
0175 {
0176 return swizzle_iterator<InputIterator, Size>(iterator, components);
0177 }
0178
0179 }
0180
0181
0182 template<size_t Size, class InputIterator>
0183 struct is_device_iterator<detail::swizzle_iterator<InputIterator, Size> > : boost::true_type {};
0184
0185 }
0186 }
0187
0188 #endif