26 - Numerics library [lib.numerics]

-1- This clause describes components that C++ programs may use to perform seminumerical operations.

-2- The following subclauses describe components for complex number types, numeric ( n-at-a-time) arrays, generalized numeric algorithms, and facilities included from the ISO C library, as summarized in Table ??:

Numerics library summary
SubclauseHeader(s)
lib.numeric.requirements Requirements
lib.complex.numbers Complex numbers<complex>
lib.numarray Numeric arrays<valarray>
lib.numeric.ops Generalized numeric operations<numeric>
lib.c.math C library<cmath>
 <cstdlib>

26.1 - Numeric type requirements [lib.numeric.requirements]

-1- The complex and valarray components are parameterized by the type of information they contain and manipulate. A C++ program shall instantiate these components only with a type T that satisfies the following requirements:*

[Footnote: In other words, value types. These include built-in arithmetic types, pointers, the library class complex, and instantiations of valarray for value types. --- end foonote]

-2- If any operation on T throws an exception the effects are undefined.

-3- In addition, many member and related functions of valarray<T> can be successfully instantiated and will exhibit well-defined behavior if and only if T satisfies additional requirements specified for each such member or related function.

-4- [Example: It is valid to instantiate valarray<complex>, but operator>() will not be successfully instantiated for valarray<complex> operands, since complex does not have any ordering operators.
--- end example]

26.2 - Complex numbers [lib.complex.numbers]

-1- The header <complex> defines a template class, and numerous functions for representing and manipulating complex numbers.

-2- The effect of instantiating the template complex for any type other than float, double or long double is unspecified.

-3- If the result of a function is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

26.2.1 - Header <complex> synopsis [lib.complex.synopsis]

namespace std {
  template<class T> class complex;
  template<> class complex<float>;
  template<> class complex<double>;
  template<> class complex<long double>;
  //  lib.complex.ops operators:
  template<class T>
    complex<T> operator+(const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator+(const complex<T>&, const T&);
  template<class T> complex<T> operator+(const T&, const complex<T>&);
  template<class T> complex<T> operator-
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&, const T&);
  template<class T> complex<T> operator-(const T&, const complex<T>&);
  template<class T> complex<T> operator*
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator*(const complex<T>&, const T&);
  template<class T> complex<T> operator*(const T&, const complex<T>&);
  template<class T> complex<T> operator/
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator/(const complex<T>&, const T&);
  template<class T> complex<T> operator/(const T&, const complex<T>&);
  template<class T> complex<T> operator+(const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&);
  template<class T> bool operator==
    (const complex<T>&, const complex<T>&);
  template<class T> bool operator==(const complex<T>&, const T&);
  template<class T> bool operator==(const T&, const complex<T>&);
  template<class T> bool operator!=(const complex<T>&, const complex<T>&);
  template<class T> bool operator!=(const complex<T>&, const T&);
  template<class T> bool operator!=(const T&, const complex<T>&);
  template<class T, class charT, class traits>
  basic_istream<charT, traits>&
  operator>>(basic_istream<charT, traits>&, complex<T>&);

  template<class T, class charT, class traits>
  basic_ostream<charT, traits>&
  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
  //  lib.complex.value.ops values:
  template<class T> T real(const complex<T>&);
  template<class T> T imag(const complex<T>&);
  template<class T> T abs(const complex<T>&);
  template<class T> T arg(const complex<T>&);
  template<class T> T norm(const complex<T>&);
  template<class T> complex<T> conj(const complex<T>&);
  template<class T> complex<T> polar(const T&, const T&);
  //  lib.complex.transcendentals transcendentals:
  template<class T> complex<T> cos  (const complex<T>&);
  template<class T> complex<T> cosh (const complex<T>&);
  template<class T> complex<T> exp  (const complex<T>&);
  template<class T> complex<T> log  (const complex<T>&);
  template<class T> complex<T> log10(const complex<T>&);
  template<class T> complex<T> pow(const complex<T>&, int);
  template<class T> complex<T> pow(const complex<T>&, const T&);
  template<class T> complex<T> pow(const complex<T>&, const complex<T>&);
  template<class T> complex<T> pow(const T&, const complex<T>&);
  template<class T> complex<T> sin  (const complex<T>&);
  template<class T> complex<T> sinh (const complex<T>&);
  template<class T> complex<T> sqrt (const complex<T>&);
  template<class T> complex<T> tan  (const complex<T>&);
  template<class T> complex<T> tanh (const complex<T>&);
}

26.2.2 - Template class complex [lib.complex]

namespace std {
  template<class T>
  class complex {
  public:
    typedef T value_type;

    complex(const T& re = T(), const T& im = T());
    complex(const complex&);
    template<class X> complex(const complex<X>&);
    T real() const;
    T imag() const;

    complex<T>& operator= (const T&);
    complex<T>& operator+=(const T&);
    complex<T>& operator-=(const T&);
    complex<T>& operator*=(const T&);
    complex<T>& operator/=(const T&);

    complex& operator=(const complex&);
    template<class X> complex<T>& operator= (const complex<X>&);
    template<class X> complex<T>& operator+=(const complex<X>&);
    template<class X> complex<T>& operator-=(const complex<X>&);
    template<class X> complex<T>& operator*=(const complex<X>&);
    template<class X> complex<T>& operator/=(const complex<X>&);
  };

  template<class T> complex<T> operator+
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator+(const complex<T>&, const T&);
  template<class T> complex<T> operator+(const T&, const complex<T>&);

  template<class T> complex<T> operator-
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&, const T&);
  template<class T> complex<T> operator-(const T&, const complex<T>&);

  template<class T> complex<T> operator*
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator*(const complex<T>&, const T&);
  template<class T> complex<T> operator*(const T&, const complex<T>&);

  template<class T> complex<T> operator/
    (const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator/(const complex<T>&, const T&);
  template<class T> complex<T> operator/(const T&, const complex<T>&);

  template<class T> complex<T> operator+(const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&);

  template<class T> bool operator==(const complex<T>&, const complex<T>&);
  template<class T> bool operator==(const complex<T>&, const T&);
  template<class T> bool operator==(const T&, const complex<T>&);

  template<class T> bool operator!=(const complex<T>&, const complex<T>&);
  template<class T> bool operator!=(const complex<T>&, const T&);
  template<class T> bool operator!=(const T&, const complex<T>&);

  template<class T, class charT, class traits>
  basic_istream<charT, traits>&
  operator>>(basic_istream<charT, traits>&, complex<T>&);

  template<class T, class charT, class traits>
  basic_ostream<charT, traits>&
  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
};

-1- The class complex describes an object that can store the Cartesian components, real() and imag(), of a complex number.

26.2.3 - complex specializations [lib.complex.special]

  template<> class complex<float> {
  public:
    typedef float value_type;

    complex(float re = 0.0f, float im = 0.0f);
    explicit complex(const complex<double>&);
    explicit complex(const complex<long double>&);
    float real() const;
    float imag() const;

    complex<float>& operator= (float);
    complex<float>& operator+=(float);
    complex<float>& operator-=(float);
    complex<float>& operator*=(float);
    complex<float>& operator/=(float);

    complex<float>& operator=(const complex<float>&);
    template<class X> complex<float>& operator= (const complex<X>&);
    template<class X> complex<float>& operator+=(const complex<X>&);
    template<class X> complex<float>& operator-=(const complex<X>&);
    template<class X> complex<float>& operator*=(const complex<X>&);
    template<class X> complex<float>& operator/=(const complex<X>&);
  };
  template<> class complex<double> {
  public:
    typedef double value_type;

    complex(double re = 0.0, double im = 0.0);
    complex(const complex<float>&);
    explicit complex(const complex<long double>&);
    double real() const;
    double imag() const;

    complex<double>& operator= (double);
    complex<double>& operator+=(double);
    complex<double>& operator-=(double);
    complex<double>& operator*=(double);
    complex<double>& operator/=(double);

    complex<double>& operator=(const complex<double>&);
    template<class X> complex<double>& operator= (const complex<X>&);
    template<class X> complex<double>& operator+=(const complex<X>&);
    template<class X> complex<double>& operator-=(const complex<X>&);
    template<class X> complex<double>& operator*=(const complex<X>&);
    template<class X> complex<double>& operator/=(const complex<X>&);
  };
  template<> class complex<long double> {
  public:
    typedef long double value_type;

    complex(long double re = 0.0L, long double im = 0.0L);
    complex(const complex<float>&);
    complex(const complex<double>&);
    long double real() const;
    long double imag() const;

    complex<long double>& operator=(const complex<long double>&);
    complex<long double>& operator= (long double);
    complex<long double>& operator+=(long double);
    complex<long double>& operator-=(long double);
    complex<long double>& operator*=(long double);
    complex<long double>& operator/=(long double);

    template<class X> complex<long double>& operator= (const complex<X>&);
    template<class X> complex<long double>& operator+=(const complex<X>&);
    template<class X> complex<long double>& operator-=(const complex<X>&);
    template<class X> complex<long double>& operator*=(const complex<X>&);
    template<class X> complex<long double>& operator/=(const complex<X>&);
  };

26.2.4 - complex member functions [lib.complex.members]

template<class T> complex(const T& re = T(), const T& im = T());

-1- Effects: Constructs an object of class complex.

-2- Postcondition: real() == re && imag() == im.

26.2.5 - complex member operators [lib.complex.member.ops]

template <class T> complex<T>& operator+=(const T& rhs);

-1- Effects: Adds the scalar value rhs to the real part of the complex value *this and stores the result in the real part of *this, leaving the imaginary part unchanged.

-2- Returns: *this.

template <class T> complex<T>& operator-=(const T& rhs);

-3- Effects: Subtracts the scalar value rhs from the real part of the complex value *this and stores the result in the real part of *this, leaving the imaginary part unchanged.

-4- Returns: *this.

template <class T> complex<T>& operator*=(const T& rhs);

-5- Effects: Multiplies the scalar value rhs by the complex value *this and stores the result in *this.

-6- Returns: *this.

template <class T> complex<T>& operator/=(const T& rhs);

-7- Effects: Divides the scalar value rhs into the complex value *this and stores the result in *this.

-8- Returns: *this.

template<class T> complex<T>& operator+=(const complex<T>& rhs);

-9- Effects: Adds the complex value rhs to the complex value *this and stores the sum in *this.

-10- Returns: *this.

template<class T> complex<T>& operator-=(const complex<T>& rhs);

-11- Effects: Subtracts the complex value rhs from the complex value *this and stores the difference in *this.

-12- Returns: *this.

template<class T> complex<T>& operator*=(const complex<T>& rhs);

-13- Effects: Multiplies the complex value rhs by the complex value *this and stores the product in *this.

-14- Returns: *this.

template<class T> complex<T>& operator/=(const complex<T>& rhs);

-15- Effects: Divides the complex value rhs into the complex value *this and stores the quotient in *this.

-16- Returns: *this.

26.2.6 - complex non-member operations [lib.complex.ops]

template<class T> complex<T> operator+(const complex<T>& lhs);

-1- Notes: unary operator.

-2- Returns: complex<T>(lhs).

template<class T>
  complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs);
template<class T> complex<T> operator+(const complex<T>& lhs, const T& rhs);
template<class T> complex<T> operator+(const T& lhs, const complex<T>& rhs);

-3- Returns: complex<T>(lhs) += rhs.

template<class T> complex<T> operator-(const complex<T>& lhs);

-4- Notes: unary operator.

-5- Returns: complex<T>(-lhs.real(),-lhs.imag()).

template<class T>
  complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs);
template<class T> complex<T> operator-(const complex<T>& lhs, const T& rhs);
template<class T> complex<T> operator-(const T& lhs, const complex<T>& rhs);

-6- Returns: complex<T>(lhs) -= rhs.

template<class T>
  complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs);
template<class T> complex<T> operator*(const complex<T>& lhs, const T& rhs);
template<class T> complex<T> operator*(const T& lhs, const complex<T>& rhs);

-7- Returns: complex<T>(lhs) *= rhs.

template<class T>
  complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs);
template<class T> complex<T> operator/(const complex<T>& lhs, const T& rhs);
template<class T> complex<T> operator/(const T& lhs, const complex<T>& rhs);

-8- Returns: complex<T>(lhs) /= rhs.

template<class T>
  bool operator==(const complex<T>& lhs, const complex<T>& rhs);
template<class T> bool operator==(const complex<T>& lhs, const T& rhs);
template<class T> bool operator==(const T& lhs, const complex<T>& rhs);

-9- Returns: lhs.real() == rhs.real() && lhs.imag() == rhs.imag().

-10- Notes: The imaginary part is assumed to be T(), or 0.0, for the T arguments.

template<class T>
  bool operator!=(const complex<T>& lhs, const complex<T>& rhs);
template<class T> bool operator!=(const complex<T>& lhs, const T& rhs);
template<class T> bool operator!=(const T& lhs, const complex<T>& rhs);

-11- Returns: rhs.real() != lhs.real() || rhs.imag() != lhs.imag().

template<class T, class charT, class traits>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>&  is, complex<T>&  x);

-12- Effects: Extracts a complex number x of the form: u, (u), or (u,v), where u is the real part and v is the imaginary part (lib.istream.formatted).

-13- Requires: The input values be convertible to T.
If bad input is encountered, calls is.setstate(ios::failbit) (which may throw ios::failure (lib.iostate.flags).

-14- Returns: is .

template<class T, class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&  o, const complex<T>&  x);

-15- Effects: inserts the complex number x onto the stream o as if it were implemented as follows:

template<class T, class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& o, const complex<T>& x)
{
	basic_ostringstream<charT, traits> s;
	s.flags(o.flags());
	s.imbue(o.getloc());
	s.precision(o.precision());
	s << '(' << x.real() << "," << x.imag() << ')';
	return o << s.str();
}

26.2.7 - complex value operations [lib.complex.value.ops]

template<class T> T real(const complex<T>& x);

-1- Returns: x .real().

template<class T> T imag(const complex<T>& x);

-2- Returns: x .imag().

template<class T> T abs(const complex<T>& x);

-3- Returns: the magnitude of x .

template<class T> T arg(const complex<T>& x);

-4- Returns: the phase angle of x , or atan2(imag(x), real(x)) .

template<class T> T norm(const complex<T>& x);

-5- Returns: the squared magnitude of x .

template<class T> complex<T> conj(const complex<T>& x);

-6- Returns: the complex conjugate of x .

template<class T> complex<T> polar(const T& rho, const T& theta = 0);

-7- Returns: the complex value corresponding to a complex number whose magnitude is rho and whose phase angle is theta .

26.2.8 - complex transcendentals [lib.complex.transcendentals]

template<class T> complex<T> cos(const complex<T>& x);

-1- Returns: the complex cosine of x.

template<class T> complex<T> cosh(const complex<T>& x);

-2- Returns: the complex hyperbolic cosine of x.

template<class T> complex<T> exp(const complex<T>& x);

-3- Returns: the complex base e exponential of x.

template<class T> complex<T> log(const complex<T>& x);

-4- Notes: the branch cuts are along the negative real axis.

-5- Returns: the complex natural (base e) logarithm of x, in the range of a strip mathematically unbounded along the real axis and in the interval [-i times pi, i times pi ] along the imaginary axis. When x is a negative real number, imag(log(x)) is pi.

template<class T> complex<T> log10(const complex<T>& x);

-6- Notes: the branch cuts are along the negative real axis.

-7- Returns: the complex common (base 10)logarithm of x, defined as log(x)/log(10).

template<class T> complex<T> pow(const complex<T>& x, int y);
template<class T>
  complex<T> pow(const complex<T>& x, const complex<T>& y);
template<class T> complex<T> pow  (const complex<T>& x, const T& y);
template<class T> complex<T> pow  (const T& x, const complex<T>& y);

-8- Notes: the branch cuts are along the negative real axis.

-9- Returns: the complex power of base x raised to the y-th power, defined as exp(y*log(x)). The value returned for pow(0,0) is implementation-defined.

template<class T> complex<T> sin  (const complex<T>& x);

-10- Returns: the complex sine of x.

template<class T> complex<T> sinh (const complex<T>& x);

-11- Returns: the complex hyperbolic sine of x.

template<class T> complex<T> sqrt (const complex<T>& x);

-12- Notes: the branch cuts are along the negative real axis.

-13- Returns: the complex square root of x, in the range of the right half-plane. If the argument is a negative real number, the value returned lies on the positive imaginary axis.

template<class T> complex<T> tan  (const complex<T>& x);

-14- Returns: the complex tangent of x.

template<class T> complex<T> tanh (const complex<T>& x);

-15- Returns: the complex hyperbolic tangent of x.

26.3 - Numeric arrays [lib.numarray]

26.3.1 - Header <valarray> synopsis [lib.valarray.synopsis]

namespace std {
  template<class T> class valarray;         //  An array of type  T
  class slice;                              //  a BLAS-like slice out of an array
  template<class T> class slice_array;
  class gslice;                             //  a generalized slice out of an array
  template<class T> class gslice_array;
  template<class T> class mask_array;       //  a masked array
  template<class T> class indirect_array;   //  an indirected array
  template<class T> valarray<T> operator*
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator* (const valarray<T>&, const T&);
  template<class T> valarray<T> operator* (const T&, const valarray<T>&);
  template<class T> valarray<T> operator/
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator/ (const valarray<T>&, const T&);
  template<class T> valarray<T> operator/ (const T&, const valarray<T>&);
  template<class T> valarray<T> operator%
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator% (const valarray<T>&, const T&);
  template<class T> valarray<T> operator% (const T&, const valarray<T>&);
  template<class T> valarray<T> operator+
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator+ (const valarray<T>&, const T&);
  template<class T> valarray<T> operator+ (const T&, const valarray<T>&);
  template<class T> valarray<T> operator-
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator- (const valarray<T>&, const T&);
  template<class T> valarray<T> operator- (const T&, const valarray<T>&);
  template<class T> valarray<T> operator^
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator^ (const valarray<T>&, const T&);
  template<class T> valarray<T> operator^ (const T&, const valarray<T>&);
  template<class T> valarray<T> operator&
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator& (const valarray<T>&, const T&);
  template<class T> valarray<T> operator& (const T&, const valarray<T>&);
  template<class T> valarray<T> operator|
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator| (const valarray<T>&, const T&);
  template<class T> valarray<T> operator| (const T&, const valarray<T>&);
  template<class T> valarray<T> operator<<
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator<<(const valarray<T>&, const T&);
  template<class T> valarray<T> operator<<(const T&, const valarray<T>&);
  template<class T> valarray<T> operator>>
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> operator>>(const valarray<T>&, const T&);
  template<class T> valarray<T> operator>>(const T&, const valarray<T>&);
  template<class T> valarray<bool> operator&&
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator&&(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator&&(const T&, const valarray<T>&);
  template<class T> valarray<bool> operator||
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator||(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator||(const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator==(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator==(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator==(const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator!=(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator!=(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator!=(const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator< (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator< (const valarray<T>&, const T&);
  template<class T> valarray<bool> operator< (const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator> (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator> (const valarray<T>&, const T&);
  template<class T> valarray<bool> operator> (const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator<=(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator<=(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator<=(const T&, const valarray<T>&);
  template<class T>
    valarray<bool> operator>=(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<bool> operator>=(const valarray<T>&, const T&);
  template<class T> valarray<bool> operator>=(const T&, const valarray<T>&);
  template<class T> valarray<T> abs  (const valarray<T>&);
  template<class T> valarray<T> acos (const valarray<T>&);
  template<class T> valarray<T> asin (const valarray<T>&);
  template<class T> valarray<T> atan (const valarray<T>&);
  template<class T> valarray<T> atan2
    (const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> atan2(const valarray<T>&, const T&);
  template<class T> valarray<T> atan2(const T&, const valarray<T>&);
  template<class T> valarray<T> cos  (const valarray<T>&);
  template<class T> valarray<T> cosh (const valarray<T>&);
  template<class T> valarray<T> exp  (const valarray<T>&);
  template<class T> valarray<T> log  (const valarray<T>&);
  template<class T> valarray<T> log10(const valarray<T>&);
  template<class T> valarray<T> pow(const valarray<T>&, const valarray<T>&);
  template<class T> valarray<T> pow(const valarray<T>&, const T&);
  template<class T> valarray<T> pow(const T&, const valarray<T>&);
  template<class T> valarray<T> sin  (const valarray<T>&);
  template<class T> valarray<T> sinh (const valarray<T>&);
  template<class T> valarray<T> sqrt (const valarray<T>&);
  template<class T> valarray<T> tan  (const valarray<T>&);
  template<class T> valarray<T> tanh (const valarray<T>&);
}

-1- The header <valarray> defines five template classes ( valarray, slice_array, gslice_array, mask_array, and indirect_array), two classes ( slice and gslice), and a series of related function signatures for representing and manipulating arrays of values.

-2- The valarray array classes are defined to be free of certain forms of aliasing, thus allowing operations on these classes to be optimized.

-3- Any function returning a valarray<T> is permitted to return an object of another type, provided all the const member functions of valarray<T> are also applicable to this type. This return type shall not add more than two levels of template nesting over the most deeply nested argument type.*

[Footnote: Clause limits recommends a minimum number of recursively nested template instantiations. This requirement thus indirectly suggests a minimum allowable complexity for valarray expressions. --- end foonote]

-4- Implementations introducing such replacement types shall provide additional functions and operators as follows:

-5- In particular, an implementation shall allow a valarray<T> to be constructed from such replacement types and shall allow assignments and computed assignments of such types to valarray<T>, slice_array<T>, gslice_array<T>, mask_array<T> and indirect_array<T> objects.

-6- These library functions are permitted to throw a bad_alloc (lib.bad.alloc) exception if there are not sufficient resources available to carry out the operation. Note that the exception is not mandated.

26.3.2 - Template class valarray [lib.template.valarray]

namespace std {
  template<class T> class valarray {
  public:
    typedef T value_type;

    //  lib.valarray.cons construct/destroy:
    valarray();
    explicit valarray(size_t);
    valarray(const T&, size_t);
    valarray(const T*, size_t);
    valarray(const valarray&);
    valarray(const slice_array<T>&);
    valarray(const gslice_array<T>&);
    valarray(const mask_array<T>&);
    valarray(const indirect_array<T>&);
   ~valarray();
    //  lib.valarray.assign assignment:
    valarray<T>& operator=(const valarray<T>&);
    valarray<T>& operator=(const T&);
    valarray<T>& operator=(const slice_array<T>&);
    valarray<T>& operator=(const gslice_array<T>&);
    valarray<T>& operator=(const mask_array<T>&);
    valarray<T>& operator=(const indirect_array<T>&);
    //  lib.valarray.access element access:
    T                 operator[](size_t) const;
    T&                operator[](size_t);
    //  lib.valarray.sub subset operations:
    valarray<T>       operator[](slice) const;
    slice_array<T>    operator[](slice);
    valarray<T>       operator[](const gslice&) const;
    gslice_array<T>   operator[](const gslice&);
    valarray<T>       operator[](const valarray<bool>&) const;
    mask_array<T>     operator[](const valarray<bool>&);
    valarray<T>       operator[](const valarray<size_t>&) const;
    indirect_array<T> operator[](const valarray<size_t>&);
    //  lib.valarray.unary unary operators:
    valarray<T> operator+() const;
    valarray<T> operator-() const;
    valarray<T> operator~() const;
    valarray<T> operator!() const;
    //  lib.valarray.cassign computed assignment:
    valarray<T>& operator*= (const T&);
    valarray<T>& operator/= (const T&);
    valarray<T>& operator%= (const T&);
    valarray<T>& operator+= (const T&);
    valarray<T>& operator-= (const T&);
    valarray<T>& operator^= (const T&);
    valarray<T>& operator&= (const T&);
    valarray<T>& operator|= (const T&);
    valarray<T>& operator<<=(const T&);
    valarray<T>& operator>>=(const T&);
    valarray<T>& operator*= (const valarray<T>&);
    valarray<T>& operator/= (const valarray<T>&);
    valarray<T>& operator%= (const valarray<T>&);
    valarray<T>& operator+= (const valarray<T>&);
    valarray<T>& operator-= (const valarray<T>&);
    valarray<T>& operator^= (const valarray<T>&);
    valarray<T>& operator|= (const valarray<T>&);
    valarray<T>& operator&= (const valarray<T>&);
    valarray<T>& operator<<=(const valarray<T>&);
    valarray<T>& operator>>=(const valarray<T>&);
    //  lib.valarray.members member functions:
    size_t size() const;
    T    sum() const;
    T    min() const;
    T    max() const;
    valarray<T> shift (int) const;
    valarray<T> cshift(int) const;
    valarray<T> apply(T func(T)) const;
    valarray<T> apply(T func(const T&)) const;
    void resize(size_t sz, T c = T());
  };
}

-1- The template class valarray<T> is a one-dimensional smart array, with elements numbered sequentially from zero. It is a representation of the mathematical concept of an ordered set of values. The illusion of higher dimensionality may be produced by the familiar idiom of computed indices, together with the powerful subsetting capabilities provided by the generalized subscript operators.*

[Footnote: The intent is to specify an array template that has the minimum functionality necessary to address aliasing ambiguities and the proliferation of temporaries. Thus, the valarray template is neither a matrix class nor a field class. However, it is a very useful building block for designing such classes. --- end foonote]

-2- An implementation is permitted to qualify any of the functions declared in <valarray> as inline.

26.3.2.1 - valarray constructors [lib.valarray.cons]

valarray();

-1- Effects: Constructs an object of class valarray<T>,*

[Footnote: For convenience, such objects are referred to as ``arrays'' throughout the remainder of lib.numarray. --- end foonote]
which has zero length until it is passed into a library function as a modifiable lvalue or through a non-constant this pointer.*
[Footnote: This default constructor is essential, since arrays of valarray are likely to prove useful. There shall also be a way to change the size of an array after initialization; this is supplied by the semantics of the resize member function. --- end foonote]
explicit valarray(size_t);

-2- The array created by this constructor has a length equal to the value of the argument. The elements of the array are constructed using the default constructor for the instantiating type T .

valarray(const T&, size_t);

-3- The array created by this constructor has a length equal to the second argument. The elements of the array are initialized with the value of the first argument.

valarray(const T*, size_t);

-4- The array created by this constructor has a length equal to the second argument n. The values of the elements of the array are initialized with the first n values pointed to by the first argument.* If the value of the second argument is greater than the number of values pointed to by the first argument, the behavior is undefined.

[Footnote: This constructor is the preferred method for converting a C array to a valarray object. --- end foonote]
valarray(const valarray<T>&);

-5- The array created by this constructor has the same length as the argument array. The elements are initialized with the values of the corresponding elements of the argument array.*

[Footnote: This copy constructor creates a distinct array rather than an alias. Implementations in which arrays share storage are permitted, but they shall implement a copy-on-reference mechanism to ensure that arrays are conceptually distinct. --- end foonote]
valarray(const slice_array<T>&);
valarray(const gslice_array<T>&);
valarray(const mask_array<T>&);
valarray(const indirect_array<T>&);

-6- These conversion constructors convert one of the four reference templates to a valarray.

~valarray();

-7- The destructor is applied to every element of *this; an implementation may return all allocated memory.

26.3.2.2 - valarray assignment [lib.valarray.assign]

valarray<T>& operator=(const valarray<T>&);

-1- Each element of the *this array is assigned the value of the corresponding element of the argument array. The resulting behavior is undefined if the length of the argument array is not equal to the length of the *this array.

valarray<T>& operator=(const T&);

-2- The scalar assignment operator causes each element of the *this array to be assigned the value of the argument.

valarray<T>& operator=(const slice_array<T>&);
valarray<T>& operator=(const gslice_array<T>&);
valarray<T>& operator=(const mask_array<T>&);
valarray<T>& operator=(const indirect_array<T>&);

-3- These operators allow the results of a generalized subscripting operation to be assigned directly to a valarray.

-4- If the value of an element in the left hand side of a valarray assignment operator depends on the value of another element in that left hand side, the resulting behavior is undefined.

26.3.2.3 - valarray element access [lib.valarray.access]

T  operator[](size_t) const;
T& operator[](size_t);

-1- When applied to a constant array, the subscript operator returns the value of the corresponding element of the array. When applied to a non-constant array, the subscript operator returns a reference to the corresponding element of the array.

-2- Thus, the expression (a[i] = q, a[i]) == q evaluates as true for any non-constant valarray<T> a, any T q, and for any size_t i such that the value of i is less than the length of a.

-3- The expression &a[i+j] == &a[i] + j evaluates as true for all size_t i and size_t j such that i+j is less than the length of the non-constant array a.

-4- Likewise, the expression &a[i] != &b[j] evaluates as true for any two non-constant arrays a and b and for any size_t i and size_t j such that i is less than the length of a and j is less than the length of b. This property indicates an absence of aliasing and may be used to advantage by optimizing compilers.*

[Footnote: Compilers may take advantage of inlining, constant propagation, loop fusion, tracking of pointers obtained from operator new, and other techniques to generate efficient valarrays. --- end foonote]

-5- The reference returned by the subscript operator for a non-constant array is guaranteed to be valid until the member function resize(size_t, T) (lib.valarray.members) is called for that array or until the lifetime of that array ends, whichever happens first.

-6- If the subscript operator is invoked with a size_t argument whose value is not less than the length of the array, the behavior is undefined.

26.3.2.4 - valarray subset operations [lib.valarray.sub]

valarray<T>       operator[](slice) const;
slice_array<T>    operator[](slice);
valarray<T>       operator[](const gslice&) const;
gslice_array<T>   operator[](const gslice&);
valarray<T>       operator[](const valarray<bool>&) const;
mask_array<T>     operator[](const valarray<bool>&);
valarray<T>       operator[](const valarray<size_t>&) const;
indirect_array<T> operator[](const valarray<size_t>&);

-1- Each of these operations returns a subset of the array. The const-qualified versions return this subset as a new valarray. The non-const versions return a class template object which has reference semantics to the original array.

26.3.2.5 - valarray unary operators [lib.valarray.unary]

valarray<T> operator+() const;
valarray<T> operator-() const;
valarray<T> operator~() const;
valarray<bool> operator!() const;

-1- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type T ( bool for operator! ) or which may be unambiguously converted to type T ( bool for operator! ).

-2- Each of these operators returns an array whose length is equal to the length of the array. Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding element of the array.

26.3.2.6 - valarray computed assignment [lib.valarray.cassign]

valarray<T>& operator*= (const valarray<T>&);
valarray<T>& operator/= (const valarray<T>&);
valarray<T>& operator%= (const valarray<T>&);
valarray<T>& operator+= (const valarray<T>&);
valarray<T>& operator-= (const valarray<T>&);
valarray<T>& operator^= (const valarray<T>&);
valarray<T>& operator&= (const valarray<T>&);
valarray<T>& operator|= (const valarray<T>&);
valarray<T>& operator<<=(const valarray<T>&);
valarray<T>& operator>>=(const valarray<T>&);

-1- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied. Each of these operators performs the indicated operation on each of its elements and the corresponding element of the argument array.

-2- The array is then returned by reference.

-3- If the array and the argument array do not have the same length, the behavior is undefined. The appearance of an array on the left hand side of a computed assignment does not invalidate references or pointers.

-4- If the value of an element in the left hand side of a valarray computed assignment operator depends on the value of another element in that left hand side, the resulting behavior is undefined.

valarray<T>& operator*= (const T&);
valarray<T>& operator/= (const T&);
valarray<T>& operator%= (const T&);
valarray<T>& operator+= (const T&);
valarray<T>& operator-= (const T&);
valarray<T>& operator^= (const T&);
valarray<T>& operator&= (const T&);
valarray<T>& operator|= (const T&);
valarray<T>& operator<<=(const T&);
valarray<T>& operator>>=(const T&);

-5- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied.

-6- Each of these operators applies the indicated operation to each element of the array and the non-array argument.

-7- The array is then returned by reference.

-8- The appearance of an array on the left hand side of a computed assignment does not invalidate references or pointers to the elements of the array.

26.3.2.7 - valarray member functions [lib.valarray.members]

size_t size() const;

-1- This function returns the number of elements in the array.

T sum() const;
This function may only be instantiated for a type T to which operator+= can be applied. This function returns the sum of all the elements of the array.

-2- If the array has length 0, the behavior is undefined. If the array has length 1, sum() returns the value of element 0. Otherwise, the returned value is calculated by applying operator+= to a copy of an element of the array and all other elements of the array in an unspecified order.

T min() const;

-3- This function returns the minimum value contained in *this. The value returned for an array of length 0 is undefined. For an array of length 1, the value of element 0 is returned. For all other array lengths, the determination is made using operator<.

T max() const;

-4- This function returns the maximum value contained in *this. The value returned for an array of length 0 is undefined. For an array of length 1, the value of element 0 is returned. For all other array lengths, the determination is made using operator<.

valarray<T> shift(int n) const;

-5- This function returns an object of class valarray<T> of length size(), each of whose elements I is (*this)[I+n] if I+n is non-negative and less than size(), otherwise T(). Thus if element zero is taken as the leftmost element, a positive value of n shifts the elements left n places, with zero fill.

-6- [Example: If the argument has the value -2, the first two elements of the result will be constructed using the default constructor; the third element of the result will be assigned the value of the first element of the argument; etc.
--- end example]

valarray<T> cshift(int n) const;

-7- This function returns an object of class valarray<T>, of length size(), each of whose elements I is (*this)[(I+n)%size()]. Thus, if element zero is taken as the leftmost element, a positive value of n shifts the elements circularly left n places.

valarray<T> apply(T func(T)) const;
valarray<T> apply(T func(const T&)) const;

-8- These functions return an array whose length is equal to the array. Each element of the returned array is assigned the value returned by applying the argument function to the corresponding element of the array.

void resize(size_t sz, T c = T());

-9- This member function changes the length of the *this array to sz and then assigns to each element the value of the second argument. Resizing invalidates all pointers and references to elements in the array.

26.3.3 - valarray non-member operations [lib.valarray.nonmembers]

26.3.3.1 - valarray binary operators [lib.valarray.binary]

template<class T> valarray<T> operator*
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator/
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator%
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator+
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator-
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator^
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator&
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator|
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator<<
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> operator>>
    (const valarray<T>&, const valarray<T>&);

-1- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type T or which can be unambiguously converted to type T .

-2- Each of these operators returns an array whose length is equal to the lengths of the argument arrays. Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding elements of the argument arrays.

-3- If the argument arrays do not have the same length, the behavior is undefined.

template<class T> valarray<T> operator* (const valarray<T>&, const T&);
template<class T> valarray<T> operator* (const T&, const valarray<T>&);
template<class T> valarray<T> operator/ (const valarray<T>&, const T&);
template<class T> valarray<T> operator/ (const T&, const valarray<T>&);
template<class T> valarray<T> operator% (const valarray<T>&, const T&);
template<class T> valarray<T> operator% (const T&, const valarray<T>&);
template<class T> valarray<T> operator+ (const valarray<T>&, const T&);
template<class T> valarray<T> operator+ (const T&, const valarray<T>&);
template<class T> valarray<T> operator- (const valarray<T>&, const T&);
template<class T> valarray<T> operator- (const T&, const valarray<T>&);
template<class T> valarray<T> operator^ (const valarray<T>&, const T&);
template<class T> valarray<T> operator^ (const T&, const valarray<T>&);
template<class T> valarray<T> operator& (const valarray<T>&, const T&);
template<class T> valarray<T> operator& (const T&, const valarray<T>&);
template<class T> valarray<T> operator| (const valarray<T>&, const T&);
template<class T> valarray<T> operator| (const T&, const valarray<T>&);
template<class T> valarray<T> operator<<(const valarray<T>&, const T&);
template<class T> valarray<T> operator<<(const T&, const valarray<T>&);
template<class T> valarray<T> operator>>(const valarray<T>&, const T&);
template<class T> valarray<T> operator>>(const T&, const valarray<T>&);

-4- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type T or which can be unambiguously converted to type T .

-5- Each of these operators returns an array whose length is equal to the length of the array argument. Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding element of the array argument and the non-array argument.

26.3.3.2 - valarray logical operators [lib.valarray.comparison]

template<class T> valarray<bool> operator==
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator!=
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator<
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator>
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator<=
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator>=
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator&&
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<bool> operator||
    (const valarray<T>&, const valarray<T>&);

-1- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type bool or which can be unambiguously converted to type bool .

-2- Each of these operators returns a bool array whose length is equal to the length of the array arguments. Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding elements of the argument arrays.

-3- If the two array arguments do not have the same length, the behavior is undefined.

template<class T> valarray<bool> operator==(const valarray<T>&, const T&);
template<class T> valarray<bool> operator==(const T&, const valarray<T>&);
template<class T> valarray<bool> operator!=(const valarray<T>&, const T&);
template<class T> valarray<bool> operator!=(const T&, const valarray<T>&);
template<class T> valarray<bool> operator< (const valarray<T>&, const T&);
template<class T> valarray<bool> operator< (const T&, const valarray<T>&);
template<class T> valarray<bool> operator> (const valarray<T>&, const T&);
template<class T> valarray<bool> operator> (const T&, const valarray<T>&);
template<class T> valarray<bool> operator<=(const valarray<T>&, const T&);
template<class T> valarray<bool> operator<=(const T&, const valarray<T>&);
template<class T> valarray<bool> operator>=(const valarray<T>&, const T&);
template<class T> valarray<bool> operator>=(const T&, const valarray<T>&);
template<class T> valarray<bool> operator&&(const valarray<T>&, const T&);
template<class T> valarray<bool> operator&&(const T&, const valarray<T>&);
template<class T> valarray<bool> operator||(const valarray<T>&, const T&);
template<class T> valarray<bool> operator||(const T&, const valarray<T>&);

-4- Each of these operators may only be instantiated for a type T to which the indicated operator can be applied and for which the indicated operator returns a value which is of type bool or which can be unambiguously converted to type bool .

-5- Each of these operators returns a bool array whose length is equal to the length of the array argument. Each element of the returned array is initialized with the result of applying the indicated operator to the corresponding element of the array and the non-array argument.

26.3.3.3 - valarray transcendentals [lib.valarray.transcend]

template<class T> valarray<T> abs  (const valarray<T>&);
template<class T> valarray<T> acos (const valarray<T>&);
template<class T> valarray<T> asin (const valarray<T>&);
template<class T> valarray<T> atan (const valarray<T>&);
template<class T> valarray<T> atan2
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> atan2(const valarray<T>&, const T&);
template<class T> valarray<T> atan2(const T&, const valarray<T>&);
template<class T> valarray<T> cos  (const valarray<T>&);
template<class T> valarray<T> cosh (const valarray<T>&);
template<class T> valarray<T> exp  (const valarray<T>&);
template<class T> valarray<T> log  (const valarray<T>&);
template<class T> valarray<T> log10(const valarray<T>&);
template<class T> valarray<T> pow
    (const valarray<T>&, const valarray<T>&);
template<class T> valarray<T> pow  (const valarray<T>&, const T&);
template<class T> valarray<T> pow  (const T&, const valarray<T>&);
template<class T> valarray<T> sin  (const valarray<T>&);
template<class T> valarray<T> sinh (const valarray<T>&);
template<class T> valarray<T> sqrt (const valarray<T>&);
template<class T> valarray<T> tan  (const valarray<T>&);
template<class T> valarray<T> tanh (const valarray<T>&);

-1- Each of these functions may only be instantiated for a type T to which a unique function with the indicated name can be applied. This function shall return a value which is of type T or which can be unambiguously converted to type T .

26.3.4 - Class slice [lib.class.slice]

namespace std {
  class slice {
  public:
    slice();
    slice(size_t, size_t, size_t);

    size_t start() const;
    size_t size() const;
    size_t stride() const;
  };
}

-1- The slice class represents a BLAS-like slice from an array. Such a slice is specified by a starting index, a length, and a stride.*

[Footnote: BLAS stands for Basic Linear Algebra Subprograms. C++ programs may instantiate this class. See, for example, Dongarra, Du Croz, Duff, and Hammerling: A set of Level 3 Basic Linear Algebra Subprograms; Technical Report MCS-P1-0888, Argonne National Laboratory (USA), Mathematics and Computer Science Division, August, 1988. --- end foonote]

26.3.4.1 - slice constructors [lib.cons.slice]

slice();
slice(size_t start, size_t length, size_t stride);
slice(const slice&);

-1- The default constructor for slice creates a slice which specifies no elements. A default constructor is provided only to permit the declaration of arrays of slices. The constructor with arguments for a slice takes a start, length, and stride parameter.

-2- [Example: slice(3, 8, 2) constructs a slice which selects elements 3, 5, 7, ... 17 from an array.
--- end example]

26.3.4.2 - slice access functions [lib.slice.access]

size_t start() const;
size_t size() const;
size_t stride() const;

-1- These functions return the start, length, or stride specified by a slice object.

26.3.5 - Template class slice_array [lib.template.slice.array]

namespace std {
  template <class T> class slice_array {
  public:
    typedef T value_type;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;
    void operator=(const T&);
   ~slice_array();
  private:
    slice_array();
    slice_array(const slice_array&);
    slice_array& operator=(const slice_array&);
    //    remainder implementation defined
  };
}

-1- The slice_array template is a helper template used by the slice subscript operator

slice_array<T> valarray<T>::operator[](slice);
It has reference semantics to a subset of an array specified by a slice object.

-2- [Example: The expression a[slice(1, 5, 3)] = b; has the effect of assigning the elements of b to a slice of the elements in a. For the slice shown, the elements selected from a are 1, 4, ..., 13.
--- end example]

-3- [Note: C++ programs may not instantiate slice_array, since all its constructors are private. It is intended purely as a helper class and should be transparent to the user.
--- end note]

26.3.5.1 - slice_array constructors [lib.cons.slice.arr]

slice_array();
slice_array(const slice_array&);

-1- The slice_array template has no public constructors. These constructors are declared to be private. These constructors need not be defined.

26.3.5.2 - slice_array assignment [lib.slice.arr.assign]

void         operator=(const valarray<T>&) const;
slice_array& operator=(const slice_array&);

-1- The second of these two assignment operators is declared private and need not be defined. The first has reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which the slice_array object refers.

26.3.5.3 - slice_array computed assignment [lib.slice.arr.comp.assign]

void operator*= (const valarray<T>&) const;
void operator/= (const valarray<T>&) const;
void operator%= (const valarray<T>&) const;
void operator+= (const valarray<T>&) const;
void operator-= (const valarray<T>&) const;
void operator^= (const valarray<T>&) const;
void operator&= (const valarray<T>&) const;
void operator|= (const valarray<T>&) const;
void operator<<=(const valarray<T>&) const;
void operator>>=(const valarray<T>&) const;

-1- These computed assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the slice_array object refers.

26.3.5.4 - slice_array fill function [lib.slice.arr.fill]

void operator=(const T&);

-1- This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the slice_array object refers.

26.3.6 - The gslice class [lib.class.gslice]

namespace std {
  class gslice {
  public:
    gslice();
    gslice(size_t s, const valarray<size_t>& l, const valarray<size_t>& d);

    size_t           start() const;
    valarray<size_t> size() const;
    valarray<size_t> stride() const;
  };
}

-1- This class represents a generalized slice out of an array. A gslice is defined by a starting offset (s), a set of lengths (lj), and a set of strides (dj). The number of lengths shall equal the number of strides.

-2- A gslice represents a mapping from a set of indices (ij), equal in number to the number of strides, to a single index k. It is useful for building multidimensional array classes using the valarray template, which is one-dimensional. The set of one-dimensional index values specified by a gslice are k = s + sum from j { ij dj } where the multidimensional indices ij range in value from 0 to li j - 1.

-3- [Example: The gslice specification

start  = 3
length = {2, 4, 3}
stride = {19, 4, 1}
yields the sequence of one-dimensional indices
k = 3 + (0,1) × 19 + (0,1,2,3) × 4 + (0,1,2) × 1
which are ordered as shown in the following table:
    (i0, i1, i2, k) =
	    (0, 0, 0, 3),
	    (0, 0, 1, 4),
	    (0, 0, 2, 5),
	    (0, 1, 0, 7),
	    (0, 1, 1, 8),
	    (0, 1, 2, 9),
	    (0, 2, 0, 11),
	    (0, 2, 1, 12),
	    (0, 2, 2, 13),
	    (0, 3, 0, 15),
	    (0, 3, 1, 16),
	    (0, 3, 2, 17),
	    (1, 0, 0, 22),
	    (1, 0, 1, 23),
	    ...
	    (1, 3, 2, 36)
That is, the highest-ordered index turns fastest.
--- end example]

-4- It is possible to have degenerate generalized slices in which an address is repeated.

-5- [Example: If the stride parameters in the previous example are changed to {1, 1, 1}, the first few elements of the resulting sequence of indices will be

    (0, 0, 0, 3),
    (0, 0, 1, 4),
    (0, 0, 2, 5),
    (0, 1, 0, 4),
    (0, 1, 1, 5),
    (0, 1, 2, 6),
    ...

--- end example]

-6- If a degenerate slice is used as the argument to the non-const version of operator[](const gslice&), the resulting behavior is undefined.

26.3.6.1 - gslice constructors [lib.gslice.cons]

gslice();
gslice(size_t start, const valarray<size_t>& lengths,
			   const valarray<size_t>& strides);
gslice(const gslice&);

-1- The default constructor creates a gslice which specifies no elements. The constructor with arguments builds a gslice based on a specification of start, lengths, and strides, as explained in the previous section.

26.3.6.2 - gslice access functions [lib.gslice.access]

size_t           start()  const;
valarray<size_t> size() const;
valarray<size_t> stride() const;
These access functions return the representation of the start, lengths, or strides specified for the gslice.

26.3.7 - Template class gslice_array [lib.template.gslice.array]

namespace std {
  template <class T> class gslice_array {
  public:
    typedef T value_type;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;
    void operator=(const T&);
   ~gslice_array();
  private:
    gslice_array();
    gslice_array(const gslice_array&);
    gslice_array& operator=(const gslice_array&);
    //   remainder implementation defined
  };
}

-1- This template is a helper template used by the slice subscript operator

gslice_array<T> valarray<T>::operator[](const gslice&);
It has reference semantics to a subset of an array specified by a gslice object.

-2- Thus, the expression a[gslice(1, length, stride)] = b has the effect of assigning the elements of b to a generalized slice of the elements in a.

-3- [Note: C++ programs may not instantiate gslice_array, since all its constructors are private. It is intended purely as a helper class and should be transparent to the user.
--- end note]

26.3.7.1 - gslice_array constructors [lib.gslice.array.cons]

gslice_array();
gslice_array(const gslice_array&);

-1- The gslice_array template has no public constructors. It declares the above constructors to be private. These constructors need not be defined.

26.3.7.2 - gslice_array assignment [lib.gslice.array.assign]

void operator=(const valarray<T>&) const;
gslice_array& operator=(const gslice_array&);

-1- The second of these two assignment operators is declared private and need not be defined. The first has reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which the gslice_array refers.

26.3.7.3 - gslice_array computed assignment [lib.gslice.array.comp.assign]

void operator*= (const valarray<T>&) const;
void operator/= (const valarray<T>&) const;
void operator%= (const valarray<T>&) const;
void operator+= (const valarray<T>&) const;
void operator-= (const valarray<T>&) const;
void operator^= (const valarray<T>&) const;
void operator&= (const valarray<T>&) const;
void operator|= (const valarray<T>&) const;
void operator<<=(const valarray<T>&) const;
void operator>>=(const valarray<T>&) const;

-1- These computed assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the gslice_array object refers.

26.3.7.4 - gslice_array fill function [lib.gslice.array.fill]

void operator=(const T&);

-1- This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the gslice_array object refers.

26.3.8 - Template class mask_array [lib.template.mask.array]

namespace std {
  template <class T> class mask_array {
  public:
    typedef T value_type;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;
    void operator=(const T&);
   ~mask_array();
  private:
    mask_array();
    mask_array(const mask_array&);
    mask_array& operator=(const mask_array&);
    //   remainder implementation defined
  };
}

-1- This template is a helper template used by the mask subscript operator:
mask_array<T> valarray<T>::operator[](const valarray<bool>&).
It has reference semantics to a subset of an array specified by a boolean mask. Thus, the expression a[mask] = b; has the effect of assigning the elements of b to the masked elements in a (those for which the corresponding element in mask is true.)

-2- [Note: C++ programs may not declare instances of mask_array, since all its constructors are private. It is intended purely as a helper class, and should be transparent to the user.
--- end note]

26.3.8.1 - mask_array constructors [lib.mask.array.cons]

mask_array();
mask_array(const mask_array&);

-1- The mask_array template has no public constructors. It declares the above constructors to be private. These constructors need not be defined.

26.3.8.2 - mask_array assignment [lib.mask.array.assign]

void operator=(const valarray<T>&) const;
mask_array& operator=(const mask_array&);

-1- The second of these two assignment operators is declared private and need not be defined. The first has reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which it refers.

26.3.8.3 - mask_array computed assignment [lib.mask.array.comp.assign]

void operator*= (const valarray<T>&) const;
void operator/= (const valarray<T>&) const;
void operator%= (const valarray<T>&) const;
void operator+= (const valarray<T>&) const;
void operator-= (const valarray<T>&) const;
void operator^= (const valarray<T>&) const;
void operator&= (const valarray<T>&) const;
void operator|= (const valarray<T>&) const;
void operator<<=(const valarray<T>&) const;
void operator>>=(const valarray<T>&) const;

-1- These computed assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the mask object refers.

26.3.8.4 - mask_array fill function [lib.mask.array.fill]

void operator=(const T&);
This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the mask_array object refers.

26.3.9 - Template class indirect_array [lib.template.indirect.array]

namespace std {
  template <class T> class indirect_array {
  public:
    typedef T value_type;

    void operator=  (const valarray<T>&) const;
    void operator*= (const valarray<T>&) const;
    void operator/= (const valarray<T>&) const;
    void operator%= (const valarray<T>&) const;
    void operator+= (const valarray<T>&) const;
    void operator-= (const valarray<T>&) const;
    void operator^= (const valarray<T>&) const;
    void operator&= (const valarray<T>&) const;
    void operator|= (const valarray<T>&) const;
    void operator<<=(const valarray<T>&) const;
    void operator>>=(const valarray<T>&) const;
    void operator=(const T&);
   ~indirect_array();
  private:
    indirect_array();
    indirect_array(const indirect_array&);
    indirect_array& operator=(const indirect_array&);
    //   remainder implementation defined
  };
}

-1- This template is a helper template used by the indirect subscript operator
indirect_array<T> valarray<T>::operator[](const valarray<size_t>&).
It has reference semantics to a subset of an array specified by an indirect_array. Thus the expression a[indirect] = b; has the effect of assigning the elements of b to the elements in a whose indices appear in indirect.

-2- [Note: C++ programs may not declare instances of indirect_array, since all its constructors are private. It is intended purely as a helper class, and should be transparent to the user.
--- end note]

26.3.9.1 - indirect_array constructors [lib.indirect.array.cons]

indirect_array();
indirect_array(const indirect_array&);
The indirect_array template has no public constructors. The constructors listed above are private. These constructors need not be defined.

26.3.9.2 - indirect_array assignment [lib.indirect.array.assign]

void operator=(const valarray<T>&) const;
indirect_array& operator=(const indirect_array&);

-1- The second of these two assignment operators is declared private and need not be defined. The first has reference semantics, assigning the values of the argument array elements to selected elements of the valarray<T> object to which it refers.

-2- If the indirect_array specifies an element in the valarray<T> object to which it refers more than once, the behavior is undefined.

-3- [Example:

int addr[] = {2, 3, 1, 4, 4};
valarray<size_t> indirect(addr, 5);
valarray<double> a(0., 10), b(1., 5);
a[indirect] = b;
results in undefined behavior since element 4 is specified twice in the indirection.
--- end example]

26.3.9.3 - indirect_array computed assignment [lib.indirect.array.comp.assign]

void operator*= (const valarray<T>&) const;
void operator/= (const valarray<T>&) const;
void operator%= (const valarray<T>&) const;
void operator+= (const valarray<T>&) const;
void operator-= (const valarray<T>&) const;
void operator^= (const valarray<T>&) const;
void operator&= (const valarray<T>&) const;
void operator|= (const valarray<T>&) const;
void operator<<=(const valarray<T>&) const;
void operator>>=(const valarray<T>&) const;

-1- These computed assignments have reference semantics, applying the indicated operation to the elements of the argument array and selected elements of the valarray<T> object to which the indirect_array object refers.

-2- If the indirect_array specifies an element in the valarray<T> object to which it refers more than once, the behavior is undefined.

26.3.9.4 - indirect_array fill function [lib.indirect.array.fill]

void operator=(const T&);

-1- This function has reference semantics, assigning the value of its argument to the elements of the valarray<T> object to which the indirect_array object refers.

26.4 - Generalized numeric operations [lib.numeric.ops]

Header <numeric> synopsis

namespace std {
  template <class InputIterator, class T>
    T accumulate(InputIterator first, InputIterator last, T init);
  template <class InputIterator, class T, class BinaryOperation>
    T accumulate(InputIterator first, InputIterator last, T init,
		 BinaryOperation binary_op);
  template <class InputIterator1, class InputIterator2, class T>
    T inner_product(InputIterator1 first1, InputIterator1 last1,
		    InputIterator2 first2, T init);
  template <class InputIterator1, class InputIterator2, class T,
	    class BinaryOperation1, class BinaryOperation2>
    T inner_product(InputIterator1 first1, InputIterator1 last1,
		    InputIterator2 first2, T init,
		    BinaryOperation1 binary_op1,
		    BinaryOperation2 binary_op2);
  template <class InputIterator, class OutputIterator>
    OutputIterator partial_sum(InputIterator first,
                               InputIterator last,
			       OutputIterator result);
  template <class InputIterator, class OutputIterator,
            class BinaryOperation>
    OutputIterator partial_sum(InputIterator first,
                               InputIterator last,
			       OutputIterator result,
                               BinaryOperation binary_op);
  template <class InputIterator, class OutputIterator>
    OutputIterator adjacent_difference(InputIterator first,
                                       InputIterator last,
				       OutputIterator result);
  template <class InputIterator, class OutputIterator,
            class BinaryOperation>
    OutputIterator adjacent_difference(InputIterator first,
                                       InputIterator last,
				       OutputIterator result,
				       BinaryOperation binary_op);
}

-1- The requirements on the types of algorithms' arguments that are described in the introduction to clause lib.algorithms also apply to the following algorithms.

26.4.1 - Accumulate [lib.accumulate]

template <class InputIterator, class T>
  T accumulate(InputIterator first, InputIterator last, T init);
template <class InputIterator, class T, class BinaryOperation>
  T accumulate(InputIterator first, InputIterator last, T init,
	       BinaryOperation binary_op);

-1- Effects: Computes its result by initializing the accumulator acc with the initial value init and then modifies it with acc = acc + *i or acc = binary_op(acc, *i) for every iterator i in the range [first, last) in order.*

[Footnote: accumulate is similar to the APL reduction operator and Common Lisp reduce function, but it avoids the difficulty of defining the result of reduction on an empty sequence by always requiring an initial value. --- end foonote]

-2- Requires: T must meet the requirements of CopyConstructible (lib.copyconstructible) and Assignable (lib.container.requirements) types. binary_op shall not cause side effects.

26.4.2 - Inner product [lib.inner.product]

template <class InputIterator1, class InputIterator2, class T>
  T inner_product(InputIterator1 first1, InputIterator1 last1,
		  InputIterator2 first2, T init);
template <class InputIterator1, class InputIterator2, class T,
	  class BinaryOperation1, class BinaryOperation2>
  T inner_product(InputIterator1 first1, InputIterator1 last1,
		  InputIterator2 first2, T init,
		  BinaryOperation1 binary_op1,
		  BinaryOperation2 binary_op2);

-1- Effects: Computes its result by initializing the accumulator acc with the initial value init and then modifying it with acc = acc + (*i1) * (*i2) or acc = binary_op1(acc, binary_op2(*i1, *i2)) for every iterator i1 in the range [first, last) and iterator i2 in the range [first2, first2 + (last - first)) in order.

-2- Requires: T must meet the requirements of CopyConstructible (lib.copyconstructible) and Assignable (lib.container.requirements) types. binary_op1 and binary_op2 shall not cause side effects.

26.4.3 - Partial sum [lib.partial.sum]

template <class InputIterator, class OutputIterator>
  OutputIterator
    partial_sum(InputIterator first, InputIterator last,
		OutputIterator result);
template
  <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator
      partial_sum(InputIterator first, InputIterator last,
		  OutputIterator result, BinaryOperation binary_op);

-1- Effects: Assigns to every element referred to by iterator i in the range [result, result + (last - first)) a value correspondingly equal to
((...(*first + *(first + 1)) + ...) + *(first + (i - result)))
or
binary_op(binary_op(..., binary_op(*first, *(first + 1)),...), *(first + (i - result)))

-2- Returns: result + (last - first).

-3- Complexity: Exactly (last - first) - 1 applications of binary_op.

-4- Requires: binary_op is expected not to have any side effects.

-5- Notes: result may be equal to first.

26.4.4 - Adjacent difference [lib.adjacent.difference]

template <class InputIterator, class OutputIterator>
  OutputIterator
    adjacent_difference(InputIterator first, InputIterator last,
			OutputIterator result);
template
  <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator
      adjacent_difference(InputIterator first, InputIterator last,
			  OutputIterator result,
			  BinaryOperation binary_op);

-1- Effects: Assigns to every element referred to by iterator i in the range [result + 1, result + (last - first)) a value correspondingly equal to
*(first + (i - result)) - *(first + (i - result) - 1)
or
binary_op(*(first + (i - result)), *(first + (i - result) - 1)).
result gets the value of *first.

-2- Requires: binary_op shall not have any side effects.

-3- Notes: result may be equal to first.

-4- Returns: result + (last - first).

-5- Complexity: Exactly (last - first) - 1 applications of binary_op.

26.5 - C Library [lib.c.math]

-1- Tables ?? and ?? describe headers <cmath> and <cstdlib> (.CW abs() , div(), rand(), srand()), respectively.

Header <cmath> synopsis
TypeName(s)
Macro:HUGE_VAL
Functions:
acoscosfmodmodftan
asincoshfrexppowtanh
atanexpldexpsin
atan2fabslogsinh
ceilfloorlog10sqrt

Header <cstdlib> synopsis
TypeName(s)
Macros:RAND_MAX
Types:div_tldiv_t
Functions:
abslabssrand
divldivrand

-2- The contents of these headers are the same as the Standard C library headers <math.h> and <stdlib.h> respectively, with the following additions:

-3- In addition to the int versions of certain math functions in <cstdlib>, C++ adds long overloaded versions of these functions, with the same semantics.

-4- The added signatures are:

long   abs(long);               // labs()
ldiv_t div(long, long);         // ldiv()

-5- In addition to the double versions of the math functions in <cmath>, C++ adds float and long double overloaded versions of these functions, with the same semantics.

-6- The added signatures are:

float abs  (float);
float acos (float);
float asin (float);
float atan (float);
float atan2(float, float);
float ceil (float);
float cos  (float);
float cosh (float);
float exp  (float);
float fabs (float);
float floor(float);
float fmod (float, float);
float frexp(float, int*);
float ldexp(float, int);
float log  (float);
float log10(float);
float modf (float, float*);
float pow  (float, float);
float pow  (float, int);
float sin  (float);
float sinh (float);
float sqrt (float);
float tan  (float);
float tanh (float);
double abs(double);            // fabs()
double pow(double, int);
long double abs  (long double);
long double acos (long double);
long double asin (long double);
long double atan (long double);
long double atan2(long double, long double);
long double ceil (long double);
long double cos  (long double);
long double cosh (long double);
long double exp  (long double);
long double fabs (long double);
long double floor(long double);
long double fmod (long double, long double);
long double frexp(long double, int*);
long double ldexp(long double, int);
long double log  (long double);
long double log10(long double);
long double modf (long double, long double*);
long double pow  (long double, long double);
long double pow  (long double, int);
long double sin  (long double);
long double sinh (long double);
long double sqrt (long double);
long double tan  (long double);
long double tanh (long double);

See also ISO C subclauses 7.5, 7.10.2, 7.10.6.