xref: /haiku/headers/cpp/std/valarray_array.h (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
164 _Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {}
165 
166 template<typename _Tp>
167 inline
168 _Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {}
169 
170 template<typename _Tp>
171 inline _Array<_Tp>::_Array (const valarray<_Tp>& __v)
172         : _M_data (__v._M_data) {}
173 
174 template<typename _Tp>
175 inline
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
181 _Array<_Tp>::free_data() const { delete[] _M_data; }
182 
183 template<typename _Tp>
184 inline _Tp*
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