Fork me on GitHub
 All Classes Files Functions Variables Groups Pages
join_iterator.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2014 NVIDIA Corporation
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 
21 #pragma once
22 
23 #include <cusp/detail/config.h>
24 
25 #include <cusp/memory.h>
26 
27 #include <thrust/distance.h>
28 #include <thrust/functional.h>
29 
30 #include <thrust/iterator/transform_iterator.h>
31 
32 namespace cusp
33 {
34 
36 template <int size, typename T>
37 struct constant_tuple
38 {
39  typedef thrust::detail::identity_<T> T_;
40  typedef thrust::detail::identity_<thrust::null_type> N_;
41 
42  typedef
43  thrust::tuple<typename thrust::detail::eval_if<(size > 0),T_,N_>::type,
44  typename thrust::detail::eval_if<(size > 1),T_,N_>::type,
45  typename thrust::detail::eval_if<(size > 2),T_,N_>::type,
46  typename thrust::detail::eval_if<(size > 3),T_,N_>::type,
47  typename thrust::detail::eval_if<(size > 4),T_,N_>::type,
48  typename thrust::detail::eval_if<(size > 5),T_,N_>::type,
49  typename thrust::detail::eval_if<(size > 6),T_,N_>::type,
50  typename thrust::detail::eval_if<(size > 7),T_,N_>::type,
51  typename thrust::detail::eval_if<(size > 8),T_,N_>::type,
52  typename thrust::detail::eval_if<(size > 9),T_,N_>::type> type;
53 };
54 
55 template<typename T, typename V, int SIZE>
56 struct join_search
57 {
58  template<typename SizesTuple, typename Tuple>
59  __host__ __device__
60  V operator()(const SizesTuple&t1, const Tuple& t2, const T i) const
61  {
62  return i >= T(thrust::get<SIZE-2>(t1)) ? thrust::get<SIZE-1>(t2)[i] : join_search<T,V,SIZE-1>()(t1,t2,i);
63  }
64 };
65 
66 template<typename T, typename V>
67 struct join_search<T,V,2>
68 {
69  template<typename SizesTuple, typename Tuple>
70  __host__ __device__
71  V operator()(const SizesTuple&t1, const Tuple& t2, const T i) const
72  {
73  return i >= T(thrust::get<0>(t1)) ? thrust::get<1>(t2)[i] : thrust::get<0>(t2)[i];
74  }
75 };
140 template <typename Tuple>
142 {
143 public:
144 
146  typedef typename thrust::tuple_element<0,Tuple>::type Iterator1;
147  typedef typename thrust::iterator_value<Iterator1>::type value_type;
148  typedef typename thrust::iterator_pointer<Iterator1>::type pointer;
149  typedef typename thrust::iterator_reference<Iterator1>::type reference;
150  typedef typename thrust::iterator_difference<Iterator1>::type difference_type;
151  typedef typename thrust::iterator_difference<Iterator1>::type size_type;
152  typedef typename thrust::iterator_system<Iterator1>::type memory_space;
153 
154  const static size_t tuple_size = thrust::tuple_size<Tuple>::value;
155 
156  // forward definition
157  struct join_select_functor;
158 
159  typedef typename constant_tuple<tuple_size-1,size_t>::type SizesTuple;
160  typedef typename thrust::tuple_element<tuple_size-1,Tuple>::type IndexIterator;
161  typedef thrust::transform_iterator<join_select_functor,IndexIterator> TransformIterator;
162 
163  struct join_select_functor : public thrust::unary_function<difference_type,value_type>
164  {
165  SizesTuple t1;
166  Tuple t2;
167 
168  __host__ __device__
169  join_select_functor(void) {}
170 
171  __host__ __device__
172  join_select_functor(const SizesTuple& t1, const Tuple& t2)
173  : t1(t1), t2(t2) {}
174 
175  __host__ __device__
176  value_type operator()(const difference_type& i)
177  {
178  return join_search<difference_type,value_type,tuple_size-1>()(t1,t2,i);
179  }
180  };
183  // type of the join_iterator
184  typedef TransformIterator iterator;
185 
194  join_iterator(const SizesTuple& t1, const Tuple& t2) : t1(t1), t2(t2) {}
195 
200  iterator begin(void) const
201  {
202  return TransformIterator(thrust::get<tuple_size-1>(t2), join_select_functor(t1,t2));
203  }
204 
209  iterator end(void) const
210  {
211  return begin() + thrust::get<tuple_size-2>(t1);
212  }
213 
222  reference operator[](size_type n) const
223  {
224  return *(begin() + n);
225  }
226 
227 protected:
228 
230  const SizesTuple& t1;
231  const Tuple& t2;
233 };
234 
235 template <typename T1, typename T2, typename T3>
236 typename join_iterator< thrust::tuple<T1,T2,T3> >::iterator
237 make_join_iterator(const size_t s1, const size_t s2, const T1& t1, const T2& t2, const T3& t3)
238 {
239  typedef thrust::tuple<T1,T2,T3> Tuple;
240  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2),
241  thrust::make_tuple(t1, t2-s1, t3)).begin();
242 }
243 
244 template <typename T1, typename T2, typename T3, typename T4>
245 typename join_iterator< thrust::tuple<T1,T2,T3,T4> >::iterator
246 make_join_iterator(const size_t s1, const size_t s2, const size_t s3,
247  const T1& t1, const T2& t2, const T3& t3, const T4& t4)
248 {
249  typedef thrust::tuple<T1,T2,T3,T4> Tuple;
250  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3),
251  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4)).begin();
252 }
253 
254 template <typename T1, typename T2, typename T3, typename T4, typename T5>
255 typename join_iterator< thrust::tuple<T1,T2,T3,T4,T5> >::iterator
256 make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4,
257  const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
258 {
259  typedef thrust::tuple<T1,T2,T3,T4,T5> Tuple;
260  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4),
261  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5)).begin();
262 }
263 
264 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
265 typename join_iterator< thrust::tuple<T1,T2,T3,T4,T5,T6> >::iterator
266 make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5,
267  const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6)
268 {
269  typedef thrust::tuple<T1,T2,T3,T4,T5,T6> Tuple;
270  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5),
271  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6)).begin();
272 }
273 
274 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
275 typename join_iterator< thrust::tuple<T1,T2,T3,T4,T5,T6,T7> >::iterator
276 make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6,
277  const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7)
278 {
279  typedef thrust::tuple<T1,T2,T3,T4,T5,T6,T7> Tuple;
280  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6),
281  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7)).begin();
282 }
283 
284 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
285 typename join_iterator< thrust::tuple<T1,T2,T3,T4,T5,T6,T7,T8> >::iterator
286 make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6, const size_t s7,
287  const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8)
288 {
289  typedef thrust::tuple<T1,T2,T3,T4,T5,T6,T7,T8> Tuple;
290  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6, s1+s2+s3+s4+s5+s6+s7),
291  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7-s1-s2-s3-s4-s5-s6, t8)).begin();
292 }
293 
294 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
295 typename join_iterator< thrust::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::iterator
296 make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6, const size_t s7, const size_t s8,
297  const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9)
298 {
299  typedef thrust::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> Tuple;
300  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6, s1+s2+s3+s4+s5+s6+s7, s1+s2+s3+s4+s5+s6+s7+s8),
301  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7-s1-s2-s3-s4-s5-s6, t8-s1-s2-s3-s4-s5-s6-s7, t9)).begin();
302 }
303 
304 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
305 typename join_iterator< thrust::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> >::iterator
306 make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6, const size_t s7, const size_t s8, const size_t s9,
307  const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10)
308 {
309  typedef thrust::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> Tuple;
310  return join_iterator<Tuple>(thrust::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6, s1+s2+s3+s4+s5+s6+s7, s1+s2+s3+s4+s5+s6+s7+s8, s1+s2+s3+s4+s5+s6+s7+s8+s9),
311  thrust::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7-s1-s2-s3-s4-s5-s6, t8-s1-s2-s3-s4-s5-s6-s7, t9-s1-s2-s3-s4-s5-s6-s7-s8, t10)).begin();
312 }
313 
317 } // end namespace cusp
318 
join_iterator(const SizesTuple &t1, const Tuple &t2)
This constructor builds a join_iterator from two iterators.
iterator begin(void) const
This method returns an iterator pointing to the beginning of this joined sequence of permuted entries...
reference operator[](size_type n) const
Subscript access to the data contained in this iterator.
RandomAccessIterator for access to array entries from two concatenated iterators. ...
iterator end(void) const
This method returns an iterator pointing to one element past the last of this joined sequence of perm...