]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | //---------------------------------------------------------------------------// |
2 | // Copyright (c) 2013 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_CONSTANT_ITERATOR_HPP | |
12 | #define BOOST_COMPUTE_ITERATOR_CONSTANT_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 constant_iterator<T> | |
28 | template<class T> class constant_iterator; | |
29 | ||
30 | namespace detail { | |
31 | ||
32 | // helper class which defines the iterator_facade super-class | |
33 | // type for constant_iterator<T> | |
34 | template<class T> | |
35 | class constant_iterator_base | |
36 | { | |
37 | public: | |
38 | typedef ::boost::iterator_facade< | |
39 | ::boost::compute::constant_iterator<T>, | |
40 | T, | |
41 | ::std::random_access_iterator_tag | |
42 | > type; | |
43 | }; | |
44 | ||
45 | } // end detail namespace | |
46 | ||
47 | /// \class constant_iterator | |
48 | /// \brief An iterator with a constant value. | |
49 | /// | |
50 | /// The constant_iterator class provides an iterator which returns a constant | |
51 | /// value when dereferenced. | |
52 | /// | |
53 | /// For example, this could be used to implement the fill() algorithm in terms | |
54 | /// of the copy() algorithm by copying from a range of constant iterators: | |
55 | /// | |
56 | /// \snippet test/test_constant_iterator.cpp fill_with_copy | |
57 | /// | |
58 | /// \see make_constant_iterator() | |
59 | template<class T> | |
60 | class constant_iterator : public detail::constant_iterator_base<T>::type | |
61 | { | |
62 | public: | |
63 | typedef typename detail::constant_iterator_base<T>::type super_type; | |
64 | typedef typename super_type::reference reference; | |
65 | typedef typename super_type::difference_type difference_type; | |
66 | ||
67 | constant_iterator(const T &value, size_t index = 0) | |
68 | : m_value(value), | |
69 | m_index(index) | |
70 | { | |
71 | } | |
72 | ||
73 | constant_iterator(const constant_iterator<T> &other) | |
74 | : m_value(other.m_value), | |
75 | m_index(other.m_index) | |
76 | { | |
77 | } | |
78 | ||
79 | constant_iterator<T>& operator=(const constant_iterator<T> &other) | |
80 | { | |
81 | if(this != &other){ | |
82 | m_value = other.m_value; | |
83 | m_index = other.m_index; | |
84 | } | |
85 | ||
86 | return *this; | |
87 | } | |
88 | ||
89 | ~constant_iterator() | |
90 | { | |
91 | } | |
92 | ||
93 | size_t get_index() const | |
94 | { | |
95 | return m_index; | |
96 | } | |
97 | ||
98 | /// \internal_ | |
99 | template<class Expr> | |
100 | detail::meta_kernel_literal<T> operator[](const Expr &expr) const | |
101 | { | |
102 | (void) expr; | |
103 | ||
104 | return detail::meta_kernel::make_lit<T>(m_value); | |
105 | } | |
106 | ||
107 | private: | |
108 | friend class ::boost::iterator_core_access; | |
109 | ||
110 | /// \internal_ | |
111 | reference dereference() const | |
112 | { | |
113 | return m_value; | |
114 | } | |
115 | ||
116 | /// \internal_ | |
117 | bool equal(const constant_iterator<T> &other) const | |
118 | { | |
119 | return m_value == other.m_value && m_index == other.m_index; | |
120 | } | |
121 | ||
122 | /// \internal_ | |
123 | void increment() | |
124 | { | |
125 | m_index++; | |
126 | } | |
127 | ||
128 | /// \internal_ | |
129 | void decrement() | |
130 | { | |
131 | m_index--; | |
132 | } | |
133 | ||
134 | /// \internal_ | |
135 | void advance(difference_type n) | |
136 | { | |
137 | m_index = static_cast<size_t>(static_cast<difference_type>(m_index) + n); | |
138 | } | |
139 | ||
140 | /// \internal_ | |
141 | difference_type distance_to(const constant_iterator<T> &other) const | |
142 | { | |
143 | return static_cast<difference_type>(other.m_index - m_index); | |
144 | } | |
145 | ||
146 | private: | |
147 | T m_value; | |
148 | size_t m_index; | |
149 | }; | |
150 | ||
151 | /// Returns a new constant_iterator with \p value at \p index. | |
152 | /// | |
153 | /// \param value the constant value | |
154 | /// \param index the iterators index | |
155 | /// | |
156 | /// \return a \c constant_iterator with \p value | |
157 | template<class T> | |
158 | inline constant_iterator<T> | |
159 | make_constant_iterator(const T &value, size_t index = 0) | |
160 | { | |
161 | return constant_iterator<T>(value, index); | |
162 | } | |
163 | ||
164 | /// \internal_ (is_device_iterator specialization for constant_iterator) | |
165 | template<class T> | |
166 | struct is_device_iterator<constant_iterator<T> > : boost::true_type {}; | |
167 | ||
168 | } // end compute namespace | |
169 | } // end boost namespace | |
170 | ||
171 | #endif // BOOST_COMPUTE_ITERATOR_CONSTANT_ITERATOR_HPP |