OSDN Git Service

* optabs.c (init_optabs): Initialize fixtab, fixtrunctab, floattab,
[pf3gnuchains/gcc-fork.git] / libstdc++ / std / valarray_array.h
1 // The template and inlines for the -*- C++ -*- internal _Array helper class.
2
3 // Copyright (C) 1997-1999 Cygnus Solutions
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 __VALARRAY_ARRAY__
33 #define __VALARRAY_ARRAY__
34
35 #include <cstdlib>
36 #include <cstring>
37 #include <std/cpp_type_traits.h>
38
39 extern "C++" {
40
41 //
42 // Helper functions on raw pointers
43 //
44   
45   inline void*
46   __valarray_get_memory(size_t __n)
47   { return operator new(__n); }
48
49   template<typename _Tp>
50   inline _Tp*__restrict__
51   __valarray_get_storage(size_t __n)
52   {
53     return static_cast<_Tp*__restrict__>
54       (__valarray_get_memory(__n * sizeof(_Tp)));
55   }
56   
57   // Return memory to the system
58   inline void
59   __valarray_release_storage(void* __p)
60   { operator delete(__p); }
61
62   // Turn a raw-memory into an array of _Tp filled with _Tp()
63   // This is required in 'valarray<T> v(n);'
64   template<typename _Tp, bool>
65   struct _Array_default_ctor
66   {
67     // Please note that this isn't exception safe.  But
68     // valarrays aren't required to be exception safe.
69     inline static void
70     _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
71     { while (__b != __e) new(__b++) _Tp(); }
72   };
73
74   template<typename _Tp>
75   struct _Array_default_ctor<_Tp, true>
76   {
77     // For fundamental types, it suffices to say 'memset()'
78     inline static void
79     _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
80     { memset(__b, 0, (__e - __b)*sizeof(_Tp)); }
81   };
82
83   template<typename _Tp>
84   inline void
85   __valarray_default_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
86   {
87     _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
88       _S_do_it(__b, __e);
89   }
90     
91   // Turn a raw-memory into an array of _Tp filled with __t
92   // This is the required in valarray<T> v(n, t).  Also
93   // used in valarray<>::resize().
94   template<typename _Tp, bool>
95   struct _Array_init_ctor
96   {
97     // Please note that this isn't exception safe.  But
98     // valarrays aren't required to be exception safe.
99     inline static void
100     _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e, const _Tp __t)
101     { while (__b != __e) new(__b++) _Tp(__t); }
102   };
103
104   template<typename _Tp>
105   struct _Array_init_ctor<_Tp, true>
106   {
107     inline static void
108     _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e,  const _Tp __t)
109     { while (__b != __e) *__b++ = __t; }
110   };
111
112   template<typename _Tp>
113   inline void
114   __valarray_fill_construct(_Tp* __restrict__ __b, _Tp* __restrict__ __e,
115                             const _Tp __t)
116   {
117     _Array_init_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
118       _S_do_it(__b, __e, __t);
119   }
120
121   //
122   // copy-construct raw array [__o, *) from plain array [__b, __e)
123   // We can't just say 'memcpy()'
124   //
125   template<typename _Tp, bool>
126   struct _Array_copy_ctor
127   {
128     // Please note that this isn't exception safe.  But
129     // valarrays aren't required to be exception safe.
130     inline static void
131     _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
132              _Tp* __restrict__ __o)
133     { while (__b != __e) new(__o++) _Tp(*__b++); }
134   };
135
136   template<typename _Tp>
137   struct _Array_copy_ctor<_Tp, true>
138   {
139     inline static void
140     _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e,
141              _Tp* __restrict__ __o)
142     { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); }
143   };
144
145   template<typename _Tp>
146   inline void
147   __valarray_copy_construct(const _Tp* __restrict__ __b,
148                             const _Tp* __restrict__ __e,
149                             _Tp* __restrict__ __o)
150   {
151     _Array_copy_ctor<_Tp, __is_fundamental<_Tp>::_M_type>::
152       _S_do_it(__b, __e, __o);
153   }
154
155   // copy-construct raw array [__o, *) from strided array __a[<__n : __s>]
156   template<typename _Tp>
157   inline void
158   __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n,
159                              size_t __s, _Tp* __restrict__ __o)
160   {
161     if (__is_fundamental<_Tp>::_M_type)
162       while (__n--) { *__o++ = *__a; __a += __s; }
163     else
164       while (__n--) { new(__o++) _Tp(*__a);  __a += __s; }
165   }
166
167   // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]]
168   template<typename _Tp>
169   inline void
170   __valarray_copy_construct (const _Tp* __restrict__ __a,
171                              const size_t* __restrict__ __i,
172                              _Tp* __restrict__ __o, size_t __n)
173   {
174     if (__is_fundamental<_Tp>::_M_type)
175       while (__n--) *__o++ = __a[*__i++];
176     else
177       while (__n--) new (__o++) _Tp(__a[*__i++]);
178   }
179
180   // Do the necessary cleanup when we're done with arrays.
181   template<typename _Tp>
182   inline void
183   __valarray_destroy_elements(_Tp* __restrict__ __b, _Tp* __restrict__ __e)
184   {
185     if (!__is_fundamental<_Tp>::_M_type)
186       while (__b != __e) { __b->~_Tp(); ++__b; }
187   }
188
189   
190   // fill plain array __a[<__n>] with __t
191   template<typename _Tp>
192   inline void
193   __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
194   { while (__n--) *__a++ = __t; }
195   
196   // fill strided array __a[<__n-1 : __s>] with __t
197   template<typename _Tp>
198   inline void
199   __valarray_fill (_Tp* __restrict__ __a, size_t __n,
200                    size_t __s, const _Tp& __t)
201   { for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; }
202   
203   // fill indirect array __a[__i[<__n>]] with __i
204   template<typename _Tp>
205   inline void
206   __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i,
207                   size_t __n, const _Tp& __t)
208   { for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; }
209   
210   // copy plain array __a[<__n>] in __b[<__n>]
211   // For non-fundamental types, it is wrong to say 'memcpy()'
212   template<typename _Tp, bool>
213   struct _Array_copier
214   {
215     inline static void
216     _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
217     { while (__n--) *__b++ = *__a++; }      
218   };
219   
220   template<typename _Tp>
221   struct _Array_copier<_Tp, true>
222   {
223     inline static void
224     _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b)
225     { memcpy (__b, __a, __n * sizeof (_Tp)); }
226   };
227
228   template<typename _Tp>
229   inline void
230   __valarray_copy (const _Tp* __restrict__ __a, size_t __n,
231                    _Tp* __restrict__ __b)
232   {
233     _Array_copier<_Tp, __is_fundamental<_Tp>::_M_type>::
234       _S_do_it(__a, __n, __b);
235   }
236
237 // copy strided array __a[<__n : __s>] in plain __b[<__n>]
238 template<typename _Tp>
239 inline void
240 __valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s,
241                  _Tp* __restrict__ __b)
242 { for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; }
243
244 // copy plain __a[<__n>] in strided __b[<__n : __s>]
245 template<typename _Tp>
246 inline void
247 __valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b,
248                  size_t __n, size_t __s)
249 { for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; }
250
251 // copy indexed __a[__i[<__n>]] in plain __b[<__n>]
252 template<typename _Tp>
253 inline void
254 __valarray_copy (const _Tp* __restrict__ __a,
255                  const size_t* __restrict__ __i,
256                  _Tp* __restrict__ __b, size_t __n)
257 { for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; }
258
259 // copy plain __a[<__n>] in indexed __b[__i[<__n>]]
260 template<typename _Tp>
261 inline void
262 __valarray_copy (const _Tp* __restrict__ __a, size_t __n,
263                  _Tp* __restrict__ __b, const size_t* __restrict__ __i)
264 { for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; }
265
266   //
267   // Compute the sum of elements in range [__f, __l)
268   // This is a naive algorithm.  It suffers from cancelling.
269   // In the future try to specialize
270   // for _Tp = float, double, long double using a more accurate
271   // algorithm.
272   //
273   template<typename _Tp>
274   inline _Tp
275   __valarray_sum(const _Tp* __restrict__ __f, const _Tp* __restrict__ __l)
276   {
277     _Tp __r = _Tp();
278     while (__f != __l) __r = __r + *__f++;
279     return __r;
280   }
281
282   // Compute the product of all elements in range [__f, __l)
283   template<typename _Tp>
284   inline _Tp
285   __valarray_product(const _Tp* __restrict__ __f,
286                      const _Tp* __restrict__ __l)
287   {
288     _Tp __r = _Tp(1);
289     while (__f != __l) __r = __r * *__f++;
290     return __r;
291   }
292   
293
294 //
295 // Helper class _Array, first layer of valarray abstraction.
296 // All operations on valarray should be forwarded to this class
297 // whenever possible. -- gdr
298 //
299
300 template<typename _Tp> struct _Array {
301     
302     explicit _Array (size_t);
303     explicit _Array (_Tp* const __restrict__);
304     explicit _Array (const valarray<_Tp>&);
305     _Array (const _Tp* __restrict__, size_t);
306     
307     _Tp* begin () const;
308     
309     _Tp* const __restrict__ _M_data;
310 };
311
312 template<typename _Tp>
313 inline void
314 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
315 { __valarray_fill (__a._M_data, __n, __t); }
316
317 template<typename _Tp>
318 inline void
319 __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
320 { __valarray_fill (__a._M_data, __n, __s, __t); }
321
322 template<typename _Tp>
323 inline void
324 __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, 
325                  size_t __n, const _Tp& __t)
326 { __valarray_fill (__a._M_data, __i._M_data, __n, __t); }
327
328 template<typename _Tp>
329 inline void
330 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
331 { __valarray_copy (__a._M_data, __n, __b._M_data); }
332
333 template<typename _Tp>
334 inline void
335 __valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b)
336 { __valarray_copy(__a._M_data, __n, __s, __b._M_data); }
337
338 template<typename _Tp>
339 inline void
340 __valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s)
341 { __valarray_copy (__a._M_data, __b._M_data, __n, __s); }
342
343 template<typename _Tp>
344 inline void
345 __valarray_copy (_Array<_Tp> __a, _Array<size_t> __i, 
346                  _Array<_Tp> __b, size_t __n)
347 { __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); }
348
349 template<typename _Tp>
350 inline void
351 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, 
352                  _Array<size_t> __i)
353 { __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); }
354
355 template<typename _Tp>
356 inline
357 _Array<_Tp>::_Array (size_t __n)
358   : _M_data (__valarray_get_storage<_Tp>(__n))
359 { __valarray_default_construct(_M_data, _M_data + __n); }
360
361 template<typename _Tp>
362 inline
363 _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {}
364
365 template<typename _Tp>
366 inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) 
367         : _M_data (__v._M_data) {}
368
369 template<typename _Tp>
370 inline
371 _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) 
372   : _M_data (__valarray_get_storage<_Tp>(__s ))
373 { __valarray_copy_construct(__b, __s, _M_data); }
374
375 template<typename _Tp>
376 inline _Tp*
377 _Array<_Tp>::begin () const
378 { return _M_data; }
379
380 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name)                              \
381 template<typename _Tp>                                                  \
382 inline void                                                             \
383 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t)  \
384 {                                                                       \
385     for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p)              \
386       *__p _Op##= __t;                                                  \
387 }                                                                       \
388                                                                         \
389 template<typename _Tp>                                                  \
390 inline void                                                             \
391 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
392 {                                                                       \
393     _Tp* __p (__a._M_data);                                             \
394     for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q)       \
395       *__p _Op##= *__q;                                                 \
396 }                                                                       \
397                                                                         \
398 template<typename _Tp, class _Dom>                                      \
399 void                                                                    \
400 _Array_augmented_##_Name (_Array<_Tp> __a,                              \
401                          const _Expr<_Dom,_Tp>& __e, size_t __n)        \
402 {                                                                       \
403     _Tp* __p (__a._M_data);                                             \
404     for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i];     \
405 }                                                                       \
406                                                                         \
407 template<typename _Tp>                                                  \
408 inline void                                                             \
409 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s,      \
410                          _Array<_Tp> __b)                               \
411 {                                                                       \
412     _Tp* __q (__b._M_data);                                             \
413     for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \
414       *__p _Op##= *__q;                                                 \
415 }                                                                       \
416                                                                         \
417 template<typename _Tp>                                                  \
418 inline void                                                             \
419 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b,             \
420                          size_t __n, size_t __s)                        \
421 {                                                                       \
422     _Tp* __q (__b._M_data);                                             \
423     for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s)    \
424       *__p _Op##= *__q;                                                 \
425 }                                                                       \
426                                                                         \
427 template<typename _Tp, class _Dom>                                      \
428 void                                                                    \
429 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s,                  \
430                           const _Expr<_Dom,_Tp>& __e, size_t __n)       \
431 {                                                                       \
432     _Tp* __p (__a._M_data);                                             \
433     for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i];  \
434 }                                                                       \
435                                                                         \
436 template<typename _Tp>                                                  \
437 inline void                                                             \
438 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i,          \
439                           _Array<_Tp> __b, size_t __n)                  \
440 {                                                                       \
441     _Tp* __q (__b._M_data);                                             \
442     for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q)    \
443         __a._M_data[*__j] _Op##= *__q;                                  \
444 }                                                                       \
445                                                                         \
446 template<typename _Tp>                                                  \
447 inline void                                                             \
448 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n,                  \
449                           _Array<_Tp> __b, _Array<size_t> __i)          \
450 {                                                                       \
451     _Tp* __p (__a._M_data);                                             \
452     for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p)    \
453         *__p _Op##= __b._M_data[*__j];                                  \
454 }                                                                       \
455                                                                         \
456 template<typename _Tp, class _Dom>                                      \
457 void                                                                    \
458 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i,          \
459                           const _Expr<_Dom, _Tp>& __e, size_t __n)      \
460 {                                                                       \
461     size_t* __j (__i._M_data);                                          \
462     for (size_t __k=0; __k<__n; ++__k, ++__j)                           \
463       __a._M_data[*__j] _Op##= __e[__k];                                \
464 }                                                                       \
465                                                                         \
466 template<typename _Tp>                                                  \
467 void                                                                    \
468 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m,            \
469                           _Array<_Tp> __b, size_t __n)                  \
470 {                                                                       \
471     bool* ok (__m._M_data);                                             \
472     _Tp* __p (__a._M_data);                                             \
473     for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \
474         while (! *ok) {                                                 \
475             ++ok;                                                       \
476             ++__p;                                                      \
477         }                                                               \
478         *__p _Op##= *__q;                                               \
479     }                                                                   \
480 }                                                                       \
481                                                                         \
482 template<typename _Tp>                                                  \
483 void                                                                    \
484 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n,                  \
485                          _Array<_Tp> __b, _Array<bool> __m)             \
486 {                                                                       \
487     bool* ok (__m._M_data);                                             \
488     _Tp* __q (__b._M_data);                                             \
489     for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \
490         while (! *ok) {                                                 \
491             ++ok;                                                       \
492             ++__q;                                                      \
493         }                                                               \
494         *__p _Op##= *__q;                                               \
495     }                                                                   \
496 }                                                                       \
497                                                                         \
498 template<typename _Tp, class _Dom>                                      \
499 void                                                                    \
500 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m,            \
501                           const _Expr<_Dom, _Tp>& __e, size_t __n)      \
502 {                                                                       \
503     bool* ok(__m._M_data);                                              \
504     _Tp* __p (__a._M_data);                                             \
505     for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) {                   \
506         while (! *ok) {                                                 \
507             ++ok;                                                       \
508             ++__p;                                                      \
509         }                                                               \
510         *__p _Op##= __e[__i];                                           \
511     }                                                                   \
512 }
513
514 _DEFINE_ARRAY_FUNCTION(+, plus)
515 _DEFINE_ARRAY_FUNCTION(-, minus)
516 _DEFINE_ARRAY_FUNCTION(*, multiplies)
517 _DEFINE_ARRAY_FUNCTION(/, divides)
518 _DEFINE_ARRAY_FUNCTION(%, modulus)
519 _DEFINE_ARRAY_FUNCTION(^, xor)
520 _DEFINE_ARRAY_FUNCTION(|, or)
521 _DEFINE_ARRAY_FUNCTION(&, and)    
522 _DEFINE_ARRAY_FUNCTION(<<, shift_left)
523 _DEFINE_ARRAY_FUNCTION(>>, shift_right)
524
525 #undef _DEFINE_ARRAY_FUNCTION    
526
527 } // extern "C++"
528     
529 #ifdef _G_NO_VALARRAY_TEMPLATE_EXPORT
530 # define export 
531 # include <std/valarray_array.tcc>    
532 #endif
533            
534 #endif // __VALARRAY_ARRAY__
535
536 // Local Variables:
537 // mode:c++
538 // End: