Bolt  1.3
C++ template library with support for OpenCL
counting_iterator.h
Go to the documentation of this file.
1 /***************************************************************************
2 * © 2012,2014 Advanced Micro Devices, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 
16 ***************************************************************************/
17 #pragma once
18 #if !defined( BOLT_AMP_COUNTING_ITERATOR_H )
19 #define BOLT_AMP_COUNTING_ITERATOR_H
20 #include "bolt/amp/bolt.h"
22 
28 namespace bolt {
29 namespace amp {
30 
32  : public fancy_iterator_tag
33  { // identifying tag for random-access iterators
34  };
35 
73  template< typename value_type >
74  class counting_iterator: public std::iterator< counting_iterator_tag, typename value_type, int>
75  {
76  public:
77  typedef typename std::iterator< counting_iterator_tag, typename value_type, int>::difference_type
78  difference_type;
79 
80  typedef concurrency::array_view< value_type > arrayview_type;
82 
83 
84  // Basic constructor requires a reference to the container and a positional element
85  counting_iterator( value_type init, const control& ctl = control::getDefault( ) ):
86  m_initValue( init ), m_Index( 0 ) {}
87 
88  // This copy constructor allows an iterator to convert into a const_iterator, but not vica versa
89  template< typename OtherType >
90  counting_iterator( const counting_iterator< OtherType >& rhs ):m_Index( rhs.m_Index ),
91  m_initValue( rhs.m_initValue ) {}
92 
93  // This copy constructor allows an iterator to convert into a const_iterator, but not vica versa
95  {
96  if( this == &rhs )
97  return *this;
98 
99  m_initValue = rhs.m_initValue;
100  m_Index = rhs.m_Index;
101  return *this;
102  }
103 
104  counting_iterator< value_type >& operator+= ( const difference_type & n )
105  {
106  advance( n );
107  return *this;
108  }
109 
110  const counting_iterator< value_type > operator+ ( const difference_type & n ) const
111  {
112  counting_iterator< value_type > result( *this );
113  result.advance( n );
114  return result;
115  }
116 
117  const counting_iterator< value_type > operator- ( const difference_type & n ) const
118  {
119  counting_iterator< value_type > result( *this );
120  result.advance( -n );
121  return result;
122  }
123 
124  const counting_iterator< value_type > & getBuffer( const_iterator itr ) const
125  {
126  return *this;
127  }
128 
129 
130  value_type* getPointer()
131  {
132  return &m_initValue;
133  }
134 
135  const value_type* getPointer() const
136  {
137  return &m_initValue;
138  }
139 
140  const counting_iterator< value_type > & getContainer( ) const
141  {
142  return *this;
143  }
144 
145  difference_type operator- ( const counting_iterator< value_type >& rhs ) const
146  {
147  return m_Index - rhs.m_Index;
148  }
149 
150  // Public member variables
151  difference_type m_Index;
152 
153  // Used for templatized copy constructor and the templatized equal operator
154  template < typename > friend class counting_iterator;
155 
156  // For a counting_iterator, do nothing on an advance
157  void advance( difference_type n )
158  {
159  m_Index += n;
160  }
161 
162  // Pre-increment
163  counting_iterator< value_type > operator++ ( )
164  {
165  advance( 1 );
166  counting_iterator< value_type > result( *this );
167  return *this;
168  }
169 
170  // Post-increment
171  counting_iterator< value_type > operator++ ( int )
172  {
173  advance( 1 );
174  return *this;
175  }
176 
177  // Pre-decrement
178  counting_iterator< value_type > operator--( )
179  {
180  advance( -1 );
181  return *this;
182  }
183 
184  // Post-decrement
185  counting_iterator< value_type > operator--( int )
186  {
187  advance( -1 );
188  return *this;
189  }
190 
191  difference_type getIndex() const
192  {
193  return m_Index;
194  }
195 
196  template< typename OtherType >
197  bool operator== ( const counting_iterator< OtherType >& rhs ) const
198  {
199  bool sameIndex = (rhs.m_initValue == m_initValue) && (rhs.m_Index == m_Index);
200 
201  return sameIndex;
202  }
203 
204  template< typename OtherType >
205  bool operator!= ( const counting_iterator< OtherType >& rhs ) const
206  {
207  bool sameIndex = (rhs.m_initValue != m_initValue) || (rhs.m_Index != m_Index);
208 
209  return sameIndex;
210  }
211 
212  template< typename OtherType >
213  bool operator< ( const counting_iterator< OtherType >& rhs ) const
214  {
215  bool sameIndex = (m_Index < rhs.m_Index);
216 
217  return sameIndex;
218  }
219 
220  value_type operator*() const restrict(cpu,amp)
221  {
222  value_type xy = m_initValue + m_Index;
223  return xy;
224  }
225 
226 
227  value_type operator[](int x) const restrict(cpu,amp)
228  {
229  value_type temp = m_initValue + x;
230  return temp;
231  }
232 
233  private:
234  value_type m_initValue;
235  };
236 
237 
238  template< typename Type >
239  counting_iterator< Type > make_counting_iterator( Type initValue )
240  {
241  counting_iterator< Type > tmp( initValue );
242  return tmp;
243  }
244 
245 }
246 }
247 
248 
249 #endif