• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)58 inline 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)158 inline 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