197403Sobrien// The template and inlines for the -*- C++ -*- internal _Array helper class.
297403Sobrien
3169691Skan// Copyright (C) 1997, 1998, 1999, 2003, 2005 Free Software Foundation, Inc.
497403Sobrien//
597403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
697403Sobrien// software; you can redistribute it and/or modify it under the
797403Sobrien// terms of the GNU General Public License as published by the
897403Sobrien// Free Software Foundation; either version 2, or (at your option)
997403Sobrien// any later version.
1097403Sobrien
1197403Sobrien// This library is distributed in the hope that it will be useful,
1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1497403Sobrien// GNU General Public License for more details.
1597403Sobrien
1697403Sobrien// You should have received a copy of the GNU General Public License along
1797403Sobrien// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1997403Sobrien// USA.
2097403Sobrien
2197403Sobrien// As a special exception, you may use this file as part of a free software
2297403Sobrien// library without restriction.  Specifically, if other files instantiate
2397403Sobrien// templates or use macros or inline functions from this file, or you compile
2497403Sobrien// this file and link it with other files to produce an executable, this
2597403Sobrien// file does not by itself cause the resulting executable to be covered by
2697403Sobrien// the GNU General Public License.  This exception does not however
2797403Sobrien// invalidate any other reasons why the executable file might be covered by
2897403Sobrien// the GNU General Public License.
2997403Sobrien
30169691Skan/** @file valarray_array.tcc
31169691Skan *  This is an internal header file, included by other library headers.
32169691Skan *  You should not attempt to use it directly.
33169691Skan */
34169691Skan
3597403Sobrien// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
3697403Sobrien
37132720Skan#ifndef _VALARRAY_ARRAY_TCC
38132720Skan#define _VALARRAY_ARRAY_TCC 1
3997403Sobrien
40169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
41169691Skan
42132720Skan  template<typename _Tp>
43132720Skan    void
44132720Skan    __valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m,
45132720Skan		    const _Tp& __t)
46132720Skan    {
47132720Skan      _Tp* __p = __a._M_data;
48132720Skan      bool* __ok (__m._M_data);
49132720Skan      for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p)
50132720Skan	{
51132720Skan	  while (!*__ok)
52132720Skan	  {
53132720Skan	    ++__ok;
54132720Skan	    ++__p;
55132720Skan	  }
56132720Skan	  *__p = __t;
57132720Skan	}
58132720Skan    }
5997403Sobrien
60132720Skan  // Copy n elements of a into consecutive elements of b.  When m is
61132720Skan  // false, the corresponding element of a is skipped.  m must contain
62132720Skan  // at least n true elements.  a must contain at least n elements and
63132720Skan  // enough elements to match up with m through the nth true element
64132720Skan  // of m.  I.e.  if n is 10, m has 15 elements with 5 false followed
65132720Skan  // by 10 true, a must have 15 elements.
66132720Skan  template<typename _Tp>
67132720Skan    void
68132720Skan    __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b,
69132720Skan		    size_t __n)
70132720Skan    {
71132720Skan      _Tp* __p (__a._M_data);
72132720Skan      bool* __ok (__m._M_data);
73132720Skan      for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;
74132720Skan	   ++__q, ++__ok, ++__p)
75132720Skan	{
76132720Skan	  while (! *__ok)
77132720Skan	    {
78132720Skan	      ++__ok;
79132720Skan	      ++__p;
80132720Skan	    }
81132720Skan	  *__q = *__p;
82132720Skan	}
8397403Sobrien    }
8497403Sobrien
85132720Skan  // Copy n consecutive elements from a into elements of b.  Elements
86132720Skan  // of b are skipped if the corresponding element of m is false.  m
87132720Skan  // must contain at least n true elements.  b must have at least as
88132720Skan  // many elements as the index of the nth true element of m.  I.e. if
89132720Skan  // m has 15 elements with 5 false followed by 10 true, b must have
90132720Skan  // at least 15 elements.
91132720Skan  template<typename _Tp>
92132720Skan    void
93132720Skan    __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
94132720Skan		    _Array<bool> __m)
95132720Skan    {
96132720Skan      _Tp* __q (__b._M_data);
97132720Skan      bool* __ok (__m._M_data);
98132720Skan      for (_Tp* __p = __a._M_data; __p < __a._M_data+__n;
99132720Skan	   ++__p, ++__ok, ++__q)
100132720Skan	{
101132720Skan	  while (! *__ok)
102132720Skan	    {
103132720Skan	      ++__ok;
104132720Skan	      ++__q;
105132720Skan	    }
106132720Skan	  *__q = *__p;
107132720Skan	}
10897403Sobrien    }
10997403Sobrien
110132720Skan  // Copy n elements from a into elements of b.  Elements of a are
111132720Skan  // skipped if the corresponding element of m is false.  Elements of
112132720Skan  // b are skipped if the corresponding element of k is false.  m and
113132720Skan  // k must contain at least n true elements.  a and b must have at
114132720Skan  // least as many elements as the index of the nth true element of m.
115132720Skan  template<typename _Tp>
116132720Skan    void
117132720Skan    __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n,
118132720Skan		    _Array<_Tp> __b, _Array<bool> __k)
119132720Skan    {
120132720Skan      _Tp* __p (__a._M_data);
121132720Skan      _Tp* __q (__b._M_data);
122132720Skan      bool* __srcok (__m._M_data);
123132720Skan      bool* __dstok (__k._M_data);
124132720Skan      for (size_t __i = 0; __i < __n;
125132720Skan	   ++__srcok, ++__p, ++__dstok, ++__q, ++__i)
126132720Skan	{
127132720Skan	  while (! *__srcok)
128132720Skan	    {
129132720Skan	      ++__srcok;
130132720Skan	      ++__p;
131132720Skan	    }
132132720Skan	  while (! *__dstok) 
133132720Skan	    {
134132720Skan	      ++__dstok;
135132720Skan	      ++__q;
136132720Skan	    }
137132720Skan	  *__q = *__p;
138132720Skan	}
13997403Sobrien    }
14097403Sobrien
141132720Skan  // Copy n consecutive elements of e into consecutive elements of a.
142132720Skan  // I.e. a[i] = e[i].
143132720Skan  template<typename _Tp, class _Dom>
144132720Skan    void
145132720Skan    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a)
146132720Skan    {
147132720Skan      _Tp* __p (__a._M_data);
148132720Skan      for (size_t __i = 0; __i < __n; ++__i, ++__p)
149132720Skan	*__p = __e[__i];
150132720Skan    }
15197403Sobrien
152132720Skan  // Copy n consecutive elements of e into elements of a using stride
153132720Skan  // s.  I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2].
154132720Skan  template<typename _Tp, class _Dom>
155132720Skan    void
156132720Skan    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
157132720Skan		     _Array<_Tp> __a, size_t __s)
158132720Skan    {
159132720Skan      _Tp* __p (__a._M_data);
160132720Skan      for (size_t __i = 0; __i < __n; ++__i, __p += __s)
161132720Skan	*__p = __e[__i];
162132720Skan    }
16397403Sobrien
164132720Skan  // Copy n consecutive elements of e into elements of a indexed by
165132720Skan  // contents of i.  I.e., a[i[0]] = e[0].
166132720Skan  template<typename _Tp, class _Dom>
167132720Skan    void
168132720Skan    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
169132720Skan		    _Array<_Tp> __a, _Array<size_t> __i)
170132720Skan    {
171132720Skan      size_t* __j (__i._M_data);
172132720Skan      for (size_t __k = 0; __k < __n; ++__k, ++__j)
173132720Skan	__a._M_data[*__j] = __e[__k];
174132720Skan    }
17597403Sobrien
176132720Skan  // Copy n elements of e indexed by contents of f into elements of a
177132720Skan  // indexed by contents of i.  I.e., a[i[0]] = e[f[0]].
178132720Skan  template<typename _Tp>
179132720Skan    void
180132720Skan    __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f,
181132720Skan		    size_t __n, 
182132720Skan		    _Array<_Tp> __a, _Array<size_t> __i)
183132720Skan    {
184132720Skan      size_t* __g (__f._M_data);
185132720Skan      size_t* __j (__i._M_data);
186132720Skan      for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) 
187132720Skan	__a._M_data[*__j] = __e._M_data[*__g];
18897403Sobrien    }
18997403Sobrien
190132720Skan  // Copy n consecutive elements of e into elements of a.  Elements of
191132720Skan  // a are skipped if the corresponding element of m is false.  m must
192132720Skan  // have at least n true elements and a must have at least as many
193132720Skan  // elements as the index of the nth true element of m.  I.e. if m
194132720Skan  // has 5 false followed by 10 true elements and n == 10, a must have
195132720Skan  // at least 15 elements.
196132720Skan  template<typename _Tp, class _Dom>
197132720Skan    void
198132720Skan    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
199132720Skan		    _Array<_Tp> __a, _Array<bool> __m)
200132720Skan    {
201132720Skan      bool* __ok (__m._M_data);
202132720Skan      _Tp* __p (__a._M_data);
203132720Skan      for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
204132720Skan	{
205132720Skan	  while (! *__ok)
206132720Skan	    {
207132720Skan	      ++__ok;
208132720Skan	      ++__p;
209132720Skan	    }
210132720Skan	  *__p = __e[__i];
211132720Skan	}
212132720Skan    }
21397403Sobrien
21497403Sobrien
215132720Skan  template<typename _Tp, class _Dom>
216132720Skan    void
217132720Skan    __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n,
218132720Skan			      _Array<_Tp> __a)
219132720Skan    {
220132720Skan      _Tp* __p (__a._M_data);
221132720Skan      for (size_t __i = 0; __i < __n; ++__i, ++__p)
222132720Skan	new (__p) _Tp(__e[__i]);
22397403Sobrien    }
22497403Sobrien
22597403Sobrien
226132720Skan  template<typename _Tp>
227132720Skan    void
228132720Skan    __valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m,
229132720Skan			      _Array<_Tp> __b, size_t __n)
230132720Skan    {
231132720Skan      _Tp* __p (__a._M_data);
232132720Skan      bool* __ok (__m._M_data);
233132720Skan      for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p)
234132720Skan	{
235132720Skan	  while (! *__ok)
236132720Skan	    {
237132720Skan	      ++__ok;
238132720Skan	      ++__p;
239132720Skan	    }
240132720Skan	  new (__q) _Tp(*__p);
241132720Skan	}
242132720Skan    }
24397403Sobrien
244169691Skan_GLIBCXX_END_NAMESPACE
245169691Skan
246132720Skan#endif /* _VALARRAY_ARRAY_TCC */
247