2 * Copyright 2008-2013 NVIDIA Corporation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <thrust/detail/config.h>
18 #include <thrust/system/detail/generic/uninitialized_copy.h>
19 #include <thrust/copy.h>
20 #include <thrust/for_each.h>
21 #include <thrust/detail/internal_functional.h>
22 #include <thrust/detail/type_traits.h>
23 #include <thrust/iterator/iterator_traits.h>
36 template<typename InputType,
38 struct uninitialized_copy_functor
40 template<typename Tuple>
42 void operator()(Tuple t)
44 const InputType &in = thrust::get<0>(t);
45 OutputType &out = thrust::get<1>(t);
47 ::new(static_cast<void*>(&out)) OutputType(in);
49 }; // end uninitialized_copy_functor
52 // non-trivial copy constructor path
53 template<typename ExecutionPolicy,
54 typename InputIterator,
55 typename ForwardIterator>
56 ForwardIterator uninitialized_copy(thrust::execution_policy<ExecutionPolicy> &exec,
59 ForwardIterator result,
60 thrust::detail::false_type) // has_trivial_copy_constructor
62 // zip up the iterators
63 typedef thrust::tuple<InputIterator,ForwardIterator> IteratorTuple;
64 typedef thrust::zip_iterator<IteratorTuple> ZipIterator;
66 ZipIterator begin = thrust::make_zip_iterator(thrust::make_tuple(first,result));
67 ZipIterator end = begin;
69 // get a zip_iterator pointing to the end
70 const typename thrust::iterator_difference<InputIterator>::type n = thrust::distance(first,last);
71 thrust::advance(end, n);
74 typedef typename iterator_traits<InputIterator>::value_type InputType;
75 typedef typename iterator_traits<ForwardIterator>::value_type OutputType;
77 detail::uninitialized_copy_functor<InputType, OutputType> f;
80 thrust::for_each(exec, begin, end, f);
82 // return the end of the output range
83 return thrust::get<1>(end.get_iterator_tuple());
84 } // end uninitialized_copy()
87 // trivial copy constructor path
88 template<typename ExecutionPolicy,
89 typename InputIterator,
90 typename ForwardIterator>
91 ForwardIterator uninitialized_copy(thrust::execution_policy<ExecutionPolicy> &exec,
94 ForwardIterator result,
95 thrust::detail::true_type) // has_trivial_copy_constructor
97 return thrust::copy(exec, first, last, result);
98 } // end uninitialized_copy()
101 // non-trivial copy constructor path
102 template<typename ExecutionPolicy,
103 typename InputIterator,
105 typename ForwardIterator>
106 ForwardIterator uninitialized_copy_n(thrust::execution_policy<ExecutionPolicy> &exec,
109 ForwardIterator result,
110 thrust::detail::false_type) // has_trivial_copy_constructor
112 // zip up the iterators
113 typedef thrust::tuple<InputIterator,ForwardIterator> IteratorTuple;
114 typedef thrust::zip_iterator<IteratorTuple> ZipIterator;
116 ZipIterator zipped_first = thrust::make_zip_iterator(thrust::make_tuple(first,result));
119 typedef typename iterator_traits<InputIterator>::value_type InputType;
120 typedef typename iterator_traits<ForwardIterator>::value_type OutputType;
122 detail::uninitialized_copy_functor<InputType, OutputType> f;
125 ZipIterator zipped_last = thrust::for_each_n(exec, zipped_first, n, f);
127 // return the end of the output range
128 return thrust::get<1>(zipped_last.get_iterator_tuple());
129 } // end uninitialized_copy_n()
132 // trivial copy constructor path
133 template<typename ExecutionPolicy,
134 typename InputIterator,
136 typename ForwardIterator>
137 ForwardIterator uninitialized_copy_n(thrust::execution_policy<ExecutionPolicy> &exec,
140 ForwardIterator result,
141 thrust::detail::true_type) // has_trivial_copy_constructor
143 return thrust::copy_n(exec, first, n, result);
144 } // end uninitialized_copy_n()
150 template<typename ExecutionPolicy,
151 typename InputIterator,
152 typename ForwardIterator>
153 ForwardIterator uninitialized_copy(thrust::execution_policy<ExecutionPolicy> &exec,
156 ForwardIterator result)
158 typedef typename iterator_traits<ForwardIterator>::value_type ResultType;
160 typedef typename thrust::detail::has_trivial_copy_constructor<ResultType>::type ResultTypeHasTrivialCopyConstructor;
162 return thrust::system::detail::generic::detail::uninitialized_copy(exec, first, last, result, ResultTypeHasTrivialCopyConstructor());
163 } // end uninitialized_copy()
166 template<typename ExecutionPolicy,
167 typename InputIterator,
169 typename ForwardIterator>
170 ForwardIterator uninitialized_copy_n(thrust::execution_policy<ExecutionPolicy> &exec,
173 ForwardIterator result)
175 typedef typename iterator_traits<ForwardIterator>::value_type ResultType;
177 typedef typename thrust::detail::has_trivial_copy_constructor<ResultType>::type ResultTypeHasTrivialCopyConstructor;
179 return thrust::system::detail::generic::detail::uninitialized_copy_n(exec, first, n, result, ResultTypeHasTrivialCopyConstructor());
180 } // end uninitialized_copy_n()
183 } // end namespace generic
184 } // end namespace detail
185 } // end namespace system
186 } // end namespace thrust