1/* 2 * Copyright 2008-2013 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 17 18#pragma once 19 20#include <thrust/detail/config.h> 21#include <thrust/system/detail/generic/transform_scan.h> 22#include <thrust/scan.h> 23#include <thrust/iterator/transform_iterator.h> 24#include <thrust/detail/type_traits.h> 25#include <thrust/detail/type_traits/function_traits.h> 26#include <thrust/detail/type_traits/iterator/is_output_iterator.h> 27 28namespace thrust 29{ 30namespace system 31{ 32namespace detail 33{ 34namespace generic 35{ 36 37 38template<typename ExecutionPolicy, 39 typename InputIterator, 40 typename OutputIterator, 41 typename UnaryFunction, 42 typename BinaryFunction> 43__host__ __device__ 44 OutputIterator transform_inclusive_scan(thrust::execution_policy<ExecutionPolicy> &exec, 45 InputIterator first, 46 InputIterator last, 47 OutputIterator result, 48 UnaryFunction unary_op, 49 BinaryFunction binary_op) 50{ 51 // the pseudocode for deducing the type of the temporary used below: 52 // 53 // if UnaryFunction is AdaptableUnaryFunction 54 // TemporaryType = AdaptableUnaryFunction::result_type 55 // else if OutputIterator is a "pure" output iterator 56 // TemporaryType = InputIterator::value_type 57 // else 58 // TemporaryType = OutputIterator::value_type 59 // 60 // XXX upon c++0x, TemporaryType needs to be: 61 // result_of_adaptable_function<UnaryFunction>::type 62 63 typedef typename thrust::detail::eval_if< 64 thrust::detail::has_result_type<UnaryFunction>::value, 65 thrust::detail::result_type<UnaryFunction>, 66 thrust::detail::eval_if< 67 thrust::detail::is_output_iterator<OutputIterator>::value, 68 thrust::iterator_value<InputIterator>, 69 thrust::iterator_value<OutputIterator> 70 > 71 >::type ValueType; 72 73 thrust::transform_iterator<UnaryFunction, InputIterator, ValueType> _first(first, unary_op); 74 thrust::transform_iterator<UnaryFunction, InputIterator, ValueType> _last(last, unary_op); 75 76 return thrust::inclusive_scan(exec, _first, _last, result, binary_op); 77} // end transform_inclusive_scan() 78 79 80template<typename ExecutionPolicy, 81 typename InputIterator, 82 typename OutputIterator, 83 typename UnaryFunction, 84 typename T, 85 typename AssociativeOperator> 86__host__ __device__ 87 OutputIterator transform_exclusive_scan(thrust::execution_policy<ExecutionPolicy> &exec, 88 InputIterator first, 89 InputIterator last, 90 OutputIterator result, 91 UnaryFunction unary_op, 92 T init, 93 AssociativeOperator binary_op) 94{ 95 // the pseudocode for deducing the type of the temporary used below: 96 // 97 // if UnaryFunction is AdaptableUnaryFunction 98 // TemporaryType = AdaptableUnaryFunction::result_type 99 // else if OutputIterator is a "pure" output iterator 100 // TemporaryType = InputIterator::value_type 101 // else 102 // TemporaryType = OutputIterator::value_type 103 // 104 // XXX upon c++0x, TemporaryType needs to be: 105 // result_of_adaptable_function<UnaryFunction>::type 106 107 typedef typename thrust::detail::eval_if< 108 thrust::detail::has_result_type<UnaryFunction>::value, 109 thrust::detail::result_type<UnaryFunction>, 110 thrust::detail::eval_if< 111 thrust::detail::is_output_iterator<OutputIterator>::value, 112 thrust::iterator_value<InputIterator>, 113 thrust::iterator_value<OutputIterator> 114 > 115 >::type ValueType; 116 117 thrust::transform_iterator<UnaryFunction, InputIterator, ValueType> _first(first, unary_op); 118 thrust::transform_iterator<UnaryFunction, InputIterator, ValueType> _last(last, unary_op); 119 120 return thrust::exclusive_scan(exec, _first, _last, result, init, binary_op); 121} // end transform_exclusive_scan() 122 123 124} // end namespace generic 125} // end namespace detail 126} // end namespace system 127} // end namespace thrust 128 129