diff --git a/thrust/iterator/detail/tuple_of_iterator_references.h b/thrust/iterator/detail/tuple_of_iterator_references.h index 93d7e05e4..7ec59f390 100644 --- a/thrust/iterator/detail/tuple_of_iterator_references.h +++ b/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 + : public thrust::tuple { private: - typedef thrust::tuple super_t; + typedef thrust::tuple super_t; public: // allow implicit construction from tuple @@ -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 + template inline __host__ __device__ - tuple_of_iterator_references &operator=(const detail::cons &other) + tuple_of_iterator_references &operator=(const thrust::tuple &other) { super_t::operator=(other); return *this; @@ -72,24 +69,21 @@ template< // XXX perhaps we should generalize to reference // we could captures reference this way __thrust_exec_check_disable__ - template + template 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 +// const thrust::tuple // >::value, // tuple_of_iterator_references & // >::type tuple_of_iterator_references & - operator=(const thrust::reference, Pointer, Derived> &other) + operator=(const thrust::reference, Pointer, Derived> &other) { - typedef thrust::tuple tuple_type; + typedef thrust::tuple tuple_type; // XXX perhaps this could be accelerated tuple_type other_tuple = other; @@ -102,144 +96,9 @@ template< inline __host__ __device__ tuple_of_iterator_references() {} - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0) - : super_t(t0, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1) - : super_t(t0, t1, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2) - : super_t(t0, t1, t2, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3) - : super_t(t0, t1, t2, t3, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3, - typename access_traits::parameter_type t4) - : super_t(t0, t1, t2, t3, t4, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3, - typename access_traits::parameter_type t4, - typename access_traits::parameter_type t5) - : super_t(t0, t1, t2, t3, t4, t5, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3, - typename access_traits::parameter_type t4, - typename access_traits::parameter_type t5, - typename access_traits::parameter_type t6) - : super_t(t0, t1, t2, t3, t4, t5, t6, - static_cast(null_type()), - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3, - typename access_traits::parameter_type t4, - typename access_traits::parameter_type t5, - typename access_traits::parameter_type t6, - typename access_traits::parameter_type t7) - : super_t(t0, t1, t2, t3, t4, t5, t6, t7, - static_cast(null_type()), - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3, - typename access_traits::parameter_type t4, - typename access_traits::parameter_type t5, - typename access_traits::parameter_type t6, - typename access_traits::parameter_type t7, - typename access_traits::parameter_type t8) - : super_t(t0, t1, t2, t3, t4, t5, t6, t7, t8, - static_cast(null_type())) - {} - - inline __host__ __device__ - tuple_of_iterator_references(typename access_traits::parameter_type t0, - typename access_traits::parameter_type t1, - typename access_traits::parameter_type t2, - typename access_traits::parameter_type t3, - typename access_traits::parameter_type t4, - typename access_traits::parameter_type t5, - typename access_traits::parameter_type t6, - typename access_traits::parameter_type t7, - typename access_traits::parameter_type t8, - typename access_traits::parameter_type t9) - : super_t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) + inline __host__ __device__ + tuple_of_iterator_references(typename access_traits::parameter_type... ts) + : super_t(ts...) {} }; @@ -247,17 +106,42 @@ template< // this overload of swap() permits swapping tuple_of_iterator_references returned as temporaries from // iterator dereferences template< - typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, - typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7, typename U8, typename U9 + typename... Ts, + typename... Us > inline __host__ __device__ -void swap(tuple_of_iterator_references x, - tuple_of_iterator_references y) +void swap(tuple_of_iterator_references x, + tuple_of_iterator_references y) { x.swap(y); } } // end detail + +// define tuple_size, tuple_element, etc. +template +struct tuple_size> + : std::integral_constant +{}; + +template +struct tuple_element> {}; + + +template +struct tuple_element<0, detail::tuple_of_iterator_references> +{ + using type = T; +}; + + +template +struct tuple_element> +{ + using type = typename tuple_element>::type; +}; + + } // end thrust diff --git a/thrust/iterator/detail/zip_iterator_base.h b/thrust/iterator/detail/zip_iterator_base.h index b1603aed4..eddae23ae 100644 --- a/thrust/iterator/detail/zip_iterator_base.h +++ b/thrust/iterator/detail/zip_iterator_base.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -128,17 +129,28 @@ template struct tuple_meta_accumulate; template< - typename Tuple - , class BinaryMetaFun + class BinaryMetaFun , typename StartType > - struct tuple_meta_accumulate_impl + struct tuple_meta_accumulate,BinaryMetaFun,StartType> +{ + typedef typename thrust::detail::identity_::type type; +}; + + +template< + class BinaryMetaFun + , typename StartType + , typename T + , typename... Ts +> + struct tuple_meta_accumulate,BinaryMetaFun,StartType> { typedef typename apply2< BinaryMetaFun - , typename Tuple::head_type + , T , typename tuple_meta_accumulate< - typename Tuple::tail_type + thrust::tuple , BinaryMetaFun , StartType >::type @@ -146,81 +158,40 @@ template< }; -template< - typename Tuple - , class BinaryMetaFun - , typename StartType -> -struct tuple_meta_accumulate - : thrust::detail::eval_if< - thrust::detail::is_same::value - , thrust::detail::identity_ - , tuple_meta_accumulate_impl< - Tuple - , BinaryMetaFun - , StartType - > - > // end eval_if +template +inline __host__ __device__ +Fun tuple_for_each_helper(Fun f) { -}; // 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 -// struct apply -// { -// typedef Arg* type; -// } -// -// template -// Arg* operator()(Arg x); -// }; - + return f; +} +template +inline __host__ __device__ +Fun tuple_for_each_helper(Fun f, T& t, Ts&... ts) +{ + f(t); + return tuple_for_each_helper(f, ts...); +} // for_each algorithm for tuples. -template + +template inline __host__ __device__ -Fun tuple_for_each(thrust::null_type, Fun f) +Fun tuple_for_each(thrust::tuple& t, Fun f, thrust::index_sequence) { - return f; + return tuple_for_each_helper(f, thrust::get(t)...); } // end tuple_for_each() - -template +// for_each algorithm for tuples. +template inline __host__ __device__ -Fun tuple_for_each(Tuple& t, Fun f) +Fun tuple_for_each(thrust::tuple& t, Fun f) { - f( t.get_head() ); - return tuple_for_each(t.get_tail(), f); -} // end tuple_for_each() + return tuple_for_each(t, f, thrust::make_index_sequence>::value>{}); +} -// 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; } - - -template -__host__ __device__ -bool tuple_equal(Tuple1 const& t1, Tuple2 const& t2) -{ - return t1.get_head() == t2.get_head() && - tuple_equal(t1.get_tail(), t2.get_tail()); -} // end tuple_equal() - -} // 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 - struct tuple_elements_helper - : eval_if< - (i < tuple_size::value), - tuple_element, - identity_ - > -{}; +template + struct tuple_of_iterator_references_helper; -template - struct tuple_elements +template + struct tuple_of_iterator_references_helper> { - 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::type... + > type; }; @@ -329,22 +287,11 @@ template iterator_reference >::type tuple_of_references; - // get at the individual tuple element types by name - typedef tuple_elements elements; - // map thrust::tuple to tuple_of_iterator_references - 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::value> + >::type type; };