OSDN Git Service

CUDA
[eos/hostdependX86LINUX64.git] / util / X86LINUX64 / cuda-6.5 / include / thrust / detail / raw_reference_cast.inl
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 #pragma once
18
19 #include <thrust/detail/config.h>
20 #include <thrust/detail/raw_reference_cast.h>
21 #include <thrust/detail/type_traits.h>
22 #include <thrust/detail/tuple_transform.h>
23
24 namespace thrust
25 {
26 namespace detail
27 {
28
29 // specialize is_unwrappable
30 // a tuple is_unwrappable if any of its elements is_unwrappable
31 template<
32   typename T0, typename T1, typename T2,
33   typename T3, typename T4, typename T5,
34   typename T6, typename T7, typename T8,
35   typename T9
36 >
37   struct is_unwrappable<
38     thrust::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
39   >
40     : or_<
41         is_unwrappable<T0>,
42         is_unwrappable<T1>,
43         is_unwrappable<T2>,
44         is_unwrappable<T3>,
45         is_unwrappable<T4>,
46         is_unwrappable<T5>,
47         is_unwrappable<T6>,
48         is_unwrappable<T7>,
49         is_unwrappable<T8>,
50         is_unwrappable<T9>
51       >
52 {};
53
54
55 // specialize is_unwrappable
56 // a tuple_of_iterator_references is_unwrappable if any of its elements is_unwrappable
57 template<
58   typename T0, typename T1, typename T2,
59   typename T3, typename T4, typename T5,
60   typename T6, typename T7, typename T8,
61   typename T9
62 >
63   struct is_unwrappable<
64     thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
65   >
66     : or_<
67         is_unwrappable<T0>,
68         is_unwrappable<T1>,
69         is_unwrappable<T2>,
70         is_unwrappable<T3>,
71         is_unwrappable<T4>,
72         is_unwrappable<T5>,
73         is_unwrappable<T6>,
74         is_unwrappable<T7>,
75         is_unwrappable<T8>,
76         is_unwrappable<T9>
77       >
78 {};
79
80
81 namespace raw_reference_detail
82 {
83
84 // unlike raw_reference,
85 // raw_reference_tuple_helper needs to return a value
86 // when it encounters one, rather than a reference
87 // upon encountering tuple, recurse
88 //
89 // we want the following behavior:
90 //  1. T                                -> T
91 //  2. T&                               -> T&
92 //  3. null_type                        -> null_type
93 //  4. reference<T>                     -> T&
94 //  5. tuple_of_iterator_references<T>  -> tuple_of_iterator_references<raw_reference_tuple_helper<T>::type>
95
96
97 // wrapped references are unwrapped using raw_reference, otherwise, return T
98 template<typename T>
99   struct raw_reference_tuple_helper
100     : eval_if<
101         is_unwrappable<
102           typename remove_cv<T>::type
103         >::value,
104         raw_reference<T>,
105         identity_<T>
106       >
107 {};
108
109
110 // recurse on tuples
111 template <
112   typename T0, typename T1, typename T2,
113   typename T3, typename T4, typename T5,
114   typename T6, typename T7, typename T8,
115   typename T9
116 >
117   struct raw_reference_tuple_helper<
118     thrust::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
119   >
120 {
121   typedef thrust::tuple<
122     typename raw_reference_tuple_helper<T0>::type,
123     typename raw_reference_tuple_helper<T1>::type,
124     typename raw_reference_tuple_helper<T2>::type,
125     typename raw_reference_tuple_helper<T3>::type,
126     typename raw_reference_tuple_helper<T4>::type,
127     typename raw_reference_tuple_helper<T5>::type,
128     typename raw_reference_tuple_helper<T6>::type,
129     typename raw_reference_tuple_helper<T7>::type,
130     typename raw_reference_tuple_helper<T8>::type,
131     typename raw_reference_tuple_helper<T9>::type
132   > type;
133 };
134
135
136 template <
137   typename T0, typename T1, typename T2,
138   typename T3, typename T4, typename T5,
139   typename T6, typename T7, typename T8,
140   typename T9
141 >
142   struct raw_reference_tuple_helper<
143     thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
144   >
145 {
146   typedef thrust::detail::tuple_of_iterator_references<
147     typename raw_reference_tuple_helper<T0>::type,
148     typename raw_reference_tuple_helper<T1>::type,
149     typename raw_reference_tuple_helper<T2>::type,
150     typename raw_reference_tuple_helper<T3>::type,
151     typename raw_reference_tuple_helper<T4>::type,
152     typename raw_reference_tuple_helper<T5>::type,
153     typename raw_reference_tuple_helper<T6>::type,
154     typename raw_reference_tuple_helper<T7>::type,
155     typename raw_reference_tuple_helper<T8>::type,
156     typename raw_reference_tuple_helper<T9>::type
157   > type;
158 };
159
160
161 } // end raw_reference_detail
162
163
164 // if a tuple "tuple_type" is_unwrappable,
165 //   then the raw_reference of tuple_type is a tuple of its members' raw_references
166 //   else the raw_reference of tuple_type is tuple_type &
167 template <
168   typename T0, typename T1, typename T2,
169   typename T3, typename T4, typename T5,
170   typename T6, typename T7, typename T8,
171   typename T9
172 >
173   struct raw_reference<
174     thrust::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
175   >
176 {
177   private:
178     typedef thrust::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> tuple_type;
179
180   public:
181     typedef typename eval_if<
182       is_unwrappable<tuple_type>::value,
183       raw_reference_detail::raw_reference_tuple_helper<tuple_type>,
184       add_reference<tuple_type>
185     >::type type;
186 };
187
188
189 template <
190   typename T0, typename T1, typename T2,
191   typename T3, typename T4, typename T5,
192   typename T6, typename T7, typename T8,
193   typename T9
194 >
195   struct raw_reference<
196     thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
197   >
198 {
199   private:
200     typedef detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> tuple_type;
201
202   public:
203     typedef typename raw_reference_detail::raw_reference_tuple_helper<tuple_type>::type type;
204
205     // XXX figure out why is_unwrappable seems to be broken for tuple_of_iterator_references
206     //typedef typename eval_if<
207     //  is_unwrappable<tuple_type>::value,
208     //  raw_reference_detail::raw_reference_tuple_helper<tuple_type>,
209     //  add_reference<tuple_type>
210     //>::type type;
211 };
212
213
214 struct raw_reference_caster
215 {
216   template<typename T>
217   __host__ __device__
218   typename detail::raw_reference<T>::type operator()(T &ref)
219   {
220     return thrust::raw_reference_cast(ref);
221   }
222
223   template<typename T>
224   __host__ __device__
225   typename detail::raw_reference<const T>::type operator()(const T &ref)
226   {
227     return thrust::raw_reference_cast(ref);
228   }
229
230   template<
231     typename T0, typename T1, typename T2,
232     typename T3, typename T4, typename T5,
233     typename T6, typename T7, typename T8,
234     typename T9
235   >
236   __host__ __device__
237   typename detail::raw_reference<
238     thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
239   >::type
240   operator()(thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> t,
241              typename enable_if<
242                is_unwrappable<thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value
243              >::type * = 0)
244   {
245     return thrust::raw_reference_cast(t);
246   }
247 }; // end raw_reference_caster
248
249
250 } // end detail
251
252
253 template<
254   typename T0, typename T1, typename T2,
255   typename T3, typename T4, typename T5,
256   typename T6, typename T7, typename T8,
257   typename T9
258 >
259 __host__ __device__
260 typename detail::enable_if_unwrappable<
261   thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>,
262   typename detail::raw_reference<
263     thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>
264   >::type
265 >::type
266 raw_reference_cast(thrust::detail::tuple_of_iterator_references<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> t)
267 {
268   thrust::detail::raw_reference_caster f;
269
270   // note that we pass raw_reference_tuple_helper, not raw_reference as the unary metafunction
271   // the subtle difference is important
272   return thrust::detail::tuple_host_device_transform<detail::raw_reference_detail::raw_reference_tuple_helper>(t, f);
273 } // end raw_reference_cast
274
275
276 } // end thrust
277