// The template and inlines for the -*- C++ -*- internal _Array helper class.

// Copyright (C) 1997, 1998, 1999, 2003, 2005, 2009, 2010
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/valarray_array.tcc
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{valarray}
 */

// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>

#ifndef _VALARRAY_ARRAY_TCC
#define _VALARRAY_ARRAY_TCC 1

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Tp>
    void
    __valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m,
		    const _Tp& __t)
    {
      _Tp* __p = __a._M_data;
      bool* __ok (__m._M_data);
      for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p)
	{
	  while (!*__ok)
	  {
	    ++__ok;
	    ++__p;
	  }
	  *__p = __t;
	}
    }

  // Copy n elements of a into consecutive elements of b.  When m is
  // false, the corresponding element of a is skipped.  m must contain
  // at least n true elements.  a must contain at least n elements and
  // enough elements to match up with m through the nth true element
  // of m.  I.e.  if n is 10, m has 15 elements with 5 false followed
  // by 10 true, a must have 15 elements.
  template<typename _Tp>
    void
    __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b,
		    size_t __n)
    {
      _Tp* __p (__a._M_data);
      bool* __ok (__m._M_data);
      for (_Tp* __q = __b._M_data; __q < __b._M_data + __n;
	   ++__q, ++__ok, ++__p)
	{
	  while (! *__ok)
	    {
	      ++__ok;
	      ++__p;
	    }
	  *__q = *__p;
	}
    }

  // Copy n consecutive elements from a into elements of b.  Elements
  // of b are skipped if the corresponding element of m is false.  m
  // must contain at least n true elements.  b must have at least as
  // many elements as the index of the nth true element of m.  I.e. if
  // m has 15 elements with 5 false followed by 10 true, b must have
  // at least 15 elements.
  template<typename _Tp>
    void
    __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b,
		    _Array<bool> __m)
    {
      _Tp* __q (__b._M_data);
      bool* __ok (__m._M_data);
      for (_Tp* __p = __a._M_data; __p < __a._M_data+__n;
	   ++__p, ++__ok, ++__q)
	{
	  while (! *__ok)
	    {
	      ++__ok;
	      ++__q;
	    }
	  *__q = *__p;
	}
    }

  // Copy n elements from a into elements of b.  Elements of a are
  // skipped if the corresponding element of m is false.  Elements of
  // b are skipped if the corresponding element of k is false.  m and
  // k must contain at least n true elements.  a and b must have at
  // least as many elements as the index of the nth true element of m.
  template<typename _Tp>
    void
    __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n,
		    _Array<_Tp> __b, _Array<bool> __k)
    {
      _Tp* __p (__a._M_data);
      _Tp* __q (__b._M_data);
      bool* __srcok (__m._M_data);
      bool* __dstok (__k._M_data);
      for (size_t __i = 0; __i < __n;
	   ++__srcok, ++__p, ++__dstok, ++__q, ++__i)
	{
	  while (! *__srcok)
	    {
	      ++__srcok;
	      ++__p;
	    }
	  while (! *__dstok) 
	    {
	      ++__dstok;
	      ++__q;
	    }
	  *__q = *__p;
	}
    }

  // Copy n consecutive elements of e into consecutive elements of a.
  // I.e. a[i] = e[i].
  template<typename _Tp, class _Dom>
    void
    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a)
    {
      _Tp* __p (__a._M_data);
      for (size_t __i = 0; __i < __n; ++__i, ++__p)
	*__p = __e[__i];
    }

  // Copy n consecutive elements of e into elements of a using stride
  // s.  I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2].
  template<typename _Tp, class _Dom>
    void
    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
		     _Array<_Tp> __a, size_t __s)
    {
      _Tp* __p (__a._M_data);
      for (size_t __i = 0; __i < __n; ++__i, __p += __s)
	*__p = __e[__i];
    }

  // Copy n consecutive elements of e into elements of a indexed by
  // contents of i.  I.e., a[i[0]] = e[0].
  template<typename _Tp, class _Dom>
    void
    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
		    _Array<_Tp> __a, _Array<size_t> __i)
    {
      size_t* __j (__i._M_data);
      for (size_t __k = 0; __k < __n; ++__k, ++__j)
	__a._M_data[*__j] = __e[__k];
    }

  // Copy n elements of e indexed by contents of f into elements of a
  // indexed by contents of i.  I.e., a[i[0]] = e[f[0]].
  template<typename _Tp>
    void
    __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f,
		    size_t __n, 
		    _Array<_Tp> __a, _Array<size_t> __i)
    {
      size_t* __g (__f._M_data);
      size_t* __j (__i._M_data);
      for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) 
	__a._M_data[*__j] = __e._M_data[*__g];
    }

  // Copy n consecutive elements of e into elements of a.  Elements of
  // a are skipped if the corresponding element of m is false.  m must
  // have at least n true elements and a must have at least as many
  // elements as the index of the nth true element of m.  I.e. if m
  // has 5 false followed by 10 true elements and n == 10, a must have
  // at least 15 elements.
  template<typename _Tp, class _Dom>
    void
    __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n,
		    _Array<_Tp> __a, _Array<bool> __m)
    {
      bool* __ok (__m._M_data);
      _Tp* __p (__a._M_data);
      for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p)
	{
	  while (! *__ok)
	    {
	      ++__ok;
	      ++__p;
	    }
	  *__p = __e[__i];
	}
    }


  template<typename _Tp, class _Dom>
    void
    __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n,
			      _Array<_Tp> __a)
    {
      _Tp* __p (__a._M_data);
      for (size_t __i = 0; __i < __n; ++__i, ++__p)
	new (__p) _Tp(__e[__i]);
    }


  template<typename _Tp>
    void
    __valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m,
			      _Array<_Tp> __b, size_t __n)
    {
      _Tp* __p (__a._M_data);
      bool* __ok (__m._M_data);
      for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p)
	{
	  while (! *__ok)
	    {
	      ++__ok;
	      ++__p;
	    }
	  new (__q) _Tp(*__p);
	}
    }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif /* _VALARRAY_ARRAY_TCC */
