1 // The template and inlines for the -*- C++ -*- internal _Array helper class.
3 // Copyright (C) 1997-1999 Cygnus Solutions
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)
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.
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,
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.
30 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
32 #ifndef __VALARRAY_ARRAY__
33 #define __VALARRAY_ARRAY__
41 // Helper functions on raw pointers
44 // fill plain array __a[<__n>] with __t
45 template<typename _Tp
>
47 __valarray_fill (_Tp
* __restrict__ __a
, size_t __n
, const _Tp
& __t
)
48 { while (__n
--) *__a
++ = __t
; }
50 // fill strided array __a[<__n-1 : __s>] with __t
51 template<typename _Tp
>
53 __valarray_fill (_Tp
* __restrict__ __a
, size_t __n
,
54 size_t __s
, const _Tp
& __t
)
55 { for (size_t __i
=0; __i
<__n
; ++__i
, __a
+=__s
) *__a
= __t
; }
57 // fill indirect array __a[__i[<__n>]] with __i
58 template<typename _Tp
>
60 __valarray_fill(_Tp
* __restrict__ __a
, const size_t* __restrict__ __i
,
61 size_t __n
, const _Tp
& __t
)
62 { for (size_t __j
=0; __j
<__n
; ++__j
, ++__i
) __a
[*__i
] = __t
; }
64 // copy plain array __a[<__n>] in __b[<__n>]
65 template<typename _Tp
>
67 __valarray_copy (const _Tp
* __restrict__ __a
, size_t __n
,
68 _Tp
* __restrict__ __b
)
69 { memcpy (__b
, __a
, __n
* sizeof(_Tp
)); }
71 // copy strided array __a[<__n : __s>] in plain __b[<__n>]
72 template<typename _Tp
>
74 __valarray_copy (const _Tp
* __restrict__ __a
, size_t __n
, size_t __s
,
75 _Tp
* __restrict__ __b
)
76 { for (size_t __i
=0; __i
<__n
; ++__i
, ++__b
, __a
+= __s
) *__b
= *__a
; }
78 // copy plain __a[<__n>] in strided __b[<__n : __s>]
79 template<typename _Tp
>
81 __valarray_copy (const _Tp
* __restrict__ __a
, _Tp
* __restrict__ __b
,
82 size_t __n
, size_t __s
)
83 { for (size_t __i
=0; __i
<__n
; ++__i
, ++__a
, __b
+=__s
) *__b
= *__a
; }
85 // copy indexed __a[__i[<__n>]] in plain __b[<__n>]
86 template<typename _Tp
>
88 __valarray_copy (const _Tp
* __restrict__ __a
,
89 const size_t* __restrict__ __i
,
90 _Tp
* __restrict__ __b
, size_t __n
)
91 { for (size_t __j
=0; __j
<__n
; ++__j
, ++__b
, ++__i
) *__b
= __a
[*__i
]; }
93 // copy plain __a[<__n>] in indexed __b[__i[<__n>]]
94 template<typename _Tp
>
96 __valarray_copy (const _Tp
* __restrict__ __a
, size_t __n
,
97 _Tp
* __restrict__ __b
, const size_t* __restrict__ __i
)
98 { for (size_t __j
=0; __j
<__n
; ++__j
, ++__a
, ++__i
) __b
[*__i
] = *__a
; }
101 // Helper class _Array, first layer of valarray abstraction.
102 // All operations on valarray should be forwarded to this class
103 // whenever possible. -- gdr
106 template<typename _Tp
> struct _Array
{
108 explicit _Array (size_t);
109 explicit _Array (_Tp
* const __restrict__
);
110 explicit _Array (const valarray
<_Tp
>&);
111 _Array (const _Tp
* __restrict__
, size_t);
113 void free_data() const;
116 _Tp
* const __restrict__ _M_data
;
119 template<typename _Tp
>
121 __valarray_fill (_Array
<_Tp
> __a
, size_t __n
, const _Tp
& __t
)
122 { __valarray_fill (__a
._M_data
, __n
, __t
); }
124 template<typename _Tp
>
126 __valarray_fill (_Array
<_Tp
> __a
, size_t __n
, size_t __s
, const _Tp
& __t
)
127 { __valarray_fill (__a
._M_data
, __n
, __s
, __t
); }
129 template<typename _Tp
>
131 __valarray_fill (_Array
<_Tp
> __a
, _Array
<size_t> __i
,
132 size_t __n
, const _Tp
& __t
)
133 { __valarray_fill (__a
._M_data
, __i
._M_data
, __n
, __t
); }
135 template<typename _Tp
>
137 __valarray_copy (_Array
<_Tp
> __a
, size_t __n
, _Array
<_Tp
> __b
)
138 { __valarray_copy (__a
._M_data
, __n
, __b
._M_data
); }
140 template<typename _Tp
>
142 __valarray_copy (_Array
<_Tp
> __a
, size_t __n
, size_t __s
, _Array
<_Tp
> __b
)
143 { __valarray_copy(__a
._M_data
, __n
, __s
, __b
._M_data
); }
145 template<typename _Tp
>
147 __valarray_copy (_Array
<_Tp
> __a
, _Array
<_Tp
> __b
, size_t __n
, size_t __s
)
148 { __valarray_copy (__a
._M_data
, __b
._M_data
, __n
, __s
); }
150 template<typename _Tp
>
152 __valarray_copy (_Array
<_Tp
> __a
, _Array
<size_t> __i
,
153 _Array
<_Tp
> __b
, size_t __n
)
154 { __valarray_copy (__a
._M_data
, __i
._M_data
, __b
._M_data
, __n
); }
156 template<typename _Tp
>
158 __valarray_copy (_Array
<_Tp
> __a
, size_t __n
, _Array
<_Tp
> __b
,
160 { __valarray_copy (__a
._M_data
, __n
, __b
._M_data
, __i
._M_data
); }
162 template<typename _Tp
>
164 _Array
<_Tp
>::_Array (size_t __n
) : _M_data (new _Tp
[__n
]) {}
166 template<typename _Tp
>
168 _Array
<_Tp
>::_Array (_Tp
* const __restrict__ __p
) : _M_data (__p
) {}
170 template<typename _Tp
>
171 inline _Array
<_Tp
>::_Array (const valarray
<_Tp
>& __v
)
172 : _M_data (__v
._M_data
) {}
174 template<typename _Tp
>
176 _Array
<_Tp
>::_Array (const _Tp
* __restrict__ __b
, size_t __s
)
177 : _M_data (new _Tp
[__s
]) { __valarray_copy (__b
, __s
, _M_data
); }
179 template<typename _Tp
>
181 _Array
<_Tp
>::free_data() const { delete[] _M_data
; }
183 template<typename _Tp
>
185 _Array
<_Tp
>::begin () const
188 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \
189 template<typename _Tp> \
191 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \
193 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \
197 template<typename _Tp> \
199 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
201 _Tp* __p (__a._M_data); \
202 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \
206 template<typename _Tp, class _Dom> \
208 _Array_augmented_##_Name (_Array<_Tp> __a, \
209 const _Expr<_Dom,_Tp>& __e, size_t __n) \
211 _Tp* __p (__a._M_data); \
212 for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \
215 template<typename _Tp> \
217 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \
220 _Tp* __q (__b._M_data); \
221 for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \
225 template<typename _Tp> \
227 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \
228 size_t __n, size_t __s) \
230 _Tp* __q (__b._M_data); \
231 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \
235 template<typename _Tp, class _Dom> \
237 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \
238 const _Expr<_Dom,_Tp>& __e, size_t __n) \
240 _Tp* __p (__a._M_data); \
241 for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \
244 template<typename _Tp> \
246 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \
247 _Array<_Tp> __b, size_t __n) \
249 _Tp* __q (__b._M_data); \
250 for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \
251 __a._M_data[*__j] _Op##= *__q; \
254 template<typename _Tp> \
256 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \
257 _Array<_Tp> __b, _Array<size_t> __i) \
259 _Tp* __p (__a._M_data); \
260 for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \
261 *__p _Op##= __b._M_data[*__j]; \
264 template<typename _Tp, class _Dom> \
266 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \
267 const _Expr<_Dom, _Tp>& __e, size_t __n) \
269 size_t* __j (__i._M_data); \
270 for (size_t __k=0; __k<__n; ++__k, ++__j) \
271 __a._M_data[*__j] _Op##= __e[__k]; \
274 template<typename _Tp> \
276 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \
277 _Array<_Tp> __b, size_t __n) \
279 bool* ok (__m._M_data); \
280 _Tp* __p (__a._M_data); \
281 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \
290 template<typename _Tp> \
292 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \
293 _Array<_Tp> __b, _Array<bool> __m) \
295 bool* ok (__m._M_data); \
296 _Tp* __q (__b._M_data); \
297 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \
306 template<typename _Tp, class _Dom> \
308 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \
309 const _Expr<_Dom, _Tp>& __e, size_t __n) \
311 bool* ok(__m._M_data); \
312 _Tp* __p (__a._M_data); \
313 for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \
318 *__p _Op##= __e[__i]; \
322 _DEFINE_ARRAY_FUNCTION(+, plus
)
323 _DEFINE_ARRAY_FUNCTION(-, minus
)
324 _DEFINE_ARRAY_FUNCTION(*, multiplies
)
325 _DEFINE_ARRAY_FUNCTION(/, divides
)
326 _DEFINE_ARRAY_FUNCTION(%, modulus
)
327 _DEFINE_ARRAY_FUNCTION(^, xor)
328 _DEFINE_ARRAY_FUNCTION(|, or)
329 _DEFINE_ARRAY_FUNCTION(&, and)
330 _DEFINE_ARRAY_FUNCTION(<<, shift_left
)
331 _DEFINE_ARRAY_FUNCTION(>>, shift_right
)
333 #undef _DEFINE_ARRAY_FUNCTION
337 #ifdef _G_NO_VALARRAY_TEMPLATE_EXPORT
339 # include <std/valarray_array.tcc>
342 #endif // __VALARRAY_ARRAY__