1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com> 3 // 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 7 // 8 // See http://boostorg.github.com/compute for more information. 9 //---------------------------------------------------------------------------// 10 11 #ifndef BOOST_COMPUTE_ITERATOR_DISCARD_ITERATOR_HPP 12 #define BOOST_COMPUTE_ITERATOR_DISCARD_ITERATOR_HPP 13 14 #include <string> 15 #include <cstddef> 16 #include <iterator> 17 18 #include <boost/config.hpp> 19 #include <boost/iterator/iterator_facade.hpp> 20 21 #include <boost/compute/detail/meta_kernel.hpp> 22 #include <boost/compute/type_traits/is_device_iterator.hpp> 23 24 namespace boost { 25 namespace compute { 26 27 // forward declaration for discard_iterator 28 class discard_iterator; 29 30 namespace detail { 31 32 // helper class which defines the iterator_facade super-class 33 // type for discard_iterator 34 struct discard_iterator_base 35 { 36 typedef ::boost::iterator_facade< 37 ::boost::compute::discard_iterator, 38 void, 39 ::std::random_access_iterator_tag, 40 void * 41 > type; 42 }; 43 44 template<class IndexExpr> 45 struct discard_iterator_index_expr 46 { 47 typedef void result_type; 48 discard_iterator_index_exprboost::compute::detail::discard_iterator_index_expr49 discard_iterator_index_expr(const IndexExpr &expr) 50 : m_expr(expr) 51 { 52 } 53 54 IndexExpr m_expr; 55 }; 56 57 template<class IndexExpr> operator <<(meta_kernel & kernel,const discard_iterator_index_expr<IndexExpr> & expr)58inline meta_kernel& operator<<(meta_kernel &kernel, 59 const discard_iterator_index_expr<IndexExpr> &expr) 60 { 61 (void) expr; 62 63 return kernel; 64 } 65 66 } // end detail namespace 67 68 /// \class discard_iterator 69 /// \brief An iterator which discards all values written to it. 70 /// 71 /// \see make_discard_iterator(), constant_iterator 72 class discard_iterator : public detail::discard_iterator_base::type 73 { 74 public: 75 typedef detail::discard_iterator_base::type super_type; 76 typedef super_type::reference reference; 77 typedef super_type::difference_type difference_type; 78 discard_iterator(size_t index=0)79 discard_iterator(size_t index = 0) 80 : m_index(index) 81 { 82 } 83 discard_iterator(const discard_iterator & other)84 discard_iterator(const discard_iterator &other) 85 : m_index(other.m_index) 86 { 87 } 88 operator =(const discard_iterator & other)89 discard_iterator& operator=(const discard_iterator &other) 90 { 91 if(this != &other){ 92 m_index = other.m_index; 93 } 94 95 return *this; 96 } 97 ~discard_iterator()98 ~discard_iterator() 99 { 100 } 101 102 /// \internal_ 103 template<class Expr> 104 detail::discard_iterator_index_expr<Expr> operator [](const Expr & expr) const105 operator[](const Expr &expr) const 106 { 107 return detail::discard_iterator_index_expr<Expr>(expr); 108 } 109 110 private: 111 friend class ::boost::iterator_core_access; 112 113 /// \internal_ dereference() const114 reference dereference() const 115 { 116 return 0; 117 } 118 119 /// \internal_ equal(const discard_iterator & other) const120 bool equal(const discard_iterator &other) const 121 { 122 return m_index == other.m_index; 123 } 124 125 /// \internal_ increment()126 void increment() 127 { 128 m_index++; 129 } 130 131 /// \internal_ decrement()132 void decrement() 133 { 134 m_index--; 135 } 136 137 /// \internal_ advance(difference_type n)138 void advance(difference_type n) 139 { 140 m_index = static_cast<size_t>(static_cast<difference_type>(m_index) + n); 141 } 142 143 /// \internal_ distance_to(const discard_iterator & other) const144 difference_type distance_to(const discard_iterator &other) const 145 { 146 return static_cast<difference_type>(other.m_index - m_index); 147 } 148 149 private: 150 size_t m_index; 151 }; 152 153 /// Returns a new discard_iterator with \p index. 154 /// 155 /// \param index the index of the iterator 156 /// 157 /// \return a \c discard_iterator at \p index make_discard_iterator(size_t index=0)158inline discard_iterator make_discard_iterator(size_t index = 0) 159 { 160 return discard_iterator(index); 161 } 162 163 /// internal_ (is_device_iterator specialization for discard_iterator) 164 template<> 165 struct is_device_iterator<discard_iterator> : boost::true_type {}; 166 167 } // end compute namespace 168 } // end boost namespace 169 170 #endif // BOOST_COMPUTE_ITERATOR_DISCARD_ITERATOR_HPP 171