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
38extern "C++" {
39
40//
41// Helper functions on raw pointers
42//
43
44// fill plain array __a[<__n>] with __t
45template<typename _Tp>
46inline 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
51template<typename _Tp>
52inline 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
58template<typename _Tp>
59inline 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>]
65template<typename _Tp>
66inline 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>]
72template<typename _Tp>
73inline 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>]
79template<typename _Tp>
80inline 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>]
86template<typename _Tp>
87inline 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>]]
94template<typename _Tp>
95inline 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
106template<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
119template<typename _Tp>
120inline void
121__valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t)
122{ __valarray_fill (__a._M_data, __n, __t); }
123
124template<typename _Tp>
125inline 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
129template<typename _Tp>
130inline 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
135template<typename _Tp>
136inline void
137__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b)
138{ __valarray_copy (__a._M_data, __n, __b._M_data); }
139
140template<typename _Tp>
141inline 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
145template<typename _Tp>
146inline 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
150template<typename _Tp>
151inline 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
156template<typename _Tp>
157inline 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
162template<typename _Tp>
163inline
164_Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {}
165
166template<typename _Tp>
167inline
168_Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {}
169
170template<typename _Tp>
171inline _Array<_Tp>::_Array (const valarray<_Tp>& __v)
172        : _M_data (__v._M_data) {}
173
174template<typename _Tp>
175inline
176_Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s)
177        : _M_data (new _Tp[__s]) { __valarray_copy (__b, __s, _M_data); }
178
179template<typename _Tp>
180inline void
181_Array<_Tp>::free_data() const { delete[] _M_data; }
182
183template<typename _Tp>
184inline _Tp*
185_Array<_Tp>::begin () const
186{ return _M_data; }
187
188#define _DEFINE_ARRAY_FUNCTION(_Op, _Name)				\
189template<typename _Tp>							\
190inline 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									\
197template<typename _Tp>							\
198inline 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									\
206template<typename _Tp, class _Dom>					\
207void									\
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									\
215template<typename _Tp>							\
216inline 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									\
225template<typename _Tp>							\
226inline 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									\
235template<typename _Tp, class _Dom>					\
236void									\
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									\
244template<typename _Tp>							\
245inline 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									\
254template<typename _Tp>							\
255inline 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									\
264template<typename _Tp, class _Dom>					\
265void									\
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									\
274template<typename _Tp>							\
275void									\
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									\
290template<typename _Tp>							\
291void									\
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									\
306template<typename _Tp, class _Dom>					\
307void									\
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