<!--
    Licensed to the Apache Software  Foundation (ASF) under one or more
    contributor  license agreements.  See  the NOTICE  file distributed
    with  this  work  for  additional information  regarding  copyright
    ownership.   The ASF  licenses this  file to  you under  the Apache
    License, Version  2.0 (the  License); you may  not use  this file
    except in  compliance with the License.   You may obtain  a copy of
    the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the  License is distributed on an  "AS IS" BASIS,
    WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
    implied.   See  the License  for  the  specific language  governing
    permissions and limitations under the License.

    Copyright 1999-2007 Rogue Wave Software, Inc.
-->

<HTML>
<HEAD>
<TITLE>slice_array</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="slice.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="sort.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library Reference Guide</B></DIV>
<H2>slice_array</H2>
<P><B>Library:</B>&nbsp;&nbsp;<A HREF="2-10.html">Numerics</A></P>

<PRE><HR><B><I>Does not inherit</I></B><HR></PRE>

<UL>
<LI><A HREF="#sec1">Local Index</A></LI>
<LI><A HREF="#sec2">Summary</A></LI>
<LI><A HREF="#sec3">Synopsis</A></LI>
<LI><A HREF="#sec4">Description</A></LI>
<LI><A HREF="#sec5">Interface</A></LI>
<LI><A HREF="#sec6">Constructors</A></LI>
<LI><A HREF="#sec7">Assignment Operators</A></LI>
<LI><A HREF="#sec8">Computed Assignment Operators</A></LI>
<LI><A HREF="#sec9">Example</A></LI>
<LI><A HREF="#sec10">See Also</A></LI>
<LI><A HREF="#sec11">Standards Conformance</A></LI>
</UL>
<A NAME="sec1"><H3>Local Index</H3></A>
<H4>Members</H4>
<UL><TABLE CELLPADDING=3>
<TR><TD VALIGN=top>
<A HREF="#idx1180">operator%=()</A><BR>
<A HREF="#idx1180">operator&amp;=()</A><BR>
<A HREF="#idx1180">operator&gt;&gt;=()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1180">operator&lt;&lt;=()</A><BR>
<A HREF="#idx1180">operator*=()</A><BR>
<A HREF="#idx1180">operator+=()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1180">operator-=()</A><BR>
<A HREF="#idx1180">operator/=()</A><BR>
<A HREF="#idx1177">operator=()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1180">operator^=()</A><BR>
<A HREF="#idx1180">operator|=()</A><BR>
<A HREF="#idx1176">slice_array()</A><BR>
</TD></TR>
</TABLE></UL>

<A NAME="sec2"><H3>Summary</H3></A>
<P>A numeric array class for representing a BLAS-like slice from a <B><I><A HREF="valarray.html">valarray</A></I></B></P>
<A NAME="sec3"><H3>Synopsis</H3></A>

<PRE>#include &lt;valarray&gt;

namespace std {
  template &lt;class T&gt;
  class slice_array;
}
</PRE>
<A NAME="sec4"><H3>Description</H3></A>
<P>The <B><I><A HREF="valarray.html">valarray</A></I></B> helper class <B><I>slice_array</I></B> gives a slice view into a <B><I>valarray</I></B>. A&nbsp;<B><I>slice_array</I></B> is only produced by applying the slice subscript operator to a&nbsp;<B><I>valarray</I></B>. The elements in a <B><I>slice_array</I></B> are references to selected elements in the <B><I>valarray</I></B> (so changing an element in the <B><I>slice_array</I></B> really changes the corresponding element in the <B><I>valarray</I></B>). A <B><I>slice_array</I></B> does not itself hold any distinct elements. The template cannot be instantiated directly since all its constructors are private. However, you can easily copy a <B><I>slice_array</I></B> to a <B><I>valarray</I></B> using either the <B><I>valarray</I></B> copy constructor or the assignment operator. Reference semantics are lost at that point. </P>
<A NAME="sec5"><H3>Interface</H3></A>

<UL><PRE>namespace std {

  template &lt;class T&gt; class slice_array {
    public:

    // types
    typedef T value_type;

    // destructor
    ~slice_array();

    // public assignment
    void operator=(const valarray&lt;T&gt;&amp; array) const;
  
    // computed assignment
    void operator*=(const valarray&lt;T&gt;&amp; array) const;
    void operator/=(const valarray&lt;T&gt;&amp; array) const;
    void operator%=(const valarray&lt;T&gt;&amp; array) const;
    void operator+=(const valarray&lt;T&gt;&amp; array) const;
    void operator-=(const valarray&lt;T&gt;&amp; array) const;
    void operator^=(const valarray&lt;T&gt;&amp; array) const;
    void operator&amp;=(const valarray&lt;T&gt;&amp; array) const;
    void operator|=(const valarray&lt;T&gt;&amp; array) const;
    void operator&lt;&lt;=(const valarray&lt;T&gt;&amp; array) const;
    void operator&gt;&gt;=(const valarray&lt;T&gt;&amp; array) const;
 
    // other
    void operator=(const T&amp;);  

    private:
    // constructors
    slice_array();
    slice_array(const slice_array&lt;T&gt;&amp;);
    // operator=
    slice_array&lt;T&gt;&amp; operator=(const slice_array&lt;T&gt;&amp; array);
  };
}
</PRE></UL>
<A NAME="sec6"><H3>Constructors</H3></A>

<A NAME="idx1176"></A><PRE><B>slice_array</B>();
<B>slice_array</B>(const slice_array&amp;);</PRE>
<UL>
<P>All <B><I>slice_array</I></B> constructors are private and cannot be called directly. This prevents copy construction of <B><I>slice_array</I></B>s.</P>
</UL>

<A NAME="sec7"><H3>Assignment Operators</H3></A>

<A NAME="idx1177"></A><PRE>void <B>operator=</B>(const valarray&lt;T&gt;&amp; x) const;</PRE>
<UL>
<P>Assigns values from <SAMP>x </SAMP>to the selected elements of the <B><I><A HREF="valarray.html">valarray</A></I></B> that self refers to. Remember that a <B><I>slice_array</I></B> never holds any elements itself, it simply refers to selected elements in the <B><I>valarray</I></B> used to generate it.</P>
</UL>


<A NAME="idx1178"></A><PRE>slice_array&lt;T&gt;&amp; 
<B>operator=</B>(const slice-_array&lt;T&gt;&amp; x);</PRE>
<UL>
<P>Private assignment operator. Cannot be called directly, thus preventing assignment between <B><I>slice_array</I></B>s.</P>
</UL>


<A NAME="idx1179"></A><PRE>void <B>operator=</B>(const T&amp; x);</PRE>
<UL>
<P>Assigns <SAMP>x</SAMP> to the selected elements of the <B><I><A HREF="valarray.html">valarray</A></I></B> that self refers to. </P>
</UL>

<A NAME="sec8"><H3>Computed Assignment Operators</H3></A>

<A NAME="idx1180"></A><PRE>void <B>operator*=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator/=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator%=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator+=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator-=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator^=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator&amp;=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator|=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator&lt;&lt;=</B>(const valarray&lt;T&gt;&amp; val) const;
void <B>operator&gt;&gt;=</B>(const valarray&lt;T&gt;&amp; val) const;</PRE>
<UL>
<P>Applies the indicated operation using elements from <SAMP>val</SAMP> to the selected elements of the <B><I><A HREF="valarray.html">valarray</A></I></B> that self refers to. Remember that a <B><I>slice_array</I></B> never holds any elements itself; it simply refers to selected elements in the <B><I>valarray</I></B> used to generate it.</P>
</UL>

<A NAME="sec9"><H3>Example</H3></A>

<UL><PRE>//
//  slice_array.cpp
//

#include &lt;valarray.h&gt;  // Includes valarray and provides stream inserter.

typedef std::valarray&lt;int&gt; valarray_t;

int main(void) {

    valarray_t::value_type ibuf[9] = {0,1,2,3,4,5,6,7,8};

    // Create a valarray initialized to the sequence of
    // integers above.
    valarray_t vi (ibuf,9);
    
    std::cout &lt;&lt; "original valarray vi\n\n" &lt;&lt; vi &lt;&lt; "\n\n";

    // Display a slice of the valarray.
    std::cout &lt;&lt; "vi[slice(0,3,3)]\n\n"
              &lt;&lt; vi[std::slice(0,3,3)] &lt;&lt; "\n\n";
    
    // Unfortunately, slice_arrays were not designed to be 
    // easily combined.  An explicit conversion to valarray 
    // is required, leaving us with this awkward casting
    // syntax.
    vi[std::slice (0,3,3)] =
            static_cast&lt;valarray_t&gt;(vi[std::slice (1,3,3)]) +
            static_cast&lt;valarray_t&gt;(vi[std::slice (2,3,3)]);  

    // The operation above uses slices ([0-2],3,3) to treat
    // our valarray as a 3-dimensional array:
    //
    //  0 1 2                 3 = 1 + 2 
    //  3 4 5                 9 = 4 + 5
    //  6 7 8                15 = 7 + 8          
    //  | | |                 |   |   | 
    //  | | +-slice(2,3,3)    |   |   +- slice_array for 
    //  | |                   |   |      arithmetic operand.
    //  | +---slice(1,3,3)    |   +----- slice_array for 
    //  |                     |          arithmetic operand.
    //  +-----slice(0,3,3)    +---slice_array assignment
    //                            refers to valarray.
    
    std::cout &lt;&lt; "vi[slice(0,3,3)] = vi[slice(1,3,3)] + "
              &lt;&lt; "vi[slice(2,3,3)]\n\n"
              &lt;&lt; vi &lt;&lt; std::endl;
    
    return 0;
}


Program Output:
</PRE></UL>
<UL><PRE>original valarray vi

[0,1,2,3,4,5,6,7,8]

vi[slice(0,3,3)]

[0,3,6]

vi[slice(0,3,3)] = vi[slice(1,3,3)] + vi[slice(2,3,3)]

[3,1,2,9,4,5,15,7,8]
</PRE></UL>
<A NAME="sec10"><H3>See Also</H3></A>
<P><B><I><A HREF="slice.html">slice</A></I></B>, <B><I><A HREF="valarray.html">valarray</A></I></B>, <B><I><A HREF="gslice.html">gslice</A></I></B>, <B><I><A HREF="gslice-array.html">gslice_array</A></I></B>, <B><I><A HREF="mask-array.html">mask_array</A></I></B>, <B><I><A HREF="indirect-array.html">indirect_array</A></I></B></P>
<A NAME="sec11"><H3>Standards Conformance</H3></A>
<P><I>ISO/IEC 14882:1998 -- International Standard for Information Systems -- Programming Language C++, Section 26.3.5</I></P>

<BR>
<HR>
<A HREF="slice.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="sort.html"><IMG SRC="images/bnext.gif" WIDTH=20 HEIGHT=21 ALT="Next file" BORDER=O></A>

<!-- Google Analytics tracking code -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
    _uacct = "UA-1775151-1";
    urchinTracker();
</script>
<!-- end of Google Analytics tracking code -->

</BODY>
</HTML>
