<!--
    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>queue</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="queue-h.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="randomaccessiterators.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>queue</H2>
<P><B>Library:</B>&nbsp;&nbsp;<A HREF="2-7.html">Containers</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">Member Functions</A></LI>
<LI><A HREF="#sec8">Nonmember 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="#idx1112">back()</A><BR>
<A HREF="#idx1114">empty()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1115">front()</A><BR>
<A HREF="#idx1117">pop()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1118">push()</A><BR>
<A HREF="#idx1111">queue()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1119">size()</A><BR>
</TD></TR>
</TABLE></UL>
<H4>Non-Members</H4>
<UL><TABLE CELLPADDING=3>
<TR><TD VALIGN=top>
<A HREF="#idx1121">operator!=()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1123">operator&gt;()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1122">operator&lt;()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx1120">operator==()</A><BR>
</TD></TR>
</TABLE></UL>

<A NAME="sec2"><H3>Summary</H3></A>
<P>A container adaptor that behaves like a queue (first in, first out)</P>
<A NAME="sec3"><H3>Synopsis</H3></A>

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

namespace std {
  template &lt;class T, class Container = deque&lt;T&gt; &gt; 
  class queue;
}
</PRE>
<A NAME="sec4"><H3>Description</H3></A>
<P>The <B><I>queue</I></B> container adaptor lets a container act as a queue. In a queue, items are pushed into the back of the container and removed from the front. The first items pushed into the queue are the first items to be popped off of the queue (first in, first out, or FIFO). </P>
<P><B><I>queue</I></B> can adapt any container that supports the <SAMP>front()</SAMP>, <SAMP>back()</SAMP>, <SAMP>push_back()</SAMP>, and <SAMP>pop_front()</SAMP> operations. In particular, <B><I><A HREF="deque.html">deque</A></I></B> and <B><I><A HREF="list.html">list</A></I></B> can be used. </P>
<A NAME="sec5"><H3>Interface</H3></A>

<UL><PRE>namespace std {

  template &lt;class T, class Container = deque&lt;T&gt; &gt;
  class queue {

    public:

      // typedefs
      typedef typename Container::value_type value_type;
      typedef typename Container::size_type size_type;
      typedef Container container_type;

      // Construct/Copy/Destroy
      explicit queue (const Container&amp; = Container());

      // Accessors
      bool empty () const;
     size_type size () const;
     value_type&amp; front ();
     const value_type&amp; front () const;
     value_type&amp; back ();
     const value_type&amp; back () const;
     void push (const value_type&amp;);
     void pop ();
  };

  // Nonmember Operators

  template &lt;class T, class Container&gt;
  bool operator==(const queue&lt;T, Container&gt;&amp;,
                  const queue&lt;T, Container&gt;&amp;);

  template &lt;class T, class Container&gt;
  bool operator!=(const queue&lt;T, Container&gt;&amp;,
                  const queue&lt;T, Container&gt;&amp;);

  template &lt;class T, class Container&gt;
  bool operator&lt;(const queue&lt;T, Container&gt;&amp;,
                 const queue&lt;T, Container&gt;&amp;);

  template &lt;class T, class Container&gt;
  bool operator&gt;(const queue&lt;T, Container&gt;&amp;,
                 const queue&lt;T, Container&gt;&amp;);

  template &lt;class T, class Container&gt;
  bool operator&lt;=(const queue&lt;T, Container&gt;&amp;,
                  const queue&lt;T, Container&gt;&amp;);

  template &lt;class T, class Container&gt;
  bool operator&gt;=(const queue&lt;T, Container&gt;&amp;,
                  const queue&lt;T, Container&gt;&amp;);
}
</PRE></UL>
<A NAME="sec6"><H3>Constructors</H3></A>

<A NAME="idx1111"></A><PRE>explicit <B>queue</B>(const Container&amp; = Container());</PRE>
<UL>
<P>Creates a queue of zero elements.</P>
</UL>

<A NAME="sec7"><H3>Member Functions</H3></A>

<A NAME="idx1112"></A><PRE>value_type&amp; 
<B>back</B>();</PRE>
<UL>
<P>Returns a reference to the item at the back of the queue (the last item pushed into the queue).</P>
</UL>


<A NAME="idx1113"></A><PRE>const value_type&amp; 
<B>back</B>() const;</PRE>
<UL>
<P>Returns a constant reference to the item at the back of the queue as a <SAMP>const_value_type</SAMP>.</P>
</UL>


<A NAME="idx1114"></A><PRE>bool 
<B>empty</B>() const;</PRE>
<UL>
<P>Returns <SAMP>true</SAMP> if the queue is empty, otherwise <SAMP>false</SAMP>.</P>
</UL>


<A NAME="idx1115"></A><PRE>value_type&amp; 
<B>front</B>();</PRE>
<UL>
<P>Returns a reference to the item at the front of the queue.</P>
</UL>


<A NAME="idx1116"></A><PRE>const value_type&amp; 
<B>front</B>() const;</PRE>
<UL>
<P>Returns a constant reference to the item at the front of the queue as a <SAMP>const_value_type</SAMP>.</P>
</UL>


<A NAME="idx1117"></A><PRE>void 
<B>pop</B>();</PRE>
<UL>
<P>Removes the item at the front of the queue.</P>
</UL>


<A NAME="idx1118"></A><PRE>void 
<B>push</B>(const value_type&amp; x);</PRE>
<UL>
<P>Pushes <SAMP>x</SAMP> onto the back of the queue.</P>
</UL>


<A NAME="idx1119"></A><PRE>size_type 
<B>size</B>() const;</PRE>
<UL>
<P>Returns the number of elements on the queue.</P>
</UL>

<A NAME="sec8"><H3>Nonmember Operators</H3></A>

<A NAME="idx1120"></A><PRE>template &lt;class T, class Container&gt;
  bool <B>operator==</B>(const queue&lt;T, Container&gt;&amp; x,
                   const queue&lt;T, Container&gt;&amp; y);</PRE>
<UL>
<P>   Returns <SAMP>true</SAMP> if <SAMP>x</SAMP> is the same as <SAMP>y</SAMP>.</P>
</UL>


<A NAME="idx1121"></A><PRE>template &lt;class T, class Container&gt;
  bool <B>operator!=</B>(const queue&lt;T, Container&gt;&amp; x,
                   const queue&lt;T, Container&gt;&amp; y);</PRE>
<UL>
<P>   Returns <SAMP>!(x==y)</SAMP>.</P>
</UL>


<A NAME="idx1122"></A><PRE>template &lt;class T, class Container&gt;
  bool <B>operator&lt;</B>(const queue&lt;T, Container&gt;&amp; x,
                  const queue&lt;T, Container&gt;&amp; y);</PRE>
<UL>
<P>Returns <SAMP>true</SAMP> if the queue defined by the elements contained in <SAMP>x</SAMP> is lexicographically less than the queue defined by the elements contained in <SAMP>y</SAMP>.</P>
</UL>


<A NAME="idx1123"></A><PRE>template &lt;class T, class Container&gt;
  bool <B>operator&gt;</B>(const queue&lt;T, Container&gt;&amp; x,
                  const queue&lt;T, Container&gt;&amp; y);</PRE>
<UL>
<P>Returns <SAMP>y &lt; x</SAMP>.</P>
</UL>


<A NAME="idx1124"></A><PRE>template &lt;class T, class Container&gt;
  bool <B>operator&lt;</B>(const queue&lt;T, Container&gt;&amp; x,
                  const queue&lt;T, Container&gt;&amp; y);</PRE>
<UL>
<P>Returns <SAMP>!(y &lt; x)</SAMP>.</P>
</UL>


<A NAME="idx1125"></A><PRE>template &lt;class T, class Container&gt;
  bool <B>operator&lt;</B>(const queue&lt;T, Container&gt;&amp; x,
                  const queue&lt;T, Container&gt;&amp; y);</PRE>
<UL>
<P>Returns <SAMP>!(x &lt; y)</SAMP>.</P>
</UL>

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

<UL><PRE>//
//  queue.cpp
//

#include &lt;deque&gt;      // for deque
#include &lt;iostream&gt;   // for cout, endl
#include &lt;list&gt;       // for list
#include &lt;queue&gt;      // for queue
#include &lt;string&gt;     // for string


int main ()
{
    typedef std::queue&lt;int, std::list&lt;int, 
                                      std::allocator&lt;int&gt; &gt; &gt;
            IQueue;

    // Make a queue using a deque container.
    IQueue q;

    // Push a couple of values on and retrieve them.
    q.push (1);
    q.push (2);

    std::cout &lt;&lt; q.front () &lt;&lt; std::endl;
    std::cout &lt;&lt; q.back () &lt;&lt; std::endl;

    typedef std::queue&lt;std::string, std::deque&lt;std::string,
                       std::allocator&lt;std::string&gt; &gt; &gt; SQueue;

    // Make a queue of strings using a deque container.
    SQueue qs;

    // Push on a few strings then pop them back off.
    for (int i = 0; i &lt; 10; i++) {
        qs.push (std::string (i + 1, 'a'));
        std::cout &lt;&lt; qs.front () &lt;&lt; std::endl;
    }

    for (int j = 0; j &lt; 10; j++) {
        std::cout &lt;&lt; qs.front () &lt;&lt; std::endl;
        qs.pop ();
    }

    // Return 0 if both containers are empty, 
    // a non-zero value otherwise.
    return !(2 == q.size () &amp;&amp; qs.empty ());
}


Program Output:
</PRE></UL>
<UL><PRE>1
2
a
a
a
a
a
a
a
a
a
a
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
</PRE></UL>
<A NAME="sec10"><H3>See Also</H3></A>
<P><B><I><A HREF="allocator.html">allocator</A></I></B>, <A HREF="containers.html">Containers</A>, <B><I><A HREF="priority-queue.html">priority_queue</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 23.2.3.1</I></P>

<BR>
<HR>
<A HREF="queue-h.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="randomaccessiterators.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>
