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_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 // forward declaration for swizzle_iterator
0034 template<class InputIterator, size_t Size>
0035 class swizzle_iterator;
0036 
0037 // meta-function returing the value_type for a swizzle_iterator
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 // helper class which defines the iterator_adaptor super-class
0051 // type for swizzle_iterator
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 } // end detail namespace
0180 
0181 // is_device_iterator specialization for swizzle_iterator
0182 template<size_t Size, class InputIterator>
0183 struct is_device_iterator<detail::swizzle_iterator<InputIterator, Size> > : boost::true_type {};
0184 
0185 } // end compute namespace
0186 } // end boost namespace
0187 
0188 #endif // BOOST_COMPUTE_ITERATOR_SWIZZLE_ITERATOR_HPP