<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<style>BODY, P, DIV, H1, H2, H3, H4, H5, H6, ADDRESS, OL, UL, LI, TITLE, TD, OPTION, SELECT 
{ 
 font-family: Verdana 
}
BODY, P, DIV, ADDRESS, OL, UL, LI, TITLE, TD, OPTION, SELECT  
{  
  font-size: 10.0pt; 
  margin-top:0pt;  
  margin-bottom:0pt;  
} 
BODY, P
{
  margin-left:0pt; 
  margin-right:0pt;
}
BODY
{
  background: white;
  margin: 6px;
  padding: 0px;
}
h6 { font-size: 10pt }
h5 { font-size: 11pt }
h4 { font-size: 12pt }
h3 { font-size: 13pt }
h2 { font-size: 14pt }
h1 { font-size: 16pt }
blockquote { padding: 10px; border: 1px #DDDDDD dashed }
a img {	border: 0; }
table.zeroBorder {
	border-width: 1px 1px 1px 1px;
	border-style: dotted dotted dotted dotted;
	border-color: gray gray gray gray;
}
table.zeroBorder th {
	border-width: 1px 1px 1px 1px;
	border-style: dotted dotted dotted dotted;
	border-color: gray gray gray gray;
}
table.zeroBorder td {
	border-width: 1px 1px 1px 1px;
	border-style: dotted dotted dotted dotted;
	border-color: gray gray gray gray;
}
.hiddenStyle {
		visibility: hidden; 
		position: absolute;
		z-Index: 1;
		paddingRight: 0;
		background: white
	}
.misspell { background-image: url('/images/misspell.gif'); background-repeat: repeat-x; background-position: bottom }
@media screen {
.pb { border-top: 1px dashed #C0C0C0; border-bottom: 1px dashed #C0C0C0 }
.writely-comment { font-size: 9pt; line-height: 1.4em; padding: 1px; border: 1px dashed #C0C0C0 }
}
@media print {
.pb { border-top: 0px; border-bottom: 0px }
.writely-comment { display: none }
}
@media screen,print {
.pb { height: 1px }
}
</style></head>
<body revision='ddd5crnh_18fxn8f7:479'>
<div style=MARGIN-LEFT:80px>
  Doc no: N2231=07-0091<br>
  Reply to: Matt Austern &lt;austern@google.com&gt;<br>
  Date: 2007-03-19<br>
</div>
<br>
<h1 style=TEXT-ALIGN:center>
  STL singly linked lists
</h1>
<br>
The standard <span style="FONT-FAMILY:Comic Sans MS"></span>container class
<span style="FONT-FAMILY:Courier New">list</span> is a doubly linked list. It
provides bidirectional iterators, and the obvious implementation is a collection
of list nodes each of which contains a pointer to both the following and the
preceding node. Doubly linked lists are more flexible than singly linked lists,
but they also have higher overhead in both space and time. In practice, many
programs don't need the flexibility of doubly linked lists; singly linked lists
are the primary data structure in many functional languages, and structs that
are essentially hand-written singly linked list nodes are a common pattern for C
APIs.<br>
<br>
There is extensive experience with STL singly linked lists classes. Many C++
standard library implementations provide an
<span style="FONT-FAMILY:Courier New">slist</span> class as an extension; it's
similar to <span style="FONT-FAMILY:Courier New">list</span>, but it has forward
iterators instead of bidirectional. The SGI, Dinkumware, and Metrowerks
libraries all include <span style="FONT-FAMILY:Courier New">slist</span>. This
proposal is a subset of the SGI version. (And hence a subset of the GNU version,
which is descended from the SGI.)<br>
<br>
This proposal is a pure extension. It does not propose any changes to the list
class, or to the sequence concepts. A future proposal might reasonably introduce
new concepts for node-based containers, and might implement algorithms in terms
of node-based concepts.<br>
<h2>
  Design decisions
</h2>
Except where there is reason to differ,
<span style="FONT-FAMILY:Courier New">slist</span> is modeled on
<span style="FONT-FAMILY:Courier New">list</span>.<br>
<br>
Since singly linked lists have strictly less functionality than doubly linked
lists, the only reason to include them in the library is performance. It's
important to notice, furthermore, that this isn't a matter of asymptotic
complexity, but a matter of bytes and cycles. Inserting a new node is
<span style=FONT-STYLE:italic>O(1)</span> in either a singly linked list or a
doubly linked list, but in a singly linked list it's faster. This fact
influences most of the design decisions in this proposal.<br>
<h3>
  Insert-before versus insert-after
</h3>
There is one fundamental design decision that can be expressed in several
different ways. From the point of view of the standard it is most naturally
expressed as a question about the complexity of certain container operations,
such as insert and erase, but it is more illuminating to think about this
decision in terms of the implementation.<br>
<br>
Consider a typical C singly-linked list node, such as this example from libxml2:<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">typedef struct _xmlEnumeration
  xmlEnumeration;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">struct _xmlEnumeration
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; struct
  _xmlEnumeration&nbsp;&nbsp; *next;&nbsp;&nbsp;&nbsp;&nbsp; /* next one
  */</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; const
  xmlChar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  *name;&nbsp;&nbsp;&nbsp;&nbsp; /* Enumeration name
  */</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">};</span><br>
</div>
A list would just be represented as a pointer to the first list node, an
<span style="FONT-FAMILY:Courier New">xmlEnumeration*</span>. An "iterator",
i.e. a way of referring to a particular list element, would also just be a
pointer to some list node. Traversing the list is a loop with a skeleton of this
form:<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">while (p != 0)
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  ...</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; p =
  p-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">}</span><br>
</div>
Inserting a new element into such a list is equally straightforward: create a
new node, and fix up pointers:<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">xmlEnumeration *new =
  malloc(sizeof(xmlEnumeration));</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">new-&gt;name =
  strdup(name);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">new-&gt;next =
  p-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">p-&gt;next = new;</span><br>
</div>
Note that the new node is inserted <span style=FONT-STYLE:italic>after</span>
<span style="FONT-FAMILY:Courier New">p</span>, not before. This is unavoidable
given the definition of
<span style="FONT-FAMILY:Courier New">xmlEnumeration</span>, since there is no
way to find the node whose <span style="FONT-FAMILY:Courier New">next</span>
pointer points to <span style="FONT-FAMILY:Courier New">p</span>.<br>
<br>
It's easy to translate this general idea into a C++ class. The core of such a
list class might be written something like this:<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">struct list_node_base
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_node_base() : next(0) {
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_node_base*
  next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">};</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">template &lt;typename
  Value&gt;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">struct list_node : public list_node_base
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_node(const Value&amp; v) :
  list_node_base(), val(v) { }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; Value
  val;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">};</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">template &lt;typename
  Value&gt;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">struct list_iterator
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef Value
  value_type;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef Value*
  pointer;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef Value&amp;
  reference;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef ptrdiff_t
  difference_type;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef std::forward_iterator_tag
  iterator_category;</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_iterator(list_node_base* n)
  : node(n) { }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; value_type&amp; operator*() const
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return
  static_cast&lt;list_node&lt;value_type&gt;*&gt;(node)-&gt;val;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_iterator&amp; operator++() {
  node = node-&gt;next; return *this;
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_iterator operator++(int)
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; list_iterator
  tmp(*this); ++*this; return tmp;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; bool operator==(const
  list_iterator&lt;value_type&gt;&amp; x) const
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return node ==
  x.node;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; bool operator!=(const
  list_iterator&lt;value_type&gt;&amp; x) const
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return node !=
  x.node;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_node_base*
  node;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">};</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">template &lt;typename
  Value&gt;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">class slist
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">private:</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef list_node&lt;Value&gt;
  Node;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; list_node_base
  head;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">public:</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; slist() { head.next = 0;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; slist(const slist&amp; x) :
  head() {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; const list_node_base*
  from = &amp;x.head;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; list_node_base* to =
  &amp;this-&gt;head;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; while (from-&gt;next
  != 0) {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const
  Node* nextf =
  static_cast&lt;Node*&gt;(from-&gt;next);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  to-&gt;next = new Node(*nextf);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from =
  from-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to =
  to-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; slist&lt;Value&gt;&amp;
  operator=(const slist&amp; x) {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; if (&amp;x != this)
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  slist&lt;Value&gt; tmp(x);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  this-&gt;swap(tmp);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return
  *this;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; ~slist()
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; list_node_base* p =
  head.next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; while (p != 0)
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node* tmp
  = static_cast&lt;Node*&gt;(p);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p =
  p-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete
  tmp;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; void swap(slist&lt;Value&gt;&amp;
  x) { std::swap(this-&gt;head.next, x.head.next);
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">public:</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; typedef
  list_iterator&lt;Value&gt;
  iterator;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; iterator begin() { return
  iterator(head.next); }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; iterator end() { return
  iterator(0); }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; iterator before_begin() { return
  iterator(&amp;head); }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">public:</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; iterator insert_after(iterator i,
  const Value&amp; x) {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; Node* p = new
  Node(x);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; p-&gt;next =
  i.node-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; i.node-&gt;next =
  p;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return
  iterator(p);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; iterator erase_after(iterator i)
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; Node* p =
  static_cast&lt;Node*&gt;(i.node-&gt;next);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; i.node-&gt;next =
  p-&gt;next;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; delete
  *p;</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return
  iterator(i.node-&gt;next);</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;
  }</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">};</span><br>
</div>
<br>
In some respects this is an ordinary STL container with an ordinary iterator
interface, but in other respects it is highly nontraditional. It differs from
<span style="FONT-FAMILY:Courier New">std::list</span> more than one might have
expected at first sight. While
<span style="FONT-FAMILY:Courier New">std::list</span> provides
<span style=FONT-STYLE:italic>O(1)</span>
<span style="FONT-FAMILY:Courier New">insert(i)</span>, which inserts an element
before <span style="FONT-FAMILY:Courier New">i</span>, and
<span style="FONT-FAMILY:Courier New">erase(i)</span>, which deletes the element
that <span style="FONT-FAMILY:Courier New">i</span> points to, this class
instead provides <span style=FONT-STYLE:italic>O(1)</span>
<span style="FONT-FAMILY:Courier New">insert_after</span> and
<span style="FONT-FAMILY:Courier New">erase_after</span>. If we wanted to
provide the more traditional versions in this design, they would have to be
<span style=FONT-STYLE:italic>O(N)</span>: essentially, they would take an
iterator argument, search for the preceding list node, and and then call
<span style="FONT-FAMILY:Courier New">insert_after</span> or
<span style="FONT-FAMILY:Courier New">erase_after</span>. (Or, of course, if we
didn't provide <span style="FONT-FAMILY:Courier New">insert</span> and
<span style="FONT-FAMILY:Courier New">erase</span>, it would be easy for users
to write their own functions that do exactly the same thing.) This is directly
analogous to the use model of C-style singly linked lists like
<span style="FONT-FAMILY:Courier New">xmlEnumeration</span>.<br>
<br>
These restrictions aren't inevitable. It is perfectly possible to write an slist
with <span style=FONT-STYLE:italic>O(1)</span>
<span style="FONT-FAMILY:Courier New">insert</span> and
<span style="FONT-FAMILY:Courier New">erase</span>, at the cost of making
iterators slightly more complicated. The general idea is quite simple: the
iterator points to a node <span style=FONT-STYLE:italic>before</span> the one it
conceptually refers to. For example, the
<span style="FONT-FAMILY:Courier New">operator*</span> above could be replaced
by the following definition:<br>
<span style="FONT-FAMILY:Courier New">&nbsp; value_type&amp; operator*() const
{</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; return
static_cast&lt;list_node&lt;value_type&gt;*&gt;(node-&gt;next)-&gt;val;</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">&nbsp; }</span><br>
This permits "insert-before" semantics because in low-level implementation terms
<span style="FONT-FAMILY:Courier New">insert(i, x)</span> would insert the new
list node<span style="FONT-FAMILY:Courier New"></span> after
<span style="FONT-FAMILY:Courier New">i.node</span>, but from the user's view it
would insert the new element before the element referred to by
<span style="FONT-FAMILY:Courier New">*i</span>. One consequence is that
<span style="FONT-FAMILY:Courier New">end()</span> must become slightly more
complicated. Conceptually a past-the-end iterator points to a nonexistent
element, which in these terms would mean that
<span style="FONT-FAMILY:Courier New">end().node-&gt;next</span>, as opposed to
just <span style="FONT-FAMILY:Courier New">end().node</span>, is a null pointer,
and <span style="FONT-FAMILY:Courier New">end().node</span> is the last node in
the list. In this design, then,
<span style="FONT-FAMILY:Courier New">slist</span> will have to have two member
variables instead of one: it still needs
<span style="FONT-FAMILY:Courier New">head</span>, but it also needs a
<span style="FONT-FAMILY:Courier New">last_node</span> member variable so that
<span style="FONT-FAMILY:Courier New">end()</span> can return a node whose
<span style="FONT-FAMILY:Courier New">next</span> pointer is null. Finally,
<span style="FONT-FAMILY:Courier New">insert</span> and
<span style="FONT-FAMILY:Courier New">erase</span> also have to become slightly
more complicated to maintain the invariant that
<span style="FONT-FAMILY:Courier New">last_node</span> is always the last node
in the list.<br>
<br>
We thus have two different designs, which can be characterized from an
implementation or a user point of view:<br>
<ul>
  <li>
    Does an iterator point to the list node of the element it refers to, or to
    the preceding list node?
  </li>
  <li>
    Is a past-the-end iterator represented as a null pointer, or as a pointer to
    the last list node?
  </li>
  <li>
    Does an slist object contain a single pointer, the list head, or does it
    contain both a head pointer and a tail pointer?
  </li>
  <li>
    Are the traditional STL definitions of insert and erase
    <span style=FONT-STYLE:italic>O(1)</span>, or do programmers need to use
    insert-after and erase-after if they want O(1) operations?
  </li>
</ul>
This is the most important design choice for a singly-linked list proposal.<br>
<br>
This proposal chooses the version in which an iterator points to the list node
of the element it refers to, instead of the preceding node. The main
disadvantage of that design is that programmers have to use
<span style="FONT-FAMILY:Courier New">insert_after</span> and
<span style="FONT-FAMILY:Courier New">erase_after</span> instead of the more
familiar <span style="FONT-FAMILY:Courier New">insert</span> and
<span style="FONT-FAMILY:Courier New">erase</span>. The advantage, however, is
that all other operations are more efficient: iterator dereference is a single
pointer dereference, and the <span style="FONT-FAMILY:Courier New">slist</span>
object itself doesn't need to use a second word to store a tail pointer.
Admittedly these performance issues are small: they involve changes in small
constant factors, not changes of asymptotic complexity. I still consider them
important, however, because those constant factors are the only reason for using
<span style="FONT-FAMILY:Courier New">slist</span> instead of
<span style="FONT-FAMILY:Courier New">std::list</span> in the first place. The
main design goal for this proposal is that
<span style="FONT-FAMILY:Courier New">slist</span> should have zero overhead
relative to a hand-written C-style linked list like
<span style=FONT-FAMILY:Verdana><span style="FONT-FAMILY:Courier New">xmlEnumeration</span>,
and a design in which iterators point to the preceding list node does not
satisfy that goal. Long experience shows that for some uses the restrictions of
C-style or lisp-style singly linked lists are not onerous. For other uses,
<span style="FONT-FAMILY:Courier New">std::list</span> is still available.<br>
<br>
A smaller question: should we provide <span style=FONT-STYLE:italic>O(N)</span>
insert and erase, or omit those operations entirely? I have chosen the latter,
because providing operations with the same names as those in
<span style="FONT-FAMILY:Courier New">std::list,</span> but with much worse
performance, would invite bugs. It's also the more conservative choice, because
it's always easier to add features at a later date than to remove them. One
consequence of this fact is that
<span style="FONT-FAMILY:Courier New">slist</span> will not satisfy the Sequence
requirements of Table 67.<br style=FONT-FAMILY:Verdana>
</span><span style="FONT-WEIGHT:bold; FONT-FAMILY:Verdana"></span>
<h3>
  Size
</h3>
The only way to calculate the size of a singly linked list is to walk through
it, which is an <span style=FONT-STYLE:italic>O(N)</span> operation. All
existing STL containers have a
<span style="FONT-FAMILY:Courier New">size()</span> member function, and indeed
this is part of the container requirements of Table 65. We have three choices
for <span style="FONT-FAMILY:Courier New">slist::size()</span>:<br>
<ol>
  <li>
    Provide an <span style=FONT-STYLE:italic>O(N)</span>
    <span style="FONT-FAMILY:Courier New">slist::size()</span>, essentially
    equivalent to std::distance(begin(), end())
  </li>
  <li>
    Provide an <span style=FONT-STYLE:italic>O(1)</span>
    <span style="FONT-FAMILY:Courier New">slist::size()</span>, where the
    container keeps the node count as a separate member variable that it updates
    whenever nodes are added or destroyed.
  </li>
  <li>
    Don't provide <span style="FONT-FAMILY:Courier New">slist::size()</span> at
    all.
  </li>
</ol>
<br>
I have chosen the third option.<br>
<br>
Option 3 is superior to Option 1 because experience has shown that users find an
<span style=FONT-STYLE:italic>O(N)</span>
<span style="FONT-FAMILY:Courier New">size</span> surprising. Users expect such
a simple member function to be fast; it's too tempting to write code like<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">if (l.size() &gt; 1) { ... }</span><br>
</div>
and so an <span style=FONT-STYLE:italic>O(N)</span>
<span style="FONT-FAMILY:Courier New">size</span> invites serious performance
bugs. Since users can already get the effect of an
<span style=FONT-STYLE:italic>O(N)</span>
<span style="FONT-FAMILY:Courier New">size</span> by writing
<span style="FONT-FAMILY:Courier New">std:distance(l.begin(), l.end())</span>,
leaving it out doesn't decrease
<span style="FONT-FAMILY:Courier New">slist</span>'s functionality. This does
mean that we will have an STL container that doesn't satisfy the Container
requirements of table 65, but we already have precedent for that: the unordered
associative containers don't satisfy all of those requirements either. It seems
more important to have a useful set of container member functions than to worry
about strict conformance to this interface.<br>
<br>
The choice between Option 3 and Option 2 is more a matter of judgment. I have
chosen Option 3 for the same reason that I chose insert-after instead of
insert-before: Option 3 is more consistent with the goal of zero overhead
compared to a hand-written C-style linked list. Maintaining a count doubles the
size of an <span style="FONT-FAMILY:Courier New">slist</span> object (one word
for the list head and one for the count), and it slows down every operation that
changes the number of nodes. In most cases this isn't a change in asymptotic
complexity (the one change in asymptotic complexity is is one of the forms of
<span style="FONT-FAMILY:Courier New">splice</span>), but it is nonzero
overhead. It's a cost that all users would have to pay for, whether they need
this feature or not, and, for users who care about maintaining a count, it's
just as easy to maintain it outside the list, by incrementing the count with
every insert and decrementing it with every erase, as it is to maintain the
count within the list.<br>
<h3>
  Node-based algorithms
</h3>
The standard list class includes a number of special functions that are
reminiscent of STL algorithms, including
<span style="FONT-FAMILY:Courier New">remove</span>,
<span style="FONT-FAMILY:Courier New">unique</span>, and
<span style="FONT-FAMILY:Courier New">sort</span>. These member functions don't
duplicate the freestanding STL algorithms:
<span style="FONT-FAMILY:Courier New">std::remove</span> operates by copying
elements from one location in a sequence to another, while
<span style="FONT-FAMILY:Courier New">std::list::remove</span> operates on the
list's node structure itself. The freestanding
<span style="FONT-FAMILY:Courier New">std::remove</span> can't create and
destroy nodes, since it only knows about iterators, but
<span style="FONT-FAMILY:Courier New">list::remove</span> can.<br>
<br>
All of these algorithms can be implemented for singly-linked lists (Common Lisp
is an existence proof, as is the SGI
<span style="FONT-FAMILY:Courier New">slist</span>), and this proposal includes
all of them.<br>
<br>
This is not the only reasonable decision. An alternative would be to define a
framework for node-based algorithms (probably based on the notion of iterators
with the ability to mutate the next/previous relationship) and then pull out all
of these operations from both <span style="FONT-FAMILY:Courier New">list</span>
and <span style="FONT-FAMILY:Courier New">slist</span>, defining them as generic
algorithms for arbitrary node-based structures. That alternative would be
elegant, and would be consistent with the principles of generic programming. I
am not proposing it at this time for two related reasons. First, it would mean
that this proposal wouldn't be a pure extension—it would modify an existing
component, <span style="FONT-FAMILY:Courier New">list</span>. Second, generic
node-based algorithms are experimental, while an
<span style="FONT-FAMILY:Courier New">slist</span> with special algorithms is
existing practice.
<h2>
  Proposed wording
</h2>
Add the following class synopsis to section 23.2 [lib.sequences], and the rest
of the text as a new subsection of 23.2.<br>
<br>
<span style=FONT-WEIGHT:bold>Header &lt;slist&gt; synopsis</span><br>
<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">namespace std
  {</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator = allocator&lt;T&gt; &gt; class slist;
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator==(const
  slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator&lt;
  (const slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp;
  y); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator!=(const
  slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator&gt;
  (const slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp;
  y); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool
  operator&gt;=(const slist&lt;T,Allocator&gt;&amp; x, const
  slist&lt;T,Allocator&gt;&amp; y); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool
  operator&lt;=(const slist&lt;T,Allocator&gt;&amp; x, const
  slist&lt;T,Allocator&gt;&amp; y); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  swap(slist&lt;T,Allocator&gt;&amp; x, slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">}</span><br>
</div>
<br>
<span style=FONT-WEIGHT:bold>23.2.x Class template slist</span><br>
<br>
An <span style="FONT-FAMILY:Courier New">slist</span> is a container that
supports forward iterators and allows constant time insert and erase operations
anywhere within the sequence, with storage management handled automatically.
Fast random access to list elements is not supported.<br>
<br>
A <span style="FONT-FAMILY:Courier New">slist</span> satisfies all of the
requirements of a container (table 65), except that the
<span style="FONT-FAMILY:Courier New">size()</span> member function is not
provided. Descriptions are provided here only for operations on
<span style="FONT-FAMILY:Courier New">slist</span> that are not described in
that table or for operations where there is additional semantic information.<br>
<br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New">namespace std {
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator = allocator&lt;T&gt; &gt;
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; class slist {
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; public:
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // types:
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef typename
  Allocator::reference reference; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef typename
  Allocator::const_reference const_reference;
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef
  implementation_defined iterator;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // See
  23.1 </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef
  implementation_defined const_iterator; // See 23.1
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef
  implementation_defined size_type;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // See 23.1
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef
  implementation_defined difference_type;// See 23.1
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef T value_type;
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef Allocator
  allocator_type; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef typename
  Allocator::pointer pointer; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; typedef typename
  Allocator::const_pointer const_pointer;
  </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // 23.2.x.1
  construct/copy/destroy: </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; explicit slist(const
  Allocator&amp; = Allocator()); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; explicit
  slist(size_type n, const T&amp; value = T(),
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  const Allocator&amp; = Allocator());
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  InputIterator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  slist(InputIterator first, InputIterator last,
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  const Allocator&amp; = Allocator());
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; slist(const
  slist&lt;T,Allocator&gt;&amp;x); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; ~slist();
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;
  slist&lt;T,Allocator&gt;&amp; operator=(const slist&lt;T,Allocator&gt;&amp;x);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  InputIterator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void
  assign(InputIterator first, InputIterator last);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void assign(size_type
  n, const T&amp; t); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; allocator_type
  get_allocator() const; </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // 23.2.x.2
  iterators:<br>
  &nbsp;&nbsp;&nbsp; iterator before_begin();<br>
  &nbsp;&nbsp;&nbsp; const_iterator before_begin() const;<br style="FONT-FAMILY:Courier New">
  </span><span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; iterator
  begin(); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; const_iterator
  begin() const; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; iterator end();
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; const_iterator end()
  const; </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // capacity:
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool empty() const;
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; size_type max_size()
  const;
  </span><span style="FONT-FAMILY:Courier New"></span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // 23.2.x.3 element
  access: </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; reference front();
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; const_reference
  front() const; </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // 23.2.x.4
  modifiers: </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void push_front(const
  T&amp; x); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  pop_front();</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; iterator
  insert_after(iterator position, const T&amp; x);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  insert_after(iterator position, size_type n, const T&amp; x);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  InputIterator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void
  insert_after(iterator position, InputIterator first,
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  InputIterator last); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; iterator
  erase_after(iterator position); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; iterator
  erase_after(iterator position, iterator last);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  swap(slist&lt;T,Allocator&gt;&amp;);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void clear();
  </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; // 23.2.x.5 slist
  operations: </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  splice_after(iterator position, slist&lt;T,Allocator&gt;&amp; x);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  splice_after(iterator position, slist&lt;T,Allocator&gt;&amp; x, iterator i);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  splice_after(iterator position, slist&lt;T,Allocator&gt;&amp; x, iterator
  first, </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  iterator last); </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void remove(const
  T&amp; value); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  Predicate&gt; void remove_if(Predicate pred);
  </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void unique();
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  BinaryPredicate&gt; </span><span style="FONT-FAMILY:Courier New">void
  unique(BinaryPredicate binary_pred);
  </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  merge(slist&lt;T,Allocator&gt;&amp; x);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  Compare&gt; void merge(slist&lt;T,Allocator&gt;&amp; x, Compare comp);<br style="FONT-FAMILY:Courier New">
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void sort();
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; template &lt;class
  Compare&gt; void sort(Compare comp);
  </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void reverse();
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; };
  </span><br style="FONT-FAMILY:Courier New">
  <br>
  <span style="FONT-FAMILY:Courier New">&nbsp; // Comparison
  operators</span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator==(const
  slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; &nbsp; bool operator&lt; (const
  slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator!=(const
  slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool operator&gt;
  (const slist&lt;T,Allocator&gt;&amp; x, const slist&lt;T,Allocator&gt;&amp;
  y); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool
  operator&gt;=(const slist&lt;T,Allocator&gt;&amp; x, const
  slist&lt;T,Allocator&gt;&amp; y); </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; bool
  operator&lt;=(const slist&lt;T,Allocator&gt;&amp; x, const
  slist&lt;T,Allocator&gt;&amp; y); </span><br style="FONT-FAMILY:Courier New">
  <br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; // 23.2.x.6 specialized
  algorithms: </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp; template &lt;class T, class
  Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp; void
  swap(slist&lt;T,Allocator&gt;&amp; x, slist&lt;T,Allocator&gt;&amp; y);
  </span><br style="FONT-FAMILY:Courier New">
  <span style="FONT-FAMILY:Courier New">} </span><br>
</div>
<br>
<span style=FONT-WEIGHT:bold>3.2.x.1 slist constructors, copy, and
assignment</span><br>
&nbsp;<br>
<span style="FONT-FAMILY:Courier New">explicit slist(const Allocator&amp; =
Allocator()); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: Constructs an empty slist, using
  the specified allocator.<br>
  <span style=FONT-STYLE:italic>Complexity</span>: Constant.<br>
</div>
<br>
<span style="FONT-FAMILY:Courier New">explicit slist(size_type n, const T&amp;
value= T(), </span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp; &nbsp;&nbsp; const Allocator&amp; = Allocator()); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: Constructs an slist with n
  copies of value, using the specified allocator.<br>
  <span style=FONT-STYLE:italic>Complexity</span>: Linear in n.<br>
</div>
<br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">template &lt;class InputIterator&gt;
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">slist(InputIterator first, InputIterator
last, </span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const
Allocator&amp; = Allocator());</span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: Constructs an slist equal to the
  range [first,last).<br>
  <span style=FONT-STYLE:italic>Complexity</span>: Linear in distance(first,
  last)<br>
</div>
<br>
<span style="FONT-FAMILY:Courier New">template &lt;class InputIterator&gt;
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">void assign(InputIterator first,
InputIterator last); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: clear();
  insert_after(before_begin(), first, last);<br>
</div>
<br>
<span style="FONT-FAMILY:Courier New">void assign(size_type n, const T&amp; t);
</span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: clear();
  insert_after(before_begin(), n, t);<br>
</div>
<br>
<span style=FONT-WEIGHT:bold>23.2.x.2 slist iterators<br>
</span><br>
<span style="FONT-FAMILY:Courier New">iterator before_begin();</span><br>
<span style="FONT-FAMILY:Courier New">const_iterator before_begin()
const;</span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Returns</span>: A non-dereferenceable iterator
  that, when incremented, is equal to the iterator returned by begin().<br>
</div>
<br>
<span style=FONT-WEIGHT:bold>23.2.x.3 slist element access</span><br>
<br>
<span style="FONT-FAMILY:Courier New">reference front();
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">const_reference front() const;</span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Returns</span>: *begin().<br>
</div>
<br>
<span style=FONT-WEIGHT:bold>23.2.x.4 slist modifiers</span><br>
<br>
None of the overloads of insert_after shall affect the validity of iterators and
reference, and erase_after shall invalidate only the iterators and references to
the erased elements. If an exception is thrown during insert_after there shall
be no effect. Insertion of n elements into an slist is linear in n, and the
number of calls to the copy constructor of T is exactly equal to n. Erasing n
elements from an slist is linear time in n and the number of calls to the
destructor of type T is exactly equal to n.<br>
<br>
<span style="FONT-FAMILY:Courier New">void push_front(const T&amp; x);
</span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: insert_after(before_begin(), x);<br>
</div>
<br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">void pop_front();</span><br>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Effects</span>: erase_after(before_begin());<br>
</div>
<br>
<span style="FONT-FAMILY:Courier New">iterator insert_after(iterator position,
const T&amp; x); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  position is dereferenceable or equal to before_begin().</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Inserts a copy of x after
  position.</span></span><br style=FONT-FAMILY:Verdana>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Returns</span>:
  An iterator pointing to the copy of x.</span></span><br>
  <span style="FONT-FAMILY:Courier New"></span>
</div>
<span style="FONT-FAMILY:Courier New"><br style="FONT-FAMILY:Courier New">
</span><span style="FONT-FAMILY:Courier New">void insert_after(iterator
position, size_type n, const T&amp; x); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  position is dereferenceable or equal to before_begin().</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Inserts n copies of x after position.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br style="FONT-FAMILY:Courier New">
</span></span><span style="FONT-FAMILY:Courier New">template &lt;class
InputIterator&gt; </span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">void insert_after(iterator position,
InputIterator first, </span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
InputIterator last); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style=FONT-STYLE:italic>Requires</span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>:</span>
  position is dereferenceable or equal to before_begin().
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>first
  and last are not iterators in
  *this.</span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span><br style=FONT-FAMILY:Verdana>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Inserts copies of elements in [first, last) after position.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">iterator
erase_after(iterator position);</span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  The iterator following position is dereferenceable.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Erases the element pointed to by the iterator following
  position.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Returns</span>:
  An iterator pointing to the element following the one that was erased, or
  end() if no such element exists.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">iterator
erase_after(iterator position, iterator last);</span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  All iterators in the range (position, last) are
  dereferenceable.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Erases the elements in the range (position, last).</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Returns</span>:
  last</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void clear();</span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Erases all elements in the range [begin(), end()).</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
<span style=FONT-WEIGHT:bold>23.2.x.5 slist operations</span><br>
<br>
</span></span><span style="FONT-FAMILY:Courier New">void splice_after(iterator
position, slist&lt;T,Allocator&gt;&amp; x); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  position is dereferenceable or equal to before_begin(). &amp;x !=
  this.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Inserts the contents of x before position, and x becomes empty. Invalidates
  all iterators and references to x. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Throws</span>:
  nothing</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Complexity</span>:
  O(1)</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void splice_after(iterator
position, slist&lt;T,Allocator&gt;&amp; x, iterator i); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>position
  is dereferenceable or equal to before_begin(). The iterator following i is a
  dereferenceable iterator in x.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Inserts the element following i into *this, following position, and removes it
  from x. Invalidates only the iterators and references to the spliced
  elements.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Throws</span>:
  nothing</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>
  <span style=FONT-STYLE:italic>Complexity</span>: O(1)</span></span><br>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void splice_after(iterator
position, slist&lt;T,Allocator&gt;&amp; x, iterator first,
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iterator last); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>position
  is dereferenceable or equal to before_begin(). [first, last) is a valid range
  in x, and all iterators in the range (first, last) are dereferenceable.
  position is not an iterator in the range (first, last).</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Inserts elements in the range (first, last)after position and removes the
  elements from x.
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>Invalidates
  only the iterators and references to the spliced
  elements.</span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void remove(const T&amp;
value); </span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">template &lt;class Predicate&gt; void
remove_if(Predicate pred); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Erases all the elements in the list referred by a list iterator i for which
  the following conditions hold: *i == value, pred(*i) is true. This operation
  shall be stable: the relative order of the elements that are not removed is
  the same as their relative order in the original list.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Throws</span>:
  Nothing unless an exception is thrown by the equality comparison or the
  predicate.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Complexity</span>:
  Exactly distance(begin(), end()) applications of the corresponding predicate.
  </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void unique();
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">template &lt;class BinaryPredicate&gt;
void unique(BinaryPredicate binary_pred); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Eliminates all but the first element from every consecutive group of equal
  elements referred to by the iterator i in the range [first + 1, last) for
  which *i == *(i-1) (for the version of unique with no arguments) or pred(*i,
  *(i - 1)) (for the version of unique with a predicate argument) holds.
  </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Throws</span>:
  Nothing unless an exception in thrown by the equality comparison or the
  predicate. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Complexity</span>:
  If the range (last - first) is not empty, exactly (last - first) - 1
  applications of the corresponding predicate, otherwise no applications of the
  predicate. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void
merge(slist&lt;T,Allocator&gt;&amp; x);
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">template &lt;class Compare&gt; void
merge(slist&lt;T,Allocator&gt;&amp; x, Compare comp); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  comp defines a strict weak ordering (25.3), and *this and x are both sorted
  according to this ordering. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Merges x into *this. This operation shall be stable:
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>for
  equivalent elements in the two lists, the elements from *this shall always
  precede the elements from x. x is empty after the merge.
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana>If
  an exception is thrown other than by a comparison there are no effects.
  </span></span><span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Complexity</span>:
  At most size() + x.size() - 1 comparisons. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void sort();
</span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">template &lt;class Compare&gt; void
sort(Compare comp); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Requires</span>:
  operator&lt; (for the first version) or comp (for the second version) defines
  a strict weak ordering (25.3). </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Sorts the list according to the operator&lt;or a Compare function object. This
  operation shall be stable: the relative order of the equivalent elements is
  preserved. If an exception is thrown the order of the elements in *this is
  indeterminate. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Complexity</span>:
  Approximately NlogN comparisons, where N == distance(begin(), end()).
  </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
</span></span><span style="FONT-FAMILY:Courier New">void reverse();</span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  Reverses the order of the elements in the list. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Throws</span>:
  Nothing. </span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Complexity</span>:
  Linear time.</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><br>
<span style=FONT-WEIGHT:bold>23.2.x.6 slist specialized algorithms</span><br>
<br>
</span></span><span style="FONT-FAMILY:Courier New">template &lt;class T, class
Allocator&gt; </span><br style="FONT-FAMILY:Courier New">
<span style="FONT-FAMILY:Courier New">void swap(slist&lt;T,Allocator&gt;&amp; x,
slist&lt;T,Allocator&gt;&amp; y); </span><br>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div>
<div style=MARGIN-LEFT:40px>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana><span style=FONT-STYLE:italic>Effects</span>:
  x.swap(y)</span></span><br>
  <span style="FONT-FAMILY:Courier New"><span style=FONT-FAMILY:Verdana></span></span>
</div></body>
</html>