variadic tuple_of_iterator_references, zip_iterator
MODIFY
thrust/iterator/detail/tuple_of_iterator_references.h
thrust/iterator/detail/tuple_of_iterator_references.h
@@ -28,16 +28,13 @@ namespace detail
template<
- typename T0, typename T1, typename T2,
- typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8,
- typename T9
+ typename... Ts
>
class tuple_of_iterator_references
- : public thrust::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
+ : public thrust::tuple<Ts...>
{
private:
- typedef thrust::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> super_t;
+ typedef thrust::tuple<Ts...> super_t;
public:
// allow implicit construction from tuple<refs>
@@ -49,9 +46,9 @@ template<
// allow assignment from tuples
// XXX might be worthwhile to guard this with an enable_if is_assignable
__thrust_exec_check_disable__
- template<typename U1, typename U2>
+ template<typename... Us>
inline __host__ __device__
- tuple_of_iterator_references &operator=(const detail::cons<U1,U2> &other)
+ tuple_of_iterator_references &operator=(const thrust::tuple<Us...> &other)
{
super_t::operator=(other);
return *this;
@@ -72,24 +69,21 @@ template<
// XXX perhaps we should generalize to reference<T>
// we could captures reference<pair> this way
__thrust_exec_check_disable__
- template<typename U0, typename U1, typename U2,
- typename U3, typename U4, typename U5,
- typename U6, typename U7, typename U8,
- typename U9,
- typename Pointer, typename Derived>
+ template<typename Pointer, typename Derived,
+ typename... Us>
inline __host__ __device__
// XXX gcc-4.2 crashes on is_assignable
// typename thrust::detail::enable_if<
// thrust::detail::is_assignable<
// super_t,
-// const thrust::tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>
+// const thrust::tuple<Us...>
// >::value,
// tuple_of_iterator_references &
// >::type
tuple_of_iterator_references &
- operator=(const thrust::reference<thrust::tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>, Pointer, Derived> &other)
+ operator=(const thrust::reference<thrust::tuple<Us...>, Pointer, Derived> &other)
{
- typedef thrust::tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9> tuple_type;
+ typedef thrust::tuple<Us...> tuple_type;
// XXX perhaps this could be accelerated
tuple_type other_tuple = other;
@@ -103,143 +97,8 @@ template<
tuple_of_iterator_references() {}
inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0)
- : super_t(t0,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1)
- : super_t(t0, t1,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2)
- : super_t(t0, t1, t2,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3)
- : super_t(t0, t1, t2, t3,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3,
- typename access_traits<T4>::parameter_type t4)
- : super_t(t0, t1, t2, t3, t4,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3,
- typename access_traits<T4>::parameter_type t4,
- typename access_traits<T5>::parameter_type t5)
- : super_t(t0, t1, t2, t3, t4, t5,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3,
- typename access_traits<T4>::parameter_type t4,
- typename access_traits<T5>::parameter_type t5,
- typename access_traits<T6>::parameter_type t6)
- : super_t(t0, t1, t2, t3, t4, t5, t6,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3,
- typename access_traits<T4>::parameter_type t4,
- typename access_traits<T5>::parameter_type t5,
- typename access_traits<T6>::parameter_type t6,
- typename access_traits<T7>::parameter_type t7)
- : super_t(t0, t1, t2, t3, t4, t5, t6, t7,
- static_cast<const null_type&>(null_type()),
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3,
- typename access_traits<T4>::parameter_type t4,
- typename access_traits<T5>::parameter_type t5,
- typename access_traits<T6>::parameter_type t6,
- typename access_traits<T7>::parameter_type t7,
- typename access_traits<T8>::parameter_type t8)
- : super_t(t0, t1, t2, t3, t4, t5, t6, t7, t8,
- static_cast<const null_type&>(null_type()))
- {}
-
- inline __host__ __device__
- tuple_of_iterator_references(typename access_traits<T0>::parameter_type t0,
- typename access_traits<T1>::parameter_type t1,
- typename access_traits<T2>::parameter_type t2,
- typename access_traits<T3>::parameter_type t3,
- typename access_traits<T4>::parameter_type t4,
- typename access_traits<T5>::parameter_type t5,
- typename access_traits<T6>::parameter_type t6,
- typename access_traits<T7>::parameter_type t7,
- typename access_traits<T8>::parameter_type t8,
- typename access_traits<T9>::parameter_type t9)
- : super_t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9)
+ tuple_of_iterator_references(typename access_traits<Ts>::parameter_type... ts)
+ : super_t(ts...)
{}
};
@@ -259,5 +118,30 @@ void swap(tuple_of_iterator_references<Ts...> x,
} // end detail
+
+// define tuple_size, tuple_element, etc.
+template<class... Ts>
+struct tuple_size<detail::tuple_of_iterator_references<Ts...>>
+ : std::integral_constant<size_t, sizeof...(Ts)>
+{};
+
+template<size_t i>
+struct tuple_element<i, detail::tuple_of_iterator_references<>> {};
+
+
+template<class T, class... Ts>
+struct tuple_element<0, detail::tuple_of_iterator_references<T,Ts...>>
+{
+ using type = T;
+};
+
+
+template<size_t i, class T, class... Ts>
+struct tuple_element<i, detail::tuple_of_iterator_references<T,Ts...>>
+{
+ using type = typename tuple_element<i - 1, detail::tuple_of_iterator_references<Ts...>>::type;
+};
+
+
} // end thrust

MODIFY
thrust/iterator/detail/zip_iterator_base.h
thrust/iterator/detail/zip_iterator_base.h
#include <thrust/iterator/iterator_categories.h>
#include <thrust/iterator/detail/minimum_category.h>
#include <thrust/iterator/detail/minimum_system.h>
+#include <thrust/type_traits/integer_sequence.h>
#include <thrust/tuple.h>
#include <thrust/detail/tuple_meta_transform.h>
#include <thrust/detail/tuple_transform.h>
@@ -128,99 +129,69 @@ template<class Tuple, class BinaryMetaFun, class StartType>
struct tuple_meta_accumulate;
template<
- typename Tuple
- , class BinaryMetaFun
+ class BinaryMetaFun
, typename StartType
>
- struct tuple_meta_accumulate_impl
+ struct tuple_meta_accumulate<thrust::tuple<>,BinaryMetaFun,StartType>
{
- typedef typename apply2<
- BinaryMetaFun
- , typename Tuple::head_type
- , typename tuple_meta_accumulate<
- typename Tuple::tail_type
- , BinaryMetaFun
- , StartType
- >::type
- >::type type;
+ typedef typename thrust::detail::identity_<StartType>::type type;
};
template<
- typename Tuple
- , class BinaryMetaFun
+ class BinaryMetaFun
, typename StartType
+ , typename T
+ , typename... Ts
>
-struct tuple_meta_accumulate
- : thrust::detail::eval_if<
- thrust::detail::is_same<Tuple, thrust::null_type>::value
- , thrust::detail::identity_<StartType>
- , tuple_meta_accumulate_impl<
- Tuple
+ struct tuple_meta_accumulate<thrust::tuple<T,Ts...>,BinaryMetaFun,StartType>
+{
+ typedef typename apply2<
+ BinaryMetaFun
+ , T
+ , typename tuple_meta_accumulate<
+ thrust::tuple<Ts...>
, BinaryMetaFun
, StartType
- >
- > // end eval_if
-{
-}; // end tuple_meta_accumulate
-
-
-// transform algorithm for tuples. The template parameter Fun
-// must be a unary functor which is also a unary metafunction
-// class that computes its return type based on its argument
-// type. For example:
-//
-// struct to_ptr
-// {
-// template <class Arg>
-// struct apply
-// {
-// typedef Arg* type;
-// }
-//
-// template <class Arg>
-// Arg* operator()(Arg x);
-// };
-
+ >::type
+ >::type type;
+};
-// for_each algorithm for tuples.
template<typename Fun>
inline __host__ __device__
-Fun tuple_for_each(thrust::null_type, Fun f)
+Fun tuple_for_each_helper(Fun f)
{
return f;
-} // end tuple_for_each()
-
+}
-template<typename Tuple, typename Fun>
+template<typename Fun, typename T, typename... Ts>
inline __host__ __device__
-Fun tuple_for_each(Tuple& t, Fun f)
+Fun tuple_for_each_helper(Fun f, T& t, Ts&... ts)
{
- f( t.get_head() );
- return tuple_for_each(t.get_tail(), f);
-} // end tuple_for_each()
-
+ f(t);
+ return tuple_for_each_helper(f, ts...);
+}
-// Equality of tuples. NOTE: "==" for tuples currently (7/2003)
-// has problems under some compilers, so I just do my own.
-// No point in bringing in a bunch of #ifdefs here. This is
-// going to go away with the next tuple implementation anyway.
-//
-__host__ __device__
-inline bool tuple_equal(thrust::null_type, thrust::null_type)
-{ return true; }
+// for_each algorithm for tuples.
+template<typename Fun, typename... Ts, size_t... Is>
+inline __host__ __device__
+Fun tuple_for_each(thrust::tuple<Ts...>& t, Fun f, thrust::index_sequence<Is...>)
+{
+ return tuple_for_each_helper(f, thrust::get<Is>(t)...);
+} // end tuple_for_each()
-template<typename Tuple1, typename Tuple2>
-__host__ __device__
-bool tuple_equal(Tuple1 const& t1, Tuple2 const& t2)
+// for_each algorithm for tuples.
+template<typename Fun, typename... Ts>
+inline __host__ __device__
+Fun tuple_for_each(thrust::tuple<Ts...>& t, Fun f)
{
- return t1.get_head() == t2.get_head() &&
- tuple_equal(t1.get_tail(), t2.get_tail());
-} // end tuple_equal()
+ return tuple_for_each(t, f, thrust::make_index_sequence<thrust::tuple_size<thrust::tuple<Ts...>>::value>{});
+}
+
-} // end end tuple_impl_specific
+} // end tuple_impl_specific
// Metafunction to obtain the type of the tuple whose element types
@@ -294,29 +265,16 @@ namespace zip_iterator_base_ns
{
-template<int i, typename Tuple>
- struct tuple_elements_helper
- : eval_if<
- (i < tuple_size<Tuple>::value),
- tuple_element<i,Tuple>,
- identity_<thrust::null_type>
- >
-{};
+template<typename Tuple, typename IndexSequence>
+ struct tuple_of_iterator_references_helper;
-template<typename Tuple>
- struct tuple_elements
+template<typename Tuple, size_t... Is>
+ struct tuple_of_iterator_references_helper<Tuple, thrust::index_sequence<Is...>>
{
- typedef typename tuple_elements_helper<0,Tuple>::type T0;
- typedef typename tuple_elements_helper<1,Tuple>::type T1;
- typedef typename tuple_elements_helper<2,Tuple>::type T2;
- typedef typename tuple_elements_helper<3,Tuple>::type T3;
- typedef typename tuple_elements_helper<4,Tuple>::type T4;
- typedef typename tuple_elements_helper<5,Tuple>::type T5;
- typedef typename tuple_elements_helper<6,Tuple>::type T6;
- typedef typename tuple_elements_helper<7,Tuple>::type T7;
- typedef typename tuple_elements_helper<8,Tuple>::type T8;
- typedef typename tuple_elements_helper<9,Tuple>::type T9;
+ typedef thrust::detail::tuple_of_iterator_references<
+ typename thrust::tuple_element<Is,Tuple>::type...
+ > type;
};
@@ -329,22 +287,11 @@ template<typename IteratorTuple>
iterator_reference
>::type tuple_of_references;
- // get at the individual tuple element types by name
- typedef tuple_elements<tuple_of_references> elements;
-
// map thrust::tuple<T...> to tuple_of_iterator_references<T...>
- typedef thrust::detail::tuple_of_iterator_references<
- typename elements::T0,
- typename elements::T1,
- typename elements::T2,
- typename elements::T3,
- typename elements::T4,
- typename elements::T5,
- typename elements::T6,
- typename elements::T7,
- typename elements::T8,
- typename elements::T9
- > type;
+ typedef typename tuple_of_iterator_references_helper<
+ tuple_of_references,
+ thrust::make_index_sequence<thrust::tuple_size<tuple_of_references>::value>
+ >::type type;
};

variadic tuple_of_iterator_references, zip_iterator