100db7afdSDavid E. O'Brien // The template and inlines for the -*- C++ -*- internal _Array helper class.
200db7afdSDavid E. O'Brien 
3*ffeaf689SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
400db7afdSDavid E. O'Brien //
500db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
600db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
700db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
800db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
900db7afdSDavid E. O'Brien // any later version.
1000db7afdSDavid E. O'Brien 
1100db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1200db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1300db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1400db7afdSDavid E. O'Brien // GNU General Public License for more details.
1500db7afdSDavid E. O'Brien 
1600db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1700db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
1800db7afdSDavid E. O'Brien // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
1900db7afdSDavid E. O'Brien // USA.
2000db7afdSDavid E. O'Brien 
2100db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2200db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
2300db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2400db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2500db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2600db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
2700db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2800db7afdSDavid E. O'Brien // the GNU General Public License.
2900db7afdSDavid E. O'Brien 
3000db7afdSDavid E. O'Brien // Written by Gabriel Dos Reis <[email protected]>
3100db7afdSDavid E. O'Brien 
32*ffeaf689SAlexander Kabaev #ifndef _VALARRAY_ARRAY_TCC
33*ffeaf689SAlexander Kabaev #define _VALARRAY_ARRAY_TCC 1
3400db7afdSDavid E. O'Brien 
3500db7afdSDavid E. O'Brien namespace std
3600db7afdSDavid E. O'Brien {
37*ffeaf689SAlexander Kabaev   template<typename _Tp>
3800db7afdSDavid E. O'Brien     void
39*ffeaf689SAlexander Kabaev     __valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m,
40*ffeaf689SAlexander Kabaev 		    const _Tp& __t)
4100db7afdSDavid E. O'Brien     {
4200db7afdSDavid E. O'Brien       _Tp* __p = __a._M_data;
4300db7afdSDavid E. O'Brien       bool* __ok (__m._M_data);
44*ffeaf689SAlexander Kabaev       for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p)
45*ffeaf689SAlexander Kabaev 	{
46*ffeaf689SAlexander Kabaev 	  while (!*__ok)
47*ffeaf689SAlexander Kabaev 	  {
4800db7afdSDavid E. O'Brien 	    ++__ok;
4900db7afdSDavid E. O'Brien 	    ++__p;
5000db7afdSDavid E. O'Brien 	  }
5100db7afdSDavid E. O'Brien 	  *__p = __t;
5200db7afdSDavid E. O'Brien 	}
5300db7afdSDavid E. O'Brien     }
5400db7afdSDavid E. O'Brien 
55*ffeaf689SAlexander Kabaev   // Copy n elements of a into consecutive elements of b.  When m is
56*ffeaf689SAlexander Kabaev   // false, the corresponding element of a is skipped.  m must contain
57*ffeaf689SAlexander Kabaev   // at least n true elements.  a must contain at least n elements and
58*ffeaf689SAlexander Kabaev   // enough elements to match up with m through the nth true element
59*ffeaf689SAlexander Kabaev   // of m.  I.e.  if n is 10, m has 15 elements with 5 false followed
60*ffeaf689SAlexander Kabaev   // by 10 true, a must have 15 elements.
61*ffeaf689SAlexander Kabaev   template<typename _Tp>
6200db7afdSDavid E. O'Brien     void
63*ffeaf689SAlexander Kabaev     __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b,
64*ffeaf689SAlexander Kabaev 		    size_t __n)
6500db7afdSDavid E. O'Brien     {
6600db7afdSDavid E. O'Brien       _Tp* __p (__a._M_data);
6700db7afdSDavid E. O'Brien       bool* __ok (__m._M_data);
68*ffeaf689SAlexander Kabaev       for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;
69*ffeaf689SAlexander Kabaev 	   ++__q, ++__ok, ++__p)
70*ffeaf689SAlexander Kabaev 	{
71*ffeaf689SAlexander Kabaev 	  while (! *__ok)
72*ffeaf689SAlexander Kabaev 	    {
7300db7afdSDavid E. O'Brien 	      ++__ok;
7400db7afdSDavid E. O'Brien 	      ++__p;
7500db7afdSDavid E. O'Brien 	    }
7600db7afdSDavid E. O'Brien 	  *__q = *__p;
7700db7afdSDavid E. O'Brien 	}
7800db7afdSDavid E. O'Brien     }
7900db7afdSDavid E. O'Brien 
80*ffeaf689SAlexander Kabaev   // Copy n consecutive elements from a into elements of b.  Elements
81*ffeaf689SAlexander Kabaev   // of b are skipped if the corresponding element of m is false.  m
82*ffeaf689SAlexander Kabaev   // must contain at least n true elements.  b must have at least as
83*ffeaf689SAlexander Kabaev   // many elements as the index of the nth true element of m.  I.e. if
84*ffeaf689SAlexander Kabaev   // m has 15 elements with 5 false followed by 10 true, b must have
85*ffeaf689SAlexander Kabaev   // at least 15 elements.
86*ffeaf689SAlexander Kabaev   template<typename _Tp>
8700db7afdSDavid E. O'Brien     void
88*ffeaf689SAlexander Kabaev     __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
89*ffeaf689SAlexander Kabaev 		    _Array<bool> __m)
9000db7afdSDavid E. O'Brien     {
9100db7afdSDavid E. O'Brien       _Tp* __q (__b._M_data);
9200db7afdSDavid E. O'Brien       bool* __ok (__m._M_data);
93*ffeaf689SAlexander Kabaev       for (_Tp* __p = __a._M_data; __p < __a._M_data+__n;
94*ffeaf689SAlexander Kabaev 	   ++__p, ++__ok, ++__q)
95*ffeaf689SAlexander Kabaev 	{
96*ffeaf689SAlexander Kabaev 	  while (! *__ok)
97*ffeaf689SAlexander Kabaev 	    {
9800db7afdSDavid E. O'Brien 	      ++__ok;
9900db7afdSDavid E. O'Brien 	      ++__q;
10000db7afdSDavid E. O'Brien 	    }
10100db7afdSDavid E. O'Brien 	  *__q = *__p;
10200db7afdSDavid E. O'Brien 	}
10300db7afdSDavid E. O'Brien     }
10400db7afdSDavid E. O'Brien 
105*ffeaf689SAlexander Kabaev   // Copy n elements from a into elements of b.  Elements of a are
106*ffeaf689SAlexander Kabaev   // skipped if the corresponding element of m is false.  Elements of
107*ffeaf689SAlexander Kabaev   // b are skipped if the corresponding element of k is false.  m and
108*ffeaf689SAlexander Kabaev   // k must contain at least n true elements.  a and b must have at
109*ffeaf689SAlexander Kabaev   // least as many elements as the index of the nth true element of m.
110*ffeaf689SAlexander Kabaev   template<typename _Tp>
111*ffeaf689SAlexander Kabaev     void
112*ffeaf689SAlexander Kabaev     __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n,
113*ffeaf689SAlexander Kabaev 		    _Array<_Tp> __b, _Array<bool> __k)
114*ffeaf689SAlexander Kabaev     {
115*ffeaf689SAlexander Kabaev       _Tp* __p (__a._M_data);
116*ffeaf689SAlexander Kabaev       _Tp* __q (__b._M_data);
117*ffeaf689SAlexander Kabaev       bool* __srcok (__m._M_data);
118*ffeaf689SAlexander Kabaev       bool* __dstok (__k._M_data);
119*ffeaf689SAlexander Kabaev       for (size_t __i = 0; __i < __n;
120*ffeaf689SAlexander Kabaev 	   ++__srcok, ++__p, ++__dstok, ++__q, ++__i)
121*ffeaf689SAlexander Kabaev 	{
122*ffeaf689SAlexander Kabaev 	  while (! *__srcok)
123*ffeaf689SAlexander Kabaev 	    {
124*ffeaf689SAlexander Kabaev 	      ++__srcok;
125*ffeaf689SAlexander Kabaev 	      ++__p;
126*ffeaf689SAlexander Kabaev 	    }
127*ffeaf689SAlexander Kabaev 	  while (! *__dstok)
128*ffeaf689SAlexander Kabaev 	    {
129*ffeaf689SAlexander Kabaev 	      ++__dstok;
130*ffeaf689SAlexander Kabaev 	      ++__q;
131*ffeaf689SAlexander Kabaev 	    }
132*ffeaf689SAlexander Kabaev 	  *__q = *__p;
133*ffeaf689SAlexander Kabaev 	}
134*ffeaf689SAlexander Kabaev     }
135*ffeaf689SAlexander Kabaev 
136*ffeaf689SAlexander Kabaev   // Copy n consecutive elements of e into consecutive elements of a.
137*ffeaf689SAlexander Kabaev   // I.e. a[i] = e[i].
138*ffeaf689SAlexander Kabaev   template<typename _Tp, class _Dom>
13900db7afdSDavid E. O'Brien     void
14000db7afdSDavid E. O'Brien     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a)
14100db7afdSDavid E. O'Brien     {
14200db7afdSDavid E. O'Brien       _Tp* __p (__a._M_data);
143*ffeaf689SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__p)
144*ffeaf689SAlexander Kabaev 	*__p = __e[__i];
14500db7afdSDavid E. O'Brien     }
14600db7afdSDavid E. O'Brien 
147*ffeaf689SAlexander Kabaev   // Copy n consecutive elements of e into elements of a using stride
148*ffeaf689SAlexander Kabaev   // s.  I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2].
149*ffeaf689SAlexander Kabaev   template<typename _Tp, class _Dom>
15000db7afdSDavid E. O'Brien     void
15100db7afdSDavid E. O'Brien     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
15200db7afdSDavid E. O'Brien 		     _Array<_Tp> __a, size_t __s)
15300db7afdSDavid E. O'Brien     {
15400db7afdSDavid E. O'Brien       _Tp* __p (__a._M_data);
155*ffeaf689SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, __p += __s)
156*ffeaf689SAlexander Kabaev 	*__p = __e[__i];
15700db7afdSDavid E. O'Brien     }
15800db7afdSDavid E. O'Brien 
159*ffeaf689SAlexander Kabaev   // Copy n consecutive elements of e into elements of a indexed by
160*ffeaf689SAlexander Kabaev   // contents of i.  I.e., a[i[0]] = e[0].
161*ffeaf689SAlexander Kabaev   template<typename _Tp, class _Dom>
16200db7afdSDavid E. O'Brien     void
16300db7afdSDavid E. O'Brien     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
16400db7afdSDavid E. O'Brien 		    _Array<_Tp> __a, _Array<size_t> __i)
16500db7afdSDavid E. O'Brien     {
16600db7afdSDavid E. O'Brien       size_t* __j (__i._M_data);
167*ffeaf689SAlexander Kabaev       for (size_t __k = 0; __k < __n; ++__k, ++__j)
168*ffeaf689SAlexander Kabaev 	__a._M_data[*__j] = __e[__k];
16900db7afdSDavid E. O'Brien     }
17000db7afdSDavid E. O'Brien 
171*ffeaf689SAlexander Kabaev   // Copy n elements of e indexed by contents of f into elements of a
172*ffeaf689SAlexander Kabaev   // indexed by contents of i.  I.e., a[i[0]] = e[f[0]].
173*ffeaf689SAlexander Kabaev   template<typename _Tp>
174*ffeaf689SAlexander Kabaev     void
175*ffeaf689SAlexander Kabaev     __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f,
176*ffeaf689SAlexander Kabaev 		    size_t __n,
177*ffeaf689SAlexander Kabaev 		    _Array<_Tp> __a, _Array<size_t> __i)
178*ffeaf689SAlexander Kabaev     {
179*ffeaf689SAlexander Kabaev       size_t* __g (__f._M_data);
180*ffeaf689SAlexander Kabaev       size_t* __j (__i._M_data);
181*ffeaf689SAlexander Kabaev       for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g)
182*ffeaf689SAlexander Kabaev 	__a._M_data[*__j] = __e._M_data[*__g];
183*ffeaf689SAlexander Kabaev     }
184*ffeaf689SAlexander Kabaev 
185*ffeaf689SAlexander Kabaev   // Copy n consecutive elements of e into elements of a.  Elements of
186*ffeaf689SAlexander Kabaev   // a are skipped if the corresponding element of m is false.  m must
187*ffeaf689SAlexander Kabaev   // have at least n true elements and a must have at least as many
188*ffeaf689SAlexander Kabaev   // elements as the index of the nth true element of m.  I.e. if m
189*ffeaf689SAlexander Kabaev   // has 5 false followed by 10 true elements and n == 10, a must have
190*ffeaf689SAlexander Kabaev   // at least 15 elements.
191*ffeaf689SAlexander Kabaev   template<typename _Tp, class _Dom>
19200db7afdSDavid E. O'Brien     void
19300db7afdSDavid E. O'Brien     __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
19400db7afdSDavid E. O'Brien 		    _Array<_Tp> __a, _Array<bool> __m)
19500db7afdSDavid E. O'Brien     {
19600db7afdSDavid E. O'Brien       bool* __ok (__m._M_data);
19700db7afdSDavid E. O'Brien       _Tp* __p (__a._M_data);
198*ffeaf689SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
199*ffeaf689SAlexander Kabaev 	{
200*ffeaf689SAlexander Kabaev 	  while (! *__ok)
201*ffeaf689SAlexander Kabaev 	    {
20200db7afdSDavid E. O'Brien 	      ++__ok;
20300db7afdSDavid E. O'Brien 	      ++__p;
20400db7afdSDavid E. O'Brien 	    }
20500db7afdSDavid E. O'Brien 	  *__p = __e[__i];
20600db7afdSDavid E. O'Brien 	}
20700db7afdSDavid E. O'Brien     }
20800db7afdSDavid E. O'Brien 
20900db7afdSDavid E. O'Brien 
210*ffeaf689SAlexander Kabaev   template<typename _Tp, class _Dom>
21100db7afdSDavid E. O'Brien     void
21200db7afdSDavid E. O'Brien     __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n,
21300db7afdSDavid E. O'Brien 			      _Array<_Tp> __a)
21400db7afdSDavid E. O'Brien     {
21500db7afdSDavid E. O'Brien       _Tp* __p (__a._M_data);
216*ffeaf689SAlexander Kabaev       for (size_t __i = 0; __i < __n; ++__i, ++__p)
217*ffeaf689SAlexander Kabaev 	new (__p) _Tp(__e[__i]);
21800db7afdSDavid E. O'Brien     }
21900db7afdSDavid E. O'Brien 
22000db7afdSDavid E. O'Brien 
221*ffeaf689SAlexander Kabaev   template<typename _Tp>
22200db7afdSDavid E. O'Brien     void
22300db7afdSDavid E. O'Brien     __valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m,
22400db7afdSDavid E. O'Brien 			      _Array<_Tp> __b, size_t __n)
22500db7afdSDavid E. O'Brien     {
22600db7afdSDavid E. O'Brien       _Tp* __p (__a._M_data);
22700db7afdSDavid E. O'Brien       bool* __ok (__m._M_data);
228*ffeaf689SAlexander Kabaev       for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p)
229*ffeaf689SAlexander Kabaev 	{
230*ffeaf689SAlexander Kabaev 	  while (! *__ok)
231*ffeaf689SAlexander Kabaev 	    {
23200db7afdSDavid E. O'Brien 	      ++__ok;
23300db7afdSDavid E. O'Brien 	      ++__p;
23400db7afdSDavid E. O'Brien 	    }
23500db7afdSDavid E. O'Brien 	  new (__q) _Tp(*__p);
23600db7afdSDavid E. O'Brien 	}
23700db7afdSDavid E. O'Brien     }
238*ffeaf689SAlexander Kabaev } // namespace std
23900db7afdSDavid E. O'Brien 
240*ffeaf689SAlexander Kabaev #endif /* _VALARRAY_ARRAY_TCC */
241