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
38 extern "C++" {
39
40 //
41 // Helper functions on raw pointers
42 //
43
44 // fill plain array __a[<__n>] with __t
45 template<typename _Tp>
46 inline void
__valarray_fill(_Tp * __restrict__ __a,size_t __n,const _Tp & __t)47 __valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t)
48 { while (__n--) *__a++ = __t; }
49
50 // fill strided array __a[<__n-1 : __s>] with __t
51 template<typename _Tp>
52 inline void
__valarray_fill(_Tp * __restrict__ __a,size_t __n,size_t __s,const _Tp & __t)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; }
56
57 // fill indirect array __a[__i[<__n>]] with __i
58 template<typename _Tp>
59 inline void
__valarray_fill(_Tp * __restrict__ __a,const size_t * __restrict__ __i,size_t __n,const _Tp & __t)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; }
63
64 // copy plain array __a[<__n>] in __b[<__n>]
65 template<typename _Tp>
66 inline void
__valarray_copy(const _Tp * __restrict__ __a,size_t __n,_Tp * __restrict__ __b)67 __valarray_copy (const _Tp* __restrict__ __a, size_t __n,
68 _Tp* __restrict__ __b)
69 { memcpy (__b, __a, __n * sizeof(_Tp)); }
70
71 // copy strided array __a[<__n : __s>] in plain __b[<__n>]
72 template<typename _Tp>
73 inline void
__valarray_copy(const _Tp * __restrict__ __a,size_t __n,size_t __s,_Tp * __restrict__ __b)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; }
77
78 // copy plain __a[<__n>] in strided __b[<__n : __s>]
79 template<typename _Tp>
80 inline void
__valarray_copy(const _Tp * __restrict__ __a,_Tp * __restrict__ __b,size_t __n,size_t __s)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; }
84
85 // copy indexed __a[__i[<__n>]] in plain __b[<__n>]
86 template<typename _Tp>
87 inline void
__valarray_copy(const _Tp * __restrict__ __a,const size_t * __restrict__ __i,_Tp * __restrict__ __b,size_t __n)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]; }
92
93 // copy plain __a[<__n>] in indexed __b[__i[<__n>]]
94 template<typename _Tp>
95 inline void
__valarray_copy(const _Tp * __restrict__ __a,size_t __n,_Tp * __restrict__ __b,const size_t * __restrict__ __i)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; }
99
100 //
101 // Helper class _Array, first layer of valarray abstraction.
102 // All operations on valarray should be forwarded to this class
103 // whenever possible. -- gdr
104 //
105
106 template<typename _Tp> struct _Array {
107
108 explicit _Array (size_t);
109 explicit _Array (_Tp* const __restrict__);
110 explicit _Array (const valarray<_Tp>&);
111 _Array (const _Tp* __restrict__, size_t);
112
113 void free_data() const;
114 _Tp* begin () const;
115
116 _Tp* const __restrict__ _M_data;
117 };
118
119 template<typename _Tp>
120 inline void
__valarray_fill(_Array<_Tp> __a,size_t __n,const _Tp & __t)121 __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
122 { __valarray_fill (__a._M_data, __n, __t); }
123
124 template<typename _Tp>
125 inline void
__valarray_fill(_Array<_Tp> __a,size_t __n,size_t __s,const _Tp & __t)126 __valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t)
127 { __valarray_fill (__a._M_data, __n, __s, __t); }
128
129 template<typename _Tp>
130 inline void
__valarray_fill(_Array<_Tp> __a,_Array<size_t> __i,size_t __n,const _Tp & __t)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); }
134
135 template<typename _Tp>
136 inline void
__valarray_copy(_Array<_Tp> __a,size_t __n,_Array<_Tp> __b)137 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
138 { __valarray_copy (__a._M_data, __n, __b._M_data); }
139
140 template<typename _Tp>
141 inline void
__valarray_copy(_Array<_Tp> __a,size_t __n,size_t __s,_Array<_Tp> __b)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); }
144
145 template<typename _Tp>
146 inline void
__valarray_copy(_Array<_Tp> __a,_Array<_Tp> __b,size_t __n,size_t __s)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); }
149
150 template<typename _Tp>
151 inline void
__valarray_copy(_Array<_Tp> __a,_Array<size_t> __i,_Array<_Tp> __b,size_t __n)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); }
155
156 template<typename _Tp>
157 inline void
__valarray_copy(_Array<_Tp> __a,size_t __n,_Array<_Tp> __b,_Array<size_t> __i)158 __valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
159 _Array<size_t> __i)
160 { __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); }
161
162 template<typename _Tp>
163 inline
_Array(size_t __n)164 _Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {}
165
166 template<typename _Tp>
167 inline
_Array(_Tp * const __restrict__ __p)168 _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {}
169
170 template<typename _Tp>
_Array(const valarray<_Tp> & __v)171 inline _Array<_Tp>::_Array (const valarray<_Tp>& __v)
172 : _M_data (__v._M_data) {}
173
174 template<typename _Tp>
175 inline
_Array(const _Tp * __restrict__ __b,size_t __s)176 _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s)
177 : _M_data (new _Tp[__s]) { __valarray_copy (__b, __s, _M_data); }
178
179 template<typename _Tp>
180 inline void
free_data()181 _Array<_Tp>::free_data() const { delete[] _M_data; }
182
183 template<typename _Tp>
184 inline _Tp*
begin()185 _Array<_Tp>::begin () const
186 { return _M_data; }
187
188 #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \
189 template<typename _Tp> \
190 inline void \
191 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \
192 { \
193 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \
194 *__p _Op##= __t; \
195 } \
196 \
197 template<typename _Tp> \
198 inline void \
199 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \
200 { \
201 _Tp* __p (__a._M_data); \
202 for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \
203 *__p _Op##= *__q; \
204 } \
205 \
206 template<typename _Tp, class _Dom> \
207 void \
208 _Array_augmented_##_Name (_Array<_Tp> __a, \
209 const _Expr<_Dom,_Tp>& __e, size_t __n) \
210 { \
211 _Tp* __p (__a._M_data); \
212 for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \
213 } \
214 \
215 template<typename _Tp> \
216 inline void \
217 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \
218 _Array<_Tp> __b) \
219 { \
220 _Tp* __q (__b._M_data); \
221 for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \
222 *__p _Op##= *__q; \
223 } \
224 \
225 template<typename _Tp> \
226 inline void \
227 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \
228 size_t __n, size_t __s) \
229 { \
230 _Tp* __q (__b._M_data); \
231 for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \
232 *__p _Op##= *__q; \
233 } \
234 \
235 template<typename _Tp, class _Dom> \
236 void \
237 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \
238 const _Expr<_Dom,_Tp>& __e, size_t __n) \
239 { \
240 _Tp* __p (__a._M_data); \
241 for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \
242 } \
243 \
244 template<typename _Tp> \
245 inline void \
246 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \
247 _Array<_Tp> __b, size_t __n) \
248 { \
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; \
252 } \
253 \
254 template<typename _Tp> \
255 inline void \
256 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \
257 _Array<_Tp> __b, _Array<size_t> __i) \
258 { \
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]; \
262 } \
263 \
264 template<typename _Tp, class _Dom> \
265 void \
266 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \
267 const _Expr<_Dom, _Tp>& __e, size_t __n) \
268 { \
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]; \
272 } \
273 \
274 template<typename _Tp> \
275 void \
276 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \
277 _Array<_Tp> __b, size_t __n) \
278 { \
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) { \
282 while (! *ok) { \
283 ++ok; \
284 ++__p; \
285 } \
286 *__p _Op##= *__q; \
287 } \
288 } \
289 \
290 template<typename _Tp> \
291 void \
292 _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \
293 _Array<_Tp> __b, _Array<bool> __m) \
294 { \
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) { \
298 while (! *ok) { \
299 ++ok; \
300 ++__q; \
301 } \
302 *__p _Op##= *__q; \
303 } \
304 } \
305 \
306 template<typename _Tp, class _Dom> \
307 void \
308 _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \
309 const _Expr<_Dom, _Tp>& __e, size_t __n) \
310 { \
311 bool* ok(__m._M_data); \
312 _Tp* __p (__a._M_data); \
313 for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \
314 while (! *ok) { \
315 ++ok; \
316 ++__p; \
317 } \
318 *__p _Op##= __e[__i]; \
319 } \
320 }
321
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)
332
333 #undef _DEFINE_ARRAY_FUNCTION
334
335 } // extern "C++"
336
337 #ifdef _G_NO_VALARRAY_TEMPLATE_EXPORT
338 # define export
339 # include <std/valarray_array.tcc>
340 #endif
341
342 #endif // __VALARRAY_ARRAY__
343
344 // Local Variables:
345 // mode:c++
346 // End:
347