aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/libstdc++-v3/doc/xml/manual/containers.xml
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/libstdc++-v3/doc/xml/manual/containers.xml')
-rw-r--r--gcc-4.4.3/libstdc++-v3/doc/xml/manual/containers.xml450
1 files changed, 0 insertions, 450 deletions
diff --git a/gcc-4.4.3/libstdc++-v3/doc/xml/manual/containers.xml b/gcc-4.4.3/libstdc++-v3/doc/xml/manual/containers.xml
deleted file mode 100644
index 2b29ba6fc..000000000
--- a/gcc-4.4.3/libstdc++-v3/doc/xml/manual/containers.xml
+++ /dev/null
@@ -1,450 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
-[ ]>
-
-<part id="manual.containers" xreflabel="Containers">
-<?dbhtml filename="containers.html"?>
-
-<partinfo>
- <keywordset>
- <keyword>
- ISO C++
- </keyword>
- <keyword>
- library
- </keyword>
- </keywordset>
-</partinfo>
-
-<title>
- Containers
- <indexterm><primary>Containers</primary></indexterm>
-</title>
-
-<!-- Chapter 01 : Sequences -->
-<chapter id="manual.containers.sequences" xreflabel="Sequences">
-<?dbhtml filename="sequences.html"?>
- <title>Sequences</title>
-
-<sect1 id="containers.sequences.list" xreflabel="list">
-<?dbhtml filename="list.html"?>
- <title>list</title>
- <sect2 id="sequences.list.size" xreflabel="list::size() is O(n)">
- <title>list::size() is O(n)</title>
- <para>
- Yes it is, and that's okay. This is a decision that we preserved
- when we imported SGI's STL implementation. The following is
- quoted from <ulink
- url="http://www.sgi.com/tech/stl/FAQ.html">their FAQ</ulink>:
- </para>
- <blockquote>
- <para>
- The size() member function, for list and slist, takes time
- proportional to the number of elements in the list. This was a
- deliberate tradeoff. The only way to get a constant-time
- size() for linked lists would be to maintain an extra member
- variable containing the list's size. This would require taking
- extra time to update that variable (it would make splice() a
- linear time operation, for example), and it would also make the
- list larger. Many list algorithms don't require that extra
- word (algorithms that do require it might do better with
- vectors than with lists), and, when it is necessary to maintain
- an explicit size count, it's something that users can do
- themselves.
- </para>
- <para>
- This choice is permitted by the C++ standard. The standard says
- that size() <quote>should</quote> be constant time, and
- <quote>should</quote> does not mean the same thing as
- <quote>shall</quote>. This is the officially recommended ISO
- wording for saying that an implementation is supposed to do
- something unless there is a good reason not to.
- </para>
- <para>
- One implication of linear time size(): you should never write
- </para>
- <programlisting>
- if (L.size() == 0)
- ...
- </programlisting>
-
- <para>
- Instead, you should write
- </para>
-
- <programlisting>
- if (L.empty())
- ...
- </programlisting>
- </blockquote>
- </sect2>
-</sect1>
-
-<sect1 id="containers.sequences.vector" xreflabel="vector">
-<?dbhtml filename="vector.html"?>
- <title>vector</title>
- <para>
- </para>
- <sect2 id="sequences.vector.management" xreflabel="Space Overhead Management">
- <title>Space Overhead Management</title>
- <para>
- In <ulink
- url="http://gcc.gnu.org/ml/libstdc++/2002-04/msg00105.html">this
- message to the list</ulink>, Daniel Kostecky announced work on an
- alternate form of <code>std::vector</code> that would support
- hints on the number of elements to be over-allocated. The design
- was also described, along with possible implementation choices.
- </para>
- <para>
- The first two alpha releases were announced <ulink
- url="http://gcc.gnu.org/ml/libstdc++/2002-07/msg00048.html">here</ulink>
- and <ulink
- url="http://gcc.gnu.org/ml/libstdc++/2002-07/msg00111.html">here</ulink>.
- The releases themselves are available at
- <ulink url="http://www.kotelna.sk/dk/sw/caphint/">
- http://www.kotelna.sk/dk/sw/caphint/</ulink>.
- </para>
-
- </sect2></sect1>
-</chapter>
-
-<!-- Chapter 02 : Associative -->
-<chapter id="manual.containers.associative" xreflabel="Associative">
-<?dbhtml filename="associative.html"?>
- <title>Associative</title>
-
- <sect1 id="containers.associative.insert_hints" xreflabel="Insertion Hints">
- <title>Insertion Hints</title>
- <para>
- Section [23.1.2], Table 69, of the C++ standard lists this
- function for all of the associative containers (map, set, etc):
- </para>
- <programlisting>
- a.insert(p,t);
- </programlisting>
- <para>
- where 'p' is an iterator into the container 'a', and 't' is the
- item to insert. The standard says that <quote><code>t</code> is
- inserted as close as possible to the position just prior to
- <code>p</code>.</quote> (Library DR #233 addresses this topic,
- referring to <ulink
- url='http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html'>N1780</ulink>.
- Since version 4.2 GCC implements the resolution to DR 233, so
- that insertions happen as close as possible to the hint. For
- earlier releases the hint was only used as described below.
- </para>
- <para>
- Here we'll describe how the hinting works in the libstdc++
- implementation, and what you need to do in order to take
- advantage of it. (Insertions can change from logarithmic
- complexity to amortized constant time, if the hint is properly
- used.) Also, since the current implementation is based on the
- SGI STL one, these points may hold true for other library
- implementations also, since the HP/SGI code is used in a lot of
- places.
- </para>
- <para>
- In the following text, the phrases <emphasis>greater
- than</emphasis> and <emphasis>less than</emphasis> refer to the
- results of the strict weak ordering imposed on the container by
- its comparison object, which defaults to (basically)
- <quote>&lt;</quote>. Using those phrases is semantically sloppy,
- but I didn't want to get bogged down in syntax. I assume that if
- you are intelligent enough to use your own comparison objects,
- you are also intelligent enough to assign <quote>greater</quote>
- and <quote>lesser</quote> their new meanings in the next
- paragraph. *grin*
- </para>
- <para>
- If the <code>hint</code> parameter ('p' above) is equivalent to:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <code>begin()</code>, then the item being inserted should
- have a key less than all the other keys in the container.
- The item will be inserted at the beginning of the container,
- becoming the new entry at <code>begin()</code>.
- </para>
- </listitem>
- <listitem>
- <para>
- <code>end()</code>, then the item being inserted should have
- a key greater than all the other keys in the container. The
- item will be inserted at the end of the container, becoming
- the new entry at <code>end()</code>.
- </para>
- </listitem>
- <listitem>
- <para>
- neither <code>begin()</code> nor <code>end()</code>, then:
- Let <code>h</code> be the entry in the container pointed to
- by <code>hint</code>, that is, <code>h = *hint</code>. Then
- the item being inserted should have a key less than that of
- <code>h</code>, and greater than that of the item preceding
- <code>h</code>. The new item will be inserted between
- <code>h</code> and <code>h</code>'s predecessor.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- For <code>multimap</code> and <code>multiset</code>, the
- restrictions are slightly looser: <quote>greater than</quote>
- should be replaced by <quote>not less than</quote>and <quote>less
- than</quote> should be replaced by <quote>not greater
- than.</quote> (Why not replace greater with
- greater-than-or-equal-to? You probably could in your head, but
- the mathematicians will tell you that it isn't the same thing.)
- </para>
- <para>
- If the conditions are not met, then the hint is not used, and the
- insertion proceeds as if you had called <code> a.insert(t)
- </code> instead. (<emphasis>Note </emphasis> that GCC releases
- prior to 3.0.2 had a bug in the case with <code>hint ==
- begin()</code> for the <code>map</code> and <code>set</code>
- classes. You should not use a hint argument in those releases.)
- </para>
- <para>
- This behavior goes well with other containers'
- <code>insert()</code> functions which take an iterator: if used,
- the new item will be inserted before the iterator passed as an
- argument, same as the other containers.
- </para>
- <para>
- <emphasis>Note </emphasis> also that the hint in this
- implementation is a one-shot. The older insertion-with-hint
- routines check the immediately surrounding entries to ensure that
- the new item would in fact belong there. If the hint does not
- point to the correct place, then no further local searching is
- done; the search begins from scratch in logarithmic time.
- </para>
- </sect1>
-
-
- <sect1 id="containers.associative.bitset" xreflabel="bitset">
- <?dbhtml filename="bitset.html"?>
- <title>bitset</title>
- <sect2 id="associative.bitset.size_variable" xreflabel="Variable">
- <title>Size Variable</title>
- <para>
- No, you cannot write code of the form
- </para>
- <!-- Careful, the leading spaces in PRE show up directly. -->
- <programlisting>
- #include &lt;bitset&gt;
-
- void foo (size_t n)
- {
- std::bitset&lt;n&gt; bits;
- ....
- }
- </programlisting>
- <para>
- because <code>n</code> must be known at compile time. Your
- compiler is correct; it is not a bug. That's the way templates
- work. (Yes, it <emphasis>is</emphasis> a feature.)
- </para>
- <para>
- There are a couple of ways to handle this kind of thing. Please
- consider all of them before passing judgement. They include, in
- no particular order:
- </para>
- <itemizedlist>
- <listitem><para>A very large N in <code>bitset&lt;N&gt;</code>.</para></listitem>
- <listitem><para>A container&lt;bool&gt;.</para></listitem>
- <listitem><para>Extremely weird solutions.</para></listitem>
- </itemizedlist>
- <para>
- <emphasis>A very large N in
- <code>bitset&lt;N&gt;</code>.&nbsp;&nbsp;</emphasis> It has been
- pointed out a few times in newsgroups that N bits only takes up
- (N/8) bytes on most systems, and division by a factor of eight is
- pretty impressive when speaking of memory. Half a megabyte given
- over to a bitset (recall that there is zero space overhead for
- housekeeping info; it is known at compile time exactly how large
- the set is) will hold over four million bits. If you're using
- those bits as status flags (e.g.,
- <quote>changed</quote>/<quote>unchanged</quote> flags), that's a
- <emphasis>lot</emphasis> of state.
- </para>
- <para>
- You can then keep track of the <quote>maximum bit used</quote>
- during some testing runs on representative data, make note of how
- many of those bits really need to be there, and then reduce N to
- a smaller number. Leave some extra space, of course. (If you
- plan to write code like the incorrect example above, where the
- bitset is a local variable, then you may have to talk your
- compiler into allowing that much stack space; there may be zero
- space overhead, but it's all allocated inside the object.)
- </para>
- <para>
- <emphasis>A container&lt;bool&gt;.&nbsp;&nbsp;</emphasis> The
- Committee made provision for the space savings possible with that
- (N/8) usage previously mentioned, so that you don't have to do
- wasteful things like <code>Container&lt;char&gt;</code> or
- <code>Container&lt;short int&gt;</code>. Specifically,
- <code>vector&lt;bool&gt;</code> is required to be specialized for
- that space savings.
- </para>
- <para>
- The problem is that <code>vector&lt;bool&gt;</code> doesn't
- behave like a normal vector anymore. There have been recent
- journal articles which discuss the problems (the ones by Herb
- Sutter in the May and July/August 1999 issues of C++ Report cover
- it well). Future revisions of the ISO C++ Standard will change
- the requirement for <code>vector&lt;bool&gt;</code>
- specialization. In the meantime, <code>deque&lt;bool&gt;</code>
- is recommended (although its behavior is sane, you probably will
- not get the space savings, but the allocation scheme is different
- than that of vector).
- </para>
- <para>
- <emphasis>Extremely weird solutions.&nbsp;&nbsp;</emphasis> If
- you have access to the compiler and linker at runtime, you can do
- something insane, like figuring out just how many bits you need,
- then writing a temporary source code file. That file contains an
- instantiation of <code>bitset</code> for the required number of
- bits, inside some wrapper functions with unchanging signatures.
- Have your program then call the compiler on that file using
- Position Independent Code, then open the newly-created object
- file and load those wrapper functions. You'll have an
- instantiation of <code>bitset&lt;N&gt;</code> for the exact
- <code>N</code> that you need at the time. Don't forget to delete
- the temporary files. (Yes, this <emphasis>can</emphasis> be, and
- <emphasis>has been</emphasis>, done.)
- </para>
- <!-- I wonder if this next paragraph will get me in trouble... -->
- <para>
- This would be the approach of either a visionary genius or a
- raving lunatic, depending on your programming and management
- style. Probably the latter.
- </para>
- <para>
- Which of the above techniques you use, if any, are up to you and
- your intended application. Some time/space profiling is
- indicated if it really matters (don't just guess). And, if you
- manage to do anything along the lines of the third category, the
- author would love to hear from you...
- </para>
- <para>
- Also note that the implementation of bitset used in libstdc++ has
- <ulink url="../ext/sgiexts.html#ch23">some extensions</ulink>.
- </para>
-
- </sect2>
- <sect2 id="associative.bitset.type_string" xreflabel="Type String">
- <title>Type String</title>
- <para>
- </para>
- <para>
- Bitmasks do not take char* nor const char* arguments in their
- constructors. This is something of an accident, but you can read
- about the problem: follow the library's <quote>Links</quote> from
- the homepage, and from the C++ information <quote>defect
- reflector</quote> link, select the library issues list. Issue
- number 116 describes the problem.
- </para>
- <para>
- For now you can simply make a temporary string object using the
- constructor expression:
- </para>
- <programlisting>
- std::bitset&lt;5&gt; b ( std::string(<quote>10110</quote>) );
- </programlisting>
-
- <para>
- instead of
- </para>
-
- <programlisting>
- std::bitset&lt;5&gt; b ( <quote>10110</quote> ); // invalid
- </programlisting>
- </sect2>
- </sect1>
-
-</chapter>
-
-<!-- Chapter 03 : Interacting with C -->
-<chapter id="manual.containers.c" xreflabel="Interacting with C">
-<?dbhtml filename="containers_and_c.html"?>
- <title>Interacting with C</title>
-
- <sect1 id="containers.c.vs_array" xreflabel="Containers vs. Arrays">
- <title>Containers vs. Arrays</title>
- <para>
- You're writing some code and can't decide whether to use builtin
- arrays or some kind of container. There are compelling reasons
- to use one of the container classes, but you're afraid that
- you'll eventually run into difficulties, change everything back
- to arrays, and then have to change all the code that uses those
- data types to keep up with the change.
- </para>
- <para>
- If your code makes use of the standard algorithms, this isn't as
- scary as it sounds. The algorithms don't know, nor care, about
- the kind of <quote>container</quote> on which they work, since
- the algorithms are only given endpoints to work with. For the
- container classes, these are iterators (usually
- <code>begin()</code> and <code>end()</code>, but not always).
- For builtin arrays, these are the address of the first element
- and the <ulink
- url="../24_iterators/howto.html#2">past-the-end</ulink> element.
- </para>
- <para>
- Some very simple wrapper functions can hide all of that from the
- rest of the code. For example, a pair of functions called
- <code>beginof</code> can be written, one that takes an array,
- another that takes a vector. The first returns a pointer to the
- first element, and the second returns the vector's
- <code>begin()</code> iterator.
- </para>
- <para>
- The functions should be made template functions, and should also
- be declared inline. As pointed out in the comments in the code
- below, this can lead to <code>beginof</code> being optimized out
- of existence, so you pay absolutely nothing in terms of increased
- code size or execution time.
- </para>
- <para>
- The result is that if all your algorithm calls look like
- </para>
- <programlisting>
- std::transform(beginof(foo), endof(foo), beginof(foo), SomeFunction);
- </programlisting>
- <para>
- then the type of foo can change from an array of ints to a vector
- of ints to a deque of ints and back again, without ever changing
- any client code.
- </para>
- <para>
- This author has a collection of such functions, called
- <quote>*of</quote> because they all extend the builtin
- <quote>sizeof</quote>. It started with some Usenet discussions
- on a transparent way to find the length of an array. A
- simplified and much-reduced version for easier reading is <ulink
- url="wrappers_h.txt">given here</ulink>.
- </para>
- <para>
- Astute readers will notice two things at once: first, that the
- container class is still a <code>vector&lt;T&gt;</code> instead
- of a more general <code>Container&lt;T&gt;</code>. This would
- mean that three functions for <code>deque</code> would have to be
- added, another three for <code>list</code>, and so on. This is
- due to problems with getting template resolution correct; I find
- it easier just to give the extra three lines and avoid confusion.
- </para>
- <para>
- Second, the line
- </para>
- <programlisting>
- inline unsigned int lengthof (T (&amp;)[sz]) { return sz; }
- </programlisting>
- <para>
- looks just weird! Hint: unused parameters can be left nameless.
- </para>
- </sect1>
-
-</chapter>
-
-</part>