]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // The template and inlines for the -*- C++ -*- internal _Array helper class. |
2 | ||
3 | // Copyright (C) 1997-2000 Free Software Foundation, Inc. | |
4 | // | |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
8 | // Free Software Foundation; either version 2, or (at your option) | |
9 | // any later version. | |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
16 | // You should have received a copy of the GNU General Public License along | |
17 | // with this library; see the file COPYING. If not, write to the Free | |
18 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
19 | // USA. | |
20 | ||
21 | // As a special exception, you may use this file as part of a free software | |
22 | // library without restriction. Specifically, if other files instantiate | |
23 | // templates or use macros or inline functions from this file, or you compile | |
24 | // this file and link it with other files to produce an executable, this | |
25 | // file does not by itself cause the resulting executable to be covered by | |
26 | // the GNU General Public License. This exception does not however | |
27 | // invalidate any other reasons why the executable file might be covered by | |
28 | // the GNU General Public License. | |
29 | ||
30 | // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> | |
31 | ||
32 | #ifndef _CPP_BITS_ARRAY_H | |
33 | #define _CPP_BITS_ARRAY_H 1 | |
34 | ||
b0a85b86 GDR |
35 | #pragma GCC system_header |
36 | ||
725dc051 BK |
37 | #include <bits/c++config.h> |
38 | #include <bits/cpp_type_traits.h> | |
39 | #include <bits/std_cstdlib.h> | |
40 | #include <bits/std_cstring.h> | |
a6863e25 | 41 | #include <new> |
725dc051 BK |
42 | |
43 | namespace std | |
44 | { | |
45 | ||
46 | // | |
47 | // Helper functions on raw pointers | |
48 | // | |
49 | ||
50 | // We get memory by the old fashion way | |
51 | inline void* | |
52 | __valarray_get_memory(size_t __n) | |
53 | { return operator new(__n); } | |
54 | ||
55 | template<typename _Tp> | |
56 | inline _Tp*__restrict__ | |
57 | __valarray_get_storage(size_t __n) | |
58 | { | |
59 | return static_cast<_Tp*__restrict__> | |
60 | (__valarray_get_memory(__n * sizeof(_Tp))); | |
61 | } | |
62 | ||
63 | // Return memory to the system | |
64 | inline void | |
65 | __valarray_release_memory(void* __p) | |
66 | { operator delete(__p); } | |
67 | ||
68 | // Turn a raw-memory into an array of _Tp filled with _Tp() | |
69 | // This is required in 'valarray<T> v(n);' | |
70 | template<typename _Tp, bool> | |
71 | struct _Array_default_ctor | |
72 | { | |
73 | // Please note that this isn't exception safe. But | |
74 | // valarrays aren't required to be exception safe. | |
75 | inline static void | |
76 | _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) | |
77 | { while (__b != __e) new(__b++) _Tp(); } | |
78 | }; | |
79 | ||
80 | template<typename _Tp> | |
81 | struct _Array_default_ctor<_Tp, true> | |
82 | { | |
83 | // For fundamental types, it suffices to say 'memset()' | |
84 | inline static void | |
85 | _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) | |
86 | { memset(__b, 0, (__e - __b)*sizeof(_Tp)); } | |
87 | }; | |
88 | ||
89 | template<typename _Tp> | |
90 | inline void | |
91 | __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e) | |
92 | { | |
93 | _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: | |
94 | _S_do_it(__b, __e); | |
95 | } | |
96 | ||
97 | // Turn a raw-memory into an array of _Tp filled with __t | |
98 | // This is the required in valarray<T> v(n, t). Also | |
99 | // used in valarray<>::resize(). | |
100 | template<typename _Tp, bool> | |
101 | struct _Array_init_ctor | |
102 | { | |
103 | // Please note that this isn't exception safe. But | |
104 | // valarrays aren't required to be exception safe. | |
105 | inline static void | |
106 | _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) | |
107 | { while (__b != __e) new(__b++) _Tp(__t); } | |
108 | }; | |
109 | ||
110 | template<typename _Tp> | |
111 | struct _Array_init_ctor<_Tp, true> | |
112 | { | |
113 | inline static void | |
114 | _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t) | |
115 | { while (__b != __e) *__b++ = __t; } | |
116 | }; | |
117 | ||
118 | template<typename _Tp> | |
119 | inline void | |
120 | __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e, | |
121 | const _Tp __t) | |
122 | { | |
123 | _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: | |
124 | _S_do_it(__b, __e, __t); | |
125 | } | |
126 | ||
127 | // | |
128 | // copy-construct raw array [__o, *) from plain array [__b, __e) | |
129 | // We can't just say 'memcpy()' | |
130 | // | |
131 | template<typename _Tp, bool> | |
132 | struct _Array_copy_ctor | |
133 | { | |
134 | // Please note that this isn't exception safe. But | |
135 | // valarrays aren't required to be exception safe. | |
136 | inline static void | |
137 | _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, | |
138 | _Tp* __restrict__ __o) | |
139 | { while (__b != __e) new(__o++) _Tp(*__b++); } | |
140 | }; | |
141 | ||
142 | template<typename _Tp> | |
143 | struct _Array_copy_ctor<_Tp, true> | |
144 | { | |
145 | inline static void | |
146 | _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, | |
147 | _Tp* __restrict__ __o) | |
148 | { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } | |
149 | }; | |
150 | ||
151 | template<typename _Tp> | |
152 | inline void | |
153 | __valarray_copy_construct(const _Tp* __restrict__ __b, | |
154 | const _Tp* __restrict__ __e, | |
155 | _Tp* __restrict__ __o) | |
156 | { | |
157 | _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: | |
158 | _S_do_it(__b, __e, __o); | |
159 | } | |
160 | ||
161 | // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] | |
162 | template<typename _Tp> | |
163 | inline void | |
164 | __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, | |
165 | size_t __s, _Tp* __restrict__ __o) | |
166 | { | |
167 | if (__is_fundamental<_Tp>::_M_type) | |
168 | while (__n--) { *__o++ = *__a; __a += __s; } | |
169 | else | |
170 | while (__n--) { new(__o++) _Tp(*__a); __a += __s; } | |
171 | } | |
172 | ||
173 | // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] | |
174 | template<typename _Tp> | |
175 | inline void | |
176 | __valarray_copy_construct (const _Tp* __restrict__ __a, | |
177 | const size_t* __restrict__ __i, | |
178 | _Tp* __restrict__ __o, size_t __n) | |
179 | { | |
180 | if (__is_fundamental<_Tp>::_M_type) | |
181 | while (__n--) *__o++ = __a[*__i++]; | |
182 | else | |
183 | while (__n--) new (__o++) _Tp(__a[*__i++]); | |
184 | } | |
185 | ||
186 | // Do the necessary cleanup when we're done with arrays. | |
187 | template<typename _Tp> | |
188 | inline void | |
189 | __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e) | |
190 | { | |
191 | if (!__is_fundamental<_Tp>::_M_type) | |
192 | while (__b != __e) { __b->~_Tp(); ++__b; } | |
193 | } | |
194 | ||
195 | // fill plain array __a[<__n>] with __t | |
196 | template<typename _Tp> | |
197 | void | |
198 | __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) | |
199 | { while (__n--) *__a++ = __t; } | |
200 | ||
201 | // fill strided array __a[<__n-1 : __s>] with __t | |
202 | template<typename _Tp> | |
203 | inline void | |
204 | __valarray_fill (_Tp* __restrict__ __a, size_t __n, | |
205 | size_t __s, const _Tp& __t) | |
206 | { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } | |
207 | ||
208 | // fill indir ect array __a[__i[<__n>]] with __i | |
209 | template<typename _Tp> | |
210 | inline void | |
211 | __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, | |
212 | size_t __n, const _Tp& __t) | |
213 | { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } | |
214 | ||
215 | // copy plain array __a[<__n>] in __b[<__n>] | |
216 | // For non-fundamental types, it is wrong to say 'memcpy()' | |
217 | template<typename _Tp, bool> | |
218 | struct _Array_copier | |
219 | { | |
220 | inline static void | |
221 | _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) | |
222 | { while (__n--) *__b++ = *__a++; } | |
223 | }; | |
224 | ||
225 | template<typename _Tp> | |
226 | struct _Array_copier<_Tp, true> | |
227 | { | |
228 | inline static void | |
229 | _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) | |
230 | { memcpy (__b, __a, __n * sizeof (_Tp)); } | |
231 | }; | |
232 | ||
233 | template<typename _Tp> | |
234 | inline void | |
235 | __valarray_copy (const _Tp* __restrict__ __a, size_t __n, | |
236 | _Tp* __restrict__ __b) | |
237 | { | |
238 | _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>:: | |
239 | _S_do_it(__a, __n, __b); | |
240 | } | |
241 | ||
242 | // copy strided array __a[<__n : __s>] in plain __b[<__n>] | |
243 | template<typename _Tp> | |
244 | inline void | |
245 | __valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s, | |
246 | _Tp* __restrict__ __b) | |
247 | { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } | |
248 | ||
249 | // copy plain __a[<__n>] in strided __b[<__n : __s>] | |
250 | template<typename _Tp> | |
251 | inline void | |
252 | __valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b, | |
253 | size_t __n, size_t __s) | |
254 | { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } | |
7c301abf GDR |
255 | |
256 | // Copy strided array __src[<__n : __s1>] into another | |
257 | // strided array __dst[< : __s2>]. Their sizes must match. | |
258 | template<typename _Tp> | |
259 | inline void | |
260 | __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, | |
261 | _Tp* __restrict__ __dst, size_t __s2) | |
262 | { | |
263 | for (size_t __i = 0; __i < __n; ++__i) | |
264 | __dst[__i * __s2] = __src [ __i * __s1]; | |
265 | } | |
266 | ||
725dc051 BK |
267 | |
268 | // copy indexed __a[__i[<__n>]] in plain __b[<__n>] | |
269 | template<typename _Tp> | |
270 | inline void | |
271 | __valarray_copy (const _Tp* __restrict__ __a, | |
272 | const size_t* __restrict__ __i, | |
273 | _Tp* __restrict__ __b, size_t __n) | |
274 | { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } | |
275 | ||
276 | // copy plain __a[<__n>] in indexed __b[__i[<__n>]] | |
277 | template<typename _Tp> | |
278 | inline void | |
279 | __valarray_copy (const _Tp* __restrict__ __a, size_t __n, | |
280 | _Tp* __restrict__ __b, const size_t* __restrict__ __i) | |
281 | { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } | |
282 | ||
283 | ||
284 | // | |
285 | // Compute the sum of elements in range [__f, __l) | |
286 | // This is a naive algorithm. It suffers from cancelling. | |
287 | // In the future try to specialize | |
288 | // for _Tp = float, double, long double using a more accurate | |
289 | // algorithm. | |
290 | // | |
291 | template<typename _Tp> | |
292 | inline _Tp | |
293 | __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l) | |
294 | { | |
295 | _Tp __r = _Tp(); | |
296 | while (__f != __l) __r += *__f++; | |
297 | return __r; | |
298 | } | |
299 | ||
300 | // Compute the product of all elements in range [__f, __l) | |
301 | template<typename _Tp> | |
302 | inline _Tp | |
303 | __valarray_product(const _Tp* __restrict__ __f, | |
304 | const _Tp* __restrict__ __l) | |
305 | { | |
306 | _Tp __r = _Tp(1); | |
307 | while (__f != __l) __r = __r * *__f++; | |
308 | return __r; | |
309 | } | |
310 | ||
311 | // Compute the min/max of an array-expression | |
312 | template<typename _Ta> | |
313 | inline typename _Ta::value_type | |
314 | __valarray_min(const _Ta& __a) | |
315 | { | |
316 | size_t __s = __a.size(); | |
317 | typedef typename _Ta::value_type _Value_type; | |
318 | _Value_type __r = __s == 0 ? _Value_type() : __a[0]; | |
319 | for (size_t __i = 1; __i < __s; ++__i) | |
320 | { | |
321 | _Value_type __t = __a[__i]; | |
322 | if (__t < __r) | |
323 | __r = __t; | |
324 | } | |
325 | return __r; | |
326 | } | |
327 | ||
328 | template<typename _Ta> | |
329 | inline typename _Ta::value_type | |
330 | __valarray_max(const _Ta& __a) | |
331 | { | |
332 | size_t __s = __a.size(); | |
333 | typedef typename _Ta::value_type _Value_type; | |
334 | _Value_type __r = __s == 0 ? _Value_type() : __a[0]; | |
335 | for (size_t __i = 1; __i < __s; ++__i) | |
336 | { | |
337 | _Value_type __t = __a[__i]; | |
338 | if (__t > __r) | |
339 | __r = __t; | |
340 | } | |
341 | return __r; | |
342 | } | |
343 | ||
344 | // | |
345 | // Helper class _Array, first layer of valarray abstraction. | |
346 | // All operations on valarray should be forwarded to this class | |
347 | // whenever possible. -- gdr | |
348 | // | |
349 | ||
350 | template<typename _Tp> | |
351 | struct _Array | |
352 | { | |
353 | explicit _Array (size_t); | |
354 | explicit _Array (_Tp* const __restrict__); | |
355 | explicit _Array (const valarray<_Tp>&); | |
356 | _Array (const _Tp* __restrict__, size_t); | |
357 | ||
358 | _Tp* begin () const; | |
359 | ||
360 | _Tp* const __restrict__ _M_data; | |
361 | }; | |
362 | ||
363 | template<typename _Tp> | |
364 | inline void | |
365 | __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) | |
366 | { __valarray_fill (__a._M_data, __n, __t); } | |
367 | ||
368 | template<typename _Tp> | |
369 | inline void | |
370 | __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) | |
371 | { __valarray_fill (__a._M_data, __n, __s, __t); } | |
372 | ||
373 | template<typename _Tp> | |
374 | inline void | |
375 | __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, | |
376 | size_t __n, const _Tp& __t) | |
377 | { __valarray_fill (__a._M_data, __i._M_data, __n, __t); } | |
378 | ||
379 | template<typename _Tp> | |
380 | inline void | |
381 | __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) | |
382 | { __valarray_copy (__a._M_data, __n, __b._M_data); } | |
383 | ||
384 | template<typename _Tp> | |
385 | inline void | |
386 | __valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) | |
387 | { __valarray_copy(__a._M_data, __n, __s, __b._M_data); } | |
388 | ||
389 | template<typename _Tp> | |
390 | inline void | |
391 | __valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) | |
392 | { __valarray_copy (__a._M_data, __b._M_data, __n, __s); } | |
7c301abf GDR |
393 | |
394 | template<typename _Tp> | |
395 | inline void | |
396 | __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, | |
397 | _Array<_Tp> __b, size_t __s2) | |
398 | { __valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } | |
399 | ||
725dc051 BK |
400 | |
401 | template<typename _Tp> | |
402 | inline void | |
403 | __valarray_copy (_Array<_Tp> __a, _Array<size_t> __i, | |
404 | _Array<_Tp> __b, size_t __n) | |
405 | { __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); } | |
406 | ||
407 | template<typename _Tp> | |
408 | inline void | |
409 | __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, | |
410 | _Array<size_t> __i) | |
411 | { __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); } | |
412 | ||
413 | template<typename _Tp> | |
414 | inline | |
415 | _Array<_Tp>::_Array (size_t __n) | |
416 | : _M_data(__valarray_get_storage<_Tp>(__n)) | |
417 | { __valarray_default_construct(_M_data, _M_data + __n); } | |
418 | ||
419 | template<typename _Tp> | |
420 | inline | |
421 | _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} | |
422 | ||
423 | template<typename _Tp> | |
424 | inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) | |
425 | : _M_data (__v._M_data) {} | |
426 | ||
427 | template<typename _Tp> | |
428 | inline | |
429 | _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) | |
430 | : _M_data(__valarray_get_storage<_Tp>(__s)) | |
431 | { __valarray_copy_construct(__b, __s, _M_data); } | |
432 | ||
433 | template<typename _Tp> | |
434 | inline _Tp* | |
435 | _Array<_Tp>::begin () const | |
436 | { return _M_data; } | |
437 | ||
438 | #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ | |
439 | template<typename _Tp> \ | |
440 | inline void \ | |
441 | _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ | |
442 | { \ | |
443 | for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ | |
444 | *__p _Op##= __t; \ | |
445 | } \ | |
446 | \ | |
447 | template<typename _Tp> \ | |
448 | inline void \ | |
449 | _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ | |
450 | { \ | |
451 | _Tp* __p = __a._M_data; \ | |
452 | for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ | |
453 | *__p _Op##= *__q; \ | |
454 | } \ | |
455 | \ | |
456 | template<typename _Tp, class _Dom> \ | |
457 | void \ | |
458 | _Array_augmented_##_Name (_Array<_Tp> __a, \ | |
459 | const _Expr<_Dom,_Tp>& __e, size_t __n) \ | |
460 | { \ | |
461 | _Tp* __p (__a._M_data); \ | |
462 | for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ | |
463 | } \ | |
464 | \ | |
465 | template<typename _Tp> \ | |
466 | inline void \ | |
467 | _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ | |
468 | _Array<_Tp> __b) \ | |
469 | { \ | |
470 | _Tp* __q (__b._M_data); \ | |
471 | for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ | |
472 | *__p _Op##= *__q; \ | |
473 | } \ | |
474 | \ | |
475 | template<typename _Tp> \ | |
476 | inline void \ | |
477 | _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ | |
478 | size_t __n, size_t __s) \ | |
479 | { \ | |
480 | _Tp* __q (__b._M_data); \ | |
481 | for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ | |
482 | *__p _Op##= *__q; \ | |
483 | } \ | |
484 | \ | |
485 | template<typename _Tp, class _Dom> \ | |
486 | void \ | |
487 | _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ | |
488 | const _Expr<_Dom,_Tp>& __e, size_t __n) \ | |
489 | { \ | |
490 | _Tp* __p (__a._M_data); \ | |
491 | for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ | |
492 | } \ | |
493 | \ | |
494 | template<typename _Tp> \ | |
495 | inline void \ | |
496 | _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ | |
497 | _Array<_Tp> __b, size_t __n) \ | |
498 | { \ | |
499 | _Tp* __q (__b._M_data); \ | |
500 | for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ | |
501 | __a._M_data[*__j] _Op##= *__q; \ | |
502 | } \ | |
503 | \ | |
504 | template<typename _Tp> \ | |
505 | inline void \ | |
506 | _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ | |
507 | _Array<_Tp> __b, _Array<size_t> __i) \ | |
508 | { \ | |
509 | _Tp* __p (__a._M_data); \ | |
510 | for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ | |
511 | *__p _Op##= __b._M_data[*__j]; \ | |
512 | } \ | |
513 | \ | |
514 | template<typename _Tp, class _Dom> \ | |
515 | void \ | |
516 | _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ | |
517 | const _Expr<_Dom, _Tp>& __e, size_t __n) \ | |
518 | { \ | |
519 | size_t* __j (__i._M_data); \ | |
520 | for (size_t __k=0; __k<__n; ++__k, ++__j) \ | |
521 | __a._M_data[*__j] _Op##= __e[__k]; \ | |
522 | } \ | |
523 | \ | |
524 | template<typename _Tp> \ | |
525 | void \ | |
526 | _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ | |
527 | _Array<_Tp> __b, size_t __n) \ | |
528 | { \ | |
529 | bool* ok (__m._M_data); \ | |
530 | _Tp* __p (__a._M_data); \ | |
531 | for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ | |
532 | while (! *ok) { \ | |
533 | ++ok; \ | |
534 | ++__p; \ | |
535 | } \ | |
536 | *__p _Op##= *__q; \ | |
537 | } \ | |
538 | } \ | |
539 | \ | |
540 | template<typename _Tp> \ | |
541 | void \ | |
542 | _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ | |
543 | _Array<_Tp> __b, _Array<bool> __m) \ | |
544 | { \ | |
545 | bool* ok (__m._M_data); \ | |
546 | _Tp* __q (__b._M_data); \ | |
547 | for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ | |
548 | while (! *ok) { \ | |
549 | ++ok; \ | |
550 | ++__q; \ | |
551 | } \ | |
552 | *__p _Op##= *__q; \ | |
553 | } \ | |
554 | } \ | |
555 | \ | |
556 | template<typename _Tp, class _Dom> \ | |
557 | void \ | |
558 | _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ | |
559 | const _Expr<_Dom, _Tp>& __e, size_t __n) \ | |
560 | { \ | |
561 | bool* ok(__m._M_data); \ | |
562 | _Tp* __p (__a._M_data); \ | |
563 | for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ | |
564 | while (! *ok) { \ | |
565 | ++ok; \ | |
566 | ++__p; \ | |
567 | } \ | |
568 | *__p _Op##= __e[__i]; \ | |
569 | } \ | |
570 | } | |
571 | ||
572 | _DEFINE_ARRAY_FUNCTION(+, plus) | |
573 | _DEFINE_ARRAY_FUNCTION(-, minus) | |
574 | _DEFINE_ARRAY_FUNCTION(*, multiplies) | |
575 | _DEFINE_ARRAY_FUNCTION(/, divides) | |
576 | _DEFINE_ARRAY_FUNCTION(%, modulus) | |
577 | _DEFINE_ARRAY_FUNCTION(^, xor) | |
578 | _DEFINE_ARRAY_FUNCTION(|, or) | |
579 | _DEFINE_ARRAY_FUNCTION(&, and) | |
580 | _DEFINE_ARRAY_FUNCTION(<<, shift_left) | |
581 | _DEFINE_ARRAY_FUNCTION(>>, shift_right) | |
582 | ||
583 | #undef _DEFINE_VALARRAY_FUNCTION | |
584 | ||
585 | } // std:: | |
586 | ||
587 | #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT | |
588 | # define export | |
589 | # include <bits/valarray_array.tcc> | |
590 | #endif | |
591 | ||
592 | #endif /* _CPP_BITS_ARRAY_H */ | |
593 | ||
594 | // Local Variables: | |
595 | // mode:c++ | |
596 | // End: |