// .
fs.close();
fs.open("a_new_file");
- </pre><p>
+</pre><p>
All operations on the re-opened <code class="varname">fs</code> would fail, or at
least act very strangely, especially if <code class="varname">fs</code> reached the
EOF state on the previous file.
GLIBCXX_CHECK_HOST
GLIBCXX_TOPREL_CONFIGURE
GLIBCXX_CONFIGURE
- </pre><p>
+</pre><p>
All the major variable "discovery" is done here.
<code class="varname">CXX</code>, multilibs,
etc.
</p><pre class="programlisting">
fragments included from elsewhere
- </pre><p>
+</pre><p>
Right now, "fragments" == "the math/linkage bits".
</p><pre class="programlisting">
GLIBCXX_CHECK_COMPILER_FEATURES
function for all of the associative containers (map, set, etc):
</p><pre class="programlisting">
a.insert(p,t);
- </pre><p>
+</pre><p>
where 'p' is an iterator into the container 'a', and 't' is the
item to insert. The standard says that <span class="quote">“<span class="quote"><code class="code">t</code> is
inserted as close as possible to the position just prior to
std::bitset<n> bits;
....
}
- </pre><p>
+</pre><p>
because <code class="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 <span class="emphasis"><em>is</em></span> a feature.)
constructor expression:
</p><pre class="programlisting">
std::bitset<5> b ( std::string("10110") );
- </pre><p>
+</pre><p>
instead of
</p><pre class="programlisting">
std::bitset<5> b ( "10110" ); // invalid
- </pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="containers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="containers.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="unordered_associative.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 9.
+</pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="containers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="containers.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="unordered_associative.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 9.
Containers
</td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Unordered Associative</td></tr></table></div></body></html>
\ No newline at end of file
#endif
extension::hash_map<int,int> my_map;
- </pre><p>This is a bit cleaner than defining typedefs for all the
+</pre><p>This is a bit cleaner than defining typedefs for all the
instantiations you might need.
</p><p>The following autoconf tests check for working HP/SGI hash containers.
</p><pre class="programlisting">
The result is that if all your algorithm calls look like
</p><pre class="programlisting">
std::transform(beginof(foo), endof(foo), beginof(foo), SomeFunction);
- </pre><p>
+</pre><p>
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.
Second, the line
</p><pre class="programlisting">
inline unsigned int lengthof (T (&)[sz]) { return sz; }
- </pre><p>
+</pre><p>
looks just weird! Hint: unused parameters can be left nameless.
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="unordered_associative.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="containers.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="iterators.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Unordered Associative </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 10.
Iterators
int e;
DBID id; // some user-defined type
};
- </pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="termination.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="std_contents.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="errno.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Termination </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Use of errno by the library</td></tr></table></div></body></html>
\ No newline at end of file
+</pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="termination.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="std_contents.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="errno.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Termination </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Use of errno by the library</td></tr></table></div></body></html>
\ No newline at end of file
else
throw bad_alloc{};
}
- </pre><p>
+</pre><p>
This means you can influence what happens on allocation failure by
writing your own new-handler and then registering it with
<code class="function">std::set_new_handler</code>:
old_handler = set_new_handler (&my_new_handler);
...
}
- </pre><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.support.memory.notes"></a>Additional Notes</h3></div></div></div><p>
+</pre><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.support.memory.notes"></a>Additional Notes</h3></div></div></div><p>
Remember that it is perfectly okay to <code class="function">delete</code> a
null pointer! Nothing happens, by definition. That is not the
same thing as deleting a pointer twice.
bitset<N>& _Unchecked_reset (size_t pos);
bitset<N>& _Unchecked_flip (size_t pos);
bool _Unchecked_test (size_t pos);
- </pre><p>Note that these may in fact be removed in the future, although we have
+</pre><p>Note that these may in fact be removed in the future, although we have
no present plans to do so (and there doesn't seem to be any immediate
reason to).
</p><p>The member function <code class="code">operator[]</code> on a const bitset returns
std::cout << ti.name() << "\t=> " << realname << "\t: " << status << '\n';
std::free(realname);
}
- </pre><p>
+</pre><p>
This prints
</p><pre class="screen">
<code class="computeroutput">
<rope>
<slist>
<rb_tree>
- </pre><p>are all here;
+</pre><p>are all here;
<code class="filename"><backwards/hash_map></code> and
<code class="filename"><backwards/hash_set></code>
are deprecated but available as backwards-compatible extensions,
int sum = std::accumulate(ar,ar+50,0);
int sum_stuff = std::accumulate(ar,ar+50,someval);
int product = std::accumulate(ar,ar+50,1,std::multiplies<int>());
- </pre><p>The first call adds all the members of the array, using zero as an
+</pre><p>The first call adds all the members of the array, using zero as an
initial value for <code class="code">sum</code>. The second does the same, but uses
<code class="code">someval</code> as the starting value (thus, <code class="code">sum_stuff == sum +
someval</code>). The final call uses the second of the two signatures,
};
extern std::ostream& operator<< (std::ostream&, MyClass&);
- </pre><p><span class="emphasis"><em><code class="filename"><ios></code></em></span>
+</pre><p><span class="emphasis"><em><code class="filename"><ios></code></em></span>
declares the base classes for the entire I/O stream hierarchy,
<code class="classname">std::ios_base</code> and <code class="classname">std::basic_ios<charT></code>,
the counting types <span class="type">std::streamoff</span> and <span class="type">std::streamsize</span>,
{
return os << c.data1() << c.data2();
}
- </pre><p>The <span class="type">std::istream</span> and <span class="type">std::ostream</span> classes
+</pre><p>The <span class="type">std::istream</span> and <span class="type">std::ostream</span> classes
are the abstract parents of
the various concrete implementations. If you are only using the
interfaces, then you only need to use the appropriate interface header.
// this is explained below
<span class="emphasis"><em>static ios_base::Init __foo;</em></span> // not its real name
}
- </pre><p>Now, the runtime penalty mentioned previously: the global objects
+</pre><p>Now, the runtime penalty mentioned previously: the global objects
must be initialized before any of your own code uses them; this is
guaranteed by the standard. Like any other global object, they must
be initialized once and only once. This is typically done with a
std::cout << "Hel";
std::printf ("lo, worl");
std::cout << "d!\n";
- </pre><p>This must do what you think it does.
+</pre><p>This must do what you think it does.
</p><p>Alert members of the audience will immediately notice that buffering
is going to make a hash of the output unless special steps are taken.
</p><p>The special steps taken by libstdc++, at least for version 3.0,
#include <span class="emphasis"><em>any of the I/O headers such as ios, iostream, etc</em></span>
std::ios::sync_with_stdio(false);
- </pre><p>You must do this before performing any I/O via the C++ stream objects.
+</pre><p>You must do this before performing any I/O via the C++ stream objects.
Once you call this, the C++ streams will operate independently of the
(unused) C streams. For GCC 3.x, this means that <code class="code">cout</code> and
company will become fully buffered on their own.
| | dereference 'end'.
beginning end
- </pre><p>See? Everything between the boundary markers is chapter of the array.
+</pre><p>See? Everything between the boundary markers is chapter of the array.
Simple.
</p><p>Now think back to your junior-high school algebra course, when you
were learning how to draw graphs. Remember that a graph terminating
</p><pre class="programlisting">
T* allocate (size_type n, const void* hint = 0);
void deallocate (T* p, size_type n);
- </pre><p>
+</pre><p>
The <code class="varname">n</code> arguments in both those
functions is a <span class="emphasis"><em>count</em></span> of the number of
<span class="type">T</span>'s to allocate space for, <span class="emphasis"><em>not their
Likewise, a debugging form of whichever allocator is currently in use:
</p><pre class="programlisting">
std::deque <int, __gnu_cxx::debug_allocator<std::allocator<int> > > debug_deque;
- </pre></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="allocator.custom"></a>Custom Allocators</h4></div></div></div><p>
+</pre></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="allocator.custom"></a>Custom Allocators</h4></div></div></div><p>
Writing a portable C++ allocator would dictate that the interface
would look much like the one specified for
<code class="classname">allocator</code>. Additional member functions, but
function_taking_MyClass_pointer (ap.get());
}
- </pre><p>When an exception gets thrown, the instance of MyClass that's
+</pre><p>When an exception gets thrown, the instance of MyClass that's
been created on the heap will be <code class="function">delete</code>'d as the stack is
unwound past <code class="function">func()</code>.
</p><p>Changing that code as follows is not <acronym class="acronym">AP</acronym>-friendly:
</p><pre class="programlisting">
APMC ap (new MyClass[22]);
- </pre><p>You will get the same problems as you would without the use
+</pre><p>You will get the same problems as you would without the use
of <acronym class="acronym">AP</acronym>:
</p><pre class="programlisting">
char* array = new char[10]; // array new...
...
delete array; // ...but single-object delete
- </pre><p>
+</pre><p>
AP cannot tell whether the pointer you've passed at creation points
to one or many things. If it points to many things, you are about
to die. AP is trivial to write, however, so you could write your
{
My_Type (My_Type const&);
};
- </pre><p>
+</pre><p>
Note the const keyword; the object being copied shouldn't change.
The template class <code class="code">auto_ptr</code> (called AP here) does not
meet this requirement. Creating a new AP by copying an existing
{
std::vector< std::auto_ptr<int> > vec_ap_int;
}
- </pre><p>
+</pre><p>
Should you try this with the checks enabled, you will see an error.
</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.util.memory.shared_ptr"></a>shared_ptr</h3></div></div></div><p>
The shared_ptr class template stores a pointer, usually obtained via new,
with its respective default ctor. The other simple ctor,
</p><pre class="programlisting">
pair (const T1& x, const T2& y);
- </pre><p>does what you think it does, <code class="code">first</code> getting <code class="code">x</code>
+</pre><p>does what you think it does, <code class="code">first</code> getting <code class="code">x</code>
and <code class="code">second</code> getting <code class="code">y</code>.
</p><p>There is a constructor template for copying pairs of other types:
</p><pre class="programlisting">
template <class U, class V> pair (const pair<U,V>& p);
- </pre><p>The compiler will convert as necessary from U to T1 and from
+</pre><p>The compiler will convert as necessary from U to T1 and from
V to T2 in order to perform the respective initializations.
</p><p>The comparison operators are done for you. Equality
of two <code class="code">pair<T1,T2></code>s is defined as both <code class="code">first</code>
</p><pre class="programlisting">
x.first < y.first ||
( !(y.first < x.first) && x.second < y.second )
- </pre><p>The other operators are not defined using the <code class="code">rel_ops</code>
+</pre><p>The other operators are not defined using the <code class="code">rel_ops</code>
functions above, but their semantics are the same.
</p><p>Finally, there is a template function called <code class="function">make_pair</code>
that takes two references-to-const objects and returns an
instance of a pair instantiated on their respective types:
</p><pre class="programlisting">
pair<int,MyClass> p = make_pair(4,myobject);
- </pre></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="utilities.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="utilities.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="memory.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 6.
+</pre></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="utilities.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="utilities.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="memory.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 6.
Utilities
</td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Memory</td></tr></table></div></body></html>
\ No newline at end of file
{
...
}
- </pre><p>
+</pre><p>
then one needs to address the following questions in the body
of <code class="function">some_op_sequence</code>:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
make
make check
make install
- </pre><p>
+</pre><p>
Each step is described in more detail in the following sections.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="manual.intro.setup.prereq"></a>Prerequisites</h2></div></div></div><p>
Because libstdc++ is part of GCC, the primary source for
<< std::hex << 31 << std::endl;
return 0;
}
- </pre><p>Try it yourself! More examples can be found in 3.1.x code, in
+</pre><p>Try it yourself! More examples can be found in 3.1.x code, in
<code class="filename">include/ext/*_filebuf.h</code>, and in the article
<a class="link" href="http://gabisoft.free.fr/articles/fltrsbf1.html" target="_top">Filtering
Streambufs</a>
capital_s.resize(s.size());
std::transform (s.begin(), s.end(), capital_s.begin(), ToUpper());
}
- </pre><p>
+</pre><p>
<span class="emphasis"><em>Note</em></span> that these calls all
involve the global C locale through the use of the C functions
<code class="code">toupper</code>/<code class="code">tolower</code>.
</p><pre class="programlisting">
std::transform (s.begin(), s.end(), capital_s.begin(),
[](unsigned char c) { return std::tolower(c); });
- </pre><p>Another common operation is trimming off excess whitespace. Much
+</pre><p>Another common operation is trimming off excess whitespace. Much
like transformations, this task is trivial with the use of string's
<code class="code">find</code> family. These examples are broken into multiple
statements for readability:
to GCC 3.4 the following alternative can be used instead
</p><pre class="programlisting">
std::string(str.data(), str.size()).swap(str);
- </pre><p>This is similar to the idiom for reducing
+</pre><p>This is similar to the idiom for reducing
a <code class="code">vector</code>'s memory usage
(see <a class="link" href="../faq.html#faq.size_equals_capacity" title="7.8.">this FAQ
entry</a>) but the regular copy constructor cannot be used
If you replace CString with string in the above function, the
performance is O(n).
- </pre><p>Joe Buck also pointed out some other things to keep in mind when
+</pre><p>Joe Buck also pointed out some other things to keep in mind when
comparing CString and the Standard string class:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>CString permits access to its internal representation; coders
who exploited that may have problems moving to <code class="code">string</code>.
static const bool tinyness_before;
static const float_round_style round_style;
};
- </pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.support.types.null"></a>NULL</h3></div></div></div><p>
+</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="std.support.types.null"></a>NULL</h3></div></div></div><p>
The only change that might affect people is the type of
<code class="constant">NULL</code>: while it is required to be a macro,
the definition of that macro is <span class="emphasis"><em>not</em></span> allowed
<code class="filename"><cstdlib></code>, and call
</p><pre class="programlisting">
std::set_terminate(std::abort);
- </pre><p>
+</pre><p>
After this, all calls to <code class="function">terminate</code> will use
<code class="function">abort</code> as the terminate handler.
</p><p>
of the C++ standard (ISO 14882) are files within the following
directories:
- </p><pre class="programlisting">
+</p><pre class="programlisting">
17_intro
18_support
19_diagnostics
28_regex
29_atomics
30_threads
- </pre><p>
+</pre><p>
</p><p>
In addition, the following directories include test files:
This test case expects some kind of interactive input in order
to finish or pass. At the moment, the interactive tests are not
run by default. Instead, they are run by hand, like:
- <pre class="programlisting">
+<pre class="programlisting">
g++ 27_io/objects/char/3_xin.cc
cat 27_io/objects/char/3_xin.in | a.out</pre></dd><dt><span class="term"><code class="filename">.in</code></span></dt><dd>
This file contains the expected input for the corresponding <span class="emphasis"><em>
Also, here is an example of how to run the libstdc++ testsuite
for a multilibed build directory with different ABI settings:
- </p><pre class="programlisting">
+</p><pre class="programlisting">
make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board \"unix{-mabi=32,,-mabi=64}\"'
</pre><p>
</p><p>
run programs on, e.g. <code class="code">x86_64-pc-linux-gnu</code>, as a few tests
still execute the code they build. Here's an example of how to run the
testsuite with libstdc++ in freestanding mode:
- </p><pre class="programlisting">
+</p><pre class="programlisting">
make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board=unix/-ffreestanding'
- </pre><p>
+</pre><p>
</p><p>
You can run the tests with a compiler and library that have
already been installed. Make sure that the compiler (e.g.,
struct __is_fast_hash<hasher> : std::false_type
{ };
}
- </pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="associative.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="containers.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="containers_and_c.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Associative </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Interacting with C</td></tr></table></div></body></html>
\ No newline at end of file
+</pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="associative.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="containers.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="containers_and_c.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Associative </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Interacting with C</td></tr></table></div></body></html>
\ No newline at end of file
t1.join();
t2.join();
}
- </pre><p>For further details of the C++11 memory model see Hans-J. Boehm's
+</pre><p>For further details of the C++11 memory model see Hans-J. Boehm's
<a class="link" href="https://www.hboehm.info/c++mm/" target="_top">Threads
and memory model for C++</a> pages, particularly the <a class="link" href="https://www.hboehm.info/c++mm/threadsintro.html" target="_top">introduction</a>
and <a class="link" href="https://www.hboehm.info/c++mm/user-faq.html" target="_top">FAQ</a>.
Executing a sequence like this would fail:
</para>
- <programlisting>
+<programlisting>
#include <fstream>
...
std::fstream fs("a_file");
// .
fs.close();
fs.open("a_new_file");
- </programlisting>
+</programlisting>
<para>
All operations on the re-opened <varname>fs</varname> would fail, or at
typedefs, member functions, etc), but the two which concern us most
are:
</para>
- <programlisting>
+<programlisting>
T* allocate (size_type n, const void* hint = 0);
void deallocate (T* p, size_type n);
- </programlisting>
+</programlisting>
<para>
The <varname>n</varname> arguments in both those
(but non-portable) method of specifying that only <function>malloc</function> or <function>free</function>
should be used instead of the default node allocator is:
</para>
- <programlisting>
+<programlisting>
std::list <int, __gnu_cxx::malloc_allocator<int> > malloc_list;</programlisting>
<para>
Likewise, a debugging form of whichever allocator is currently in use:
</para>
- <programlisting>
+<programlisting>
std::deque <int, __gnu_cxx::debug_allocator<std::allocator<int> > > debug_deque;
- </programlisting>
+</programlisting>
</section>
<section xml:id="allocator.custom"><info><title>Custom Allocators</title></info>
presence of exceptions. That's <emphasis>all</emphasis>. This
code is AP-friendly:
</para>
- <programlisting>
+<programlisting>
// Not a recommend naming scheme, but good for web-based FAQs.
typedef std::auto_ptr<MyClass> APMC;
function_taking_MyClass_pointer (ap.get());
}
- </programlisting>
+</programlisting>
<para>When an exception gets thrown, the instance of MyClass that's
been created on the heap will be <function>delete</function>'d as the stack is
unwound past <function>func()</function>.
</para>
<para>Changing that code as follows is not <acronym>AP</acronym>-friendly:
</para>
- <programlisting>
+<programlisting>
APMC ap (new MyClass[22]);
- </programlisting>
+</programlisting>
<para>You will get the same problems as you would without the use
of <acronym>AP</acronym>:
</para>
- <programlisting>
+<programlisting>
char* array = new char[10]; // array new...
...
delete array; // ...but single-object delete
- </programlisting>
+</programlisting>
<para>
AP cannot tell whether the pointer you've passed at creation points
to one or many things. If it points to many things, you are about
described in the standard library require their contained types
to have, among other things, a copy constructor like this:
</para>
- <programlisting>
+<programlisting>
struct My_Type
{
My_Type (My_Type const&);
};
- </programlisting>
+</programlisting>
<para>
Note the const keyword; the object being copied shouldn't change.
The template class <code>auto_ptr</code> (called AP here) does not
in to this implementation will issue an error if you try to
compile code like this:
</para>
- <programlisting>
+<programlisting>
#include <vector>
#include <memory>
{
std::vector< std::auto_ptr<int> > vec_ap_int;
}
- </programlisting>
+</programlisting>
<para>
Should you try this with the checks enabled, you will see an error.
</para>
namespace. For maximum portability, consider defining a namespace
alias to use to talk about extensions, e.g.:
</para>
- <programlisting>
+<programlisting>
#ifdef __GNUC__
#if __GNUC__ < 3
#include <hash_map.h>
#endif
extension::hash_map<int,int> my_map;
- </programlisting>
+</programlisting>
<para>This is a bit cleaner than defining typedefs for all the
instantiations you might need.
</para>
we can arrange the contents however we like. As of this writing,
<filename>acinclude.m4</filename> is arranged as follows:
</para>
- <programlisting>
+<programlisting>
GLIBCXX_CHECK_HOST
GLIBCXX_TOPREL_CONFIGURE
GLIBCXX_CONFIGURE
- </programlisting>
+</programlisting>
<para>
All the major variable "discovery" is done here.
<varname>CXX</varname>, multilibs,
etc.
</para>
- <programlisting>
+<programlisting>
fragments included from elsewhere
- </programlisting>
+</programlisting>
<para>
Right now, "fragments" == "the math/linkage bits".
</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>
+<programlisting>
a.insert(p,t);
- </programlisting>
+</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
No, you cannot write code of the form
</para>
<!-- Careful, the leading spaces in PRE show up directly. -->
- <programlisting>
+<programlisting>
#include <bitset>
void foo (size_t n)
std::bitset<n> bits;
....
}
- </programlisting>
+</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
For now you can simply make a temporary string object using the
constructor expression:
</para>
- <programlisting>
+<programlisting>
std::bitset<5> b ( std::string("10110") );
- </programlisting>
+</programlisting>
<para>
instead of
</para>
- <programlisting>
+<programlisting>
std::bitset<5> b ( "10110" ); // invalid
- </programlisting>
+</programlisting>
</section>
</section>
cached.
The trait can be specialized for user-defined hash functions like so:
</para>
- <programlisting>
+<programlisting>
#include <unordered_set>
struct hasher
struct __is_fast_hash<hasher> : std::false_type
{ };
}
- </programlisting>
+</programlisting>
</section>
</section>
<para>
The result is that if all your algorithm calls look like
</para>
- <programlisting>
+<programlisting>
std::transform(beginof(foo), endof(foo), beginof(foo), SomeFunction);
- </programlisting>
+</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
<para>
Second, the line
</para>
- <programlisting>
+<programlisting>
inline unsigned int lengthof (T (&)[sz]) { return sz; }
- </programlisting>
+</programlisting>
<para>
looks just weird! Hint: unused parameters can be left nameless.
</para>
place). It's good to remember that you can add your own data to
these exceptions when extending the hierarchy:
</para>
- <programlisting>
+<programlisting>
struct My_Exception : public std::runtime_error
{
public:
int e;
DBID id; // some user-defined type
};
- </programlisting>
+</programlisting>
</section>
</section>
do no range-checking. If we call them member functions of an instantiation
of <code>bitset<N></code>, then their names and signatures are:
</para>
- <programlisting>
+<programlisting>
bitset<N>& _Unchecked_set (size_t pos);
bitset<N>& _Unchecked_set (size_t pos, int val);
bitset<N>& _Unchecked_reset (size_t pos);
bitset<N>& _Unchecked_flip (size_t pos);
bool _Unchecked_test (size_t pos);
- </programlisting>
+</programlisting>
<para>Note that these may in fact be removed in the future, although we have
no present plans to do so (and there doesn't seem to be any immediate
reason to).
the index of the first "on" bit, and the index of the first
"on" bit that is after <code>prev</code>, respectively:
</para>
- <programlisting>
+<programlisting>
size_t _Find_first() const;
size_t _Find_next (size_t prev) const;</programlisting>
<para>The same caveat given for the _Unchecked_* functions applies here also.
</para>
<para>The SGI headers</para>
- <programlisting>
+<programlisting>
<hash_map>
<hash_set>
<rope>
<slist>
<rb_tree>
- </programlisting>
+</programlisting>
<para>are all here;
<filename class="headerfile"><backwards/hash_map></filename> and
<filename class="headerfile"><backwards/hash_set></filename>
additional signatures return void, but take a final parameter by
reference to which they assign their results, e.g.,
</para>
- <programlisting>
+<programlisting>
void count (first, last, value, n);</programlisting>
<para>25.2 (mutating algorithms) is extended with two families of signatures,
random_sample and random_sample_n.
</para>
<para>25.2.1 (copy) is extended with
</para>
- <programlisting>
+<programlisting>
copy_n (_InputIter first, _Size count, _OutputIter result);</programlisting>
<para>which copies the first 'count' elements at 'first' into 'result'.
</para>
</itemizedlist>
<para>25.3.8 (lexicographical_compare) is extended with
</para>
- <programlisting>
+<programlisting>
lexicographical_compare_3way(_InputIter1 first1, _InputIter1 last1,
_InputIter2 first2, _InputIter2 last2)</programlisting>
<para>which does... what?
<para>26.4, the generalized numeric operations such as <code>accumulate</code>,
are extended with the following functions:
</para>
- <programlisting>
+<programlisting>
power (x, n);
power (x, n, monoid_operation);</programlisting>
<para>Returns, in FORTRAN syntax, "<code>x ** n</code>" where
That is, it assigns <code>value</code> to <code>*first</code>,
<code>value + 1</code> to<code> *(first + 1)</code> and so on."
</para>
- <programlisting>
+<programlisting>
void iota(_ForwardIter first, _ForwardIter last, _Tp value);</programlisting>
<para>The <code>iota</code> function is included in the ISO C++ 2011 standard.
</para>
Probably the only time you'll be interested in demangling at runtime
is when you're seeing <code>typeid</code> strings in RTTI. For example:
</para>
- <programlisting>
+<programlisting>
#include <iostream>
#include <cstdlib>
#include <cxxabi.h>
std::cout << ti.name() << "\t=> " << realname << "\t: " << status << '\n';
std::free(realname);
}
- </programlisting>
+</programlisting>
<para>
This prints
</para>
<para>The general outline of commands to build GCC is something like:
</para>
- <programlisting>
+<programlisting>
<replaceable>get gcc sources</replaceable>
<replaceable>extract into gccsrcdir</replaceable>
mkdir <replaceable>gccbuilddir</replaceable>
make
make check
make install
- </programlisting>
+</programlisting>
<para>
Each step is described in more detail in the following sections.
Look in the <filename class="headerfile"><iosfwd></filename> header
if you'd like to know why.) For example,
</para>
- <programlisting>
+<programlisting>
#include <iosfwd>
class MyClass
};
extern std::ostream& operator<< (std::ostream&, MyClass&);
- </programlisting>
+</programlisting>
<para><emphasis><filename class="headerfile"><ios></filename></emphasis>
declares the base classes for the entire I/O stream hierarchy,
<classname>std::ios_base</classname> and <classname>std::basic_ios<charT></classname>,
or any of the other abstract stream formatting functions.
For example,
</para>
- <programlisting>
+<programlisting>
#include <istream>
std::ostream& operator<< (std::ostream& os, MyClass& c)
{
return os << c.data1() << c.data2();
}
- </programlisting>
+</programlisting>
<para>The <type>std::istream</type> and <type>std::ostream</type> classes
are the abstract parents of
the various concrete implementations. If you are only using the
<filename class="headerfile"><ostream></filename>
headers, but nothing else. The contents of this header look like:
</para>
- <programlisting>
+<programlisting>
#include <ostream>
#include <istream>
// this is explained below
<emphasis>static ios_base::Init __foo;</emphasis> // not its real name
}
- </programlisting>
+</programlisting>
<para>Now, the runtime penalty mentioned previously: the global objects
must be initialized before any of your own code uses them; this is
guaranteed by the standard. Like any other global object, they must
assumes many things about the nature of the character type being
used (for more information, read the books or the newsgroups):
</para>
- <programlisting>
+<programlisting>
#include <iostream>
#include <streambuf>
#include <locale>
<< std::hex << 31 << std::endl;
return 0;
}
- </programlisting>
+</programlisting>
<para>Try it yourself! More examples can be found in 3.1.x code, in
<filename>include/ext/*_filebuf.h</filename>, and in the article
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gabisoft.free.fr/articles/fltrsbf1.html">Filtering
out as soon as possible, etc -- but the buffering is largely
wasted when doing this to a file:
</para>
- <programlisting>
+<programlisting>
output << "a line of text" << endl;
output << some_data_variable << endl;
output << "another line of text" << endl; </programlisting>
and let the libraries and the system worry about the buffering.
If you need a newline, just write a newline:
</para>
- <programlisting>
+<programlisting>
output << "a line of text\n"
<< some_data_variable << '\n'
<< "another line of text\n"; </programlisting>
<code>endl</code> if you also need a newline, or just flush the buffer
yourself:
</para>
- <programlisting>
+<programlisting>
output << ...... << flush; // can use std::flush manipulator
output.flush(); // or call a member fn </programlisting>
<para>On the other hand, there are times when writing to a file should
just to turn off the buffering <emphasis>before any I/O operations at
all</emphasis> have been done (note that opening counts as an I/O operation):
</para>
- <programlisting>
+<programlisting>
std::ofstream os;
std::ifstream is;
int i;
completely portably. And since this is C++, you have an open
ifstream (call it IN) and an open ofstream (call it OUT):
</para>
- <programlisting>
+<programlisting>
#include <fstream>
std::ifstream IN ("input_file");
std::ofstream OUT ("output_file"); </programlisting>
<para>Here's the easiest way to get it completely wrong:
</para>
- <programlisting>
+<programlisting>
OUT << IN;</programlisting>
<para>For those of you who don't already know why this doesn't work
(probably from having done it before), I invite you to quickly
create a simple text file called "input_file" containing
the sentence
</para>
- <programlisting>
+<programlisting>
The quick brown fox jumped over the lazy dog.</programlisting>
<para>surrounded by blank lines. Code it up and try it. The contents
of "output_file" may surprise you.
using the <code>rdbuf()</code> member function. Therefore, the easiest
way to copy the file is:
</para>
- <programlisting>
+<programlisting>
OUT << IN.rdbuf();</programlisting>
<para>So what <emphasis>was</emphasis> happening with OUT<<IN? Undefined
behavior, since that particular << isn't defined by the Standard.
<para>Because the C++ library includes the C library, both C-style and
C++-style I/O have to work at the same time. For example:
</para>
- <programlisting>
+<programlisting>
#include <iostream>
#include <cstdio>
std::cout << "Hel";
std::printf ("lo, worl");
std::cout << "d!\n";
- </programlisting>
+</programlisting>
<para>This must do what you think it does.
</para>
<para>Alert members of the audience will immediately notice that buffering
C++ I/O, then there's no need to sync with the C streams. The right
thing to do in this case is to call
</para>
- <programlisting>
+<programlisting>
#include <emphasis>any of the I/O headers such as ios, iostream, etc</emphasis>
std::ios::sync_with_stdio(false);
- </programlisting>
+</programlisting>
<para>You must do this before performing any I/O via the C++ stream objects.
Once you call this, the C++ streams will operate independently of the
(unused) C streams. For GCC 3.x, this means that <code>cout</code> and
of them as indexing 0 through n-1. Think of them as <emphasis>boundary
markers</emphasis>:
</para>
- <programlisting>
+<programlisting>
beginning end
| |
| | dereference 'end'.
beginning end
- </programlisting>
+</programlisting>
<para>See? Everything between the boundary markers is chapter of the array.
Simple.
</para>
</itemizedlist>
<para>Here is a simple example of the two forms of <code>accumulate</code>.
</para>
- <programlisting>
+<programlisting>
int ar[50];
int someval = somefunction();
int sum = std::accumulate(ar,ar+50,0);
int sum_stuff = std::accumulate(ar,ar+50,someval);
int product = std::accumulate(ar,ar+50,1,std::multiplies<int>());
- </programlisting>
+</programlisting>
<para>The first call adds all the members of the array, using zero as an
initial value for <code>sum</code>. The second does the same, but uses
<code>someval</code> as the starting value (thus, <code>sum_stuff == sum +
a generic container object, what is the behavior of the object?
Suppose one writes
</para>
- <programlisting>
+<programlisting>
template<typename Cntnr>
void
some_op_sequence(Cntnr &r_container)
{
...
}
- </programlisting>
+</programlisting>
<para>
then one needs to address the following questions in the body
This code will go through some iterations. Here's a simple
version:
</para>
- <programlisting>
+<programlisting>
#include <string>
#include <algorithm>
#include <cctype> // old <ctype.h>
capital_s.resize(s.size());
std::transform (s.begin(), s.end(), capital_s.begin(), ToUpper());
}
- </programlisting>
+</programlisting>
<para>
<emphasis>Note</emphasis> that these calls all
involve the global C locale through the use of the C functions
<!-- section 14.8.2.4 clause 16 in ISO 14882:1998 -->
At minimum, you can write short wrappers like
</para>
- <programlisting>
+<programlisting>
char toLower (char c)
{
// std::tolower(c) is undefined if c < 0 so cast to unsigned char.
which can perform the conversion to <code>unsigned char</code> and
also ensure the single-argument form of <code>std::lower</code> is used:
</para>
- <programlisting>
+<programlisting>
std::transform (s.begin(), s.end(), capital_s.begin(),
[](unsigned char c) { return std::tolower(c); });
- </programlisting>
+</programlisting>
<para>Another common operation is trimming off excess whitespace. Much
like transformations, this task is trivial with the use of string's
<code>find</code> family. These examples are broken into multiple
statements for readability:
</para>
- <programlisting>
+<programlisting>
std::string str (" \t blah blah blah \n ");
// trim leading whitespace
case-insensitive in the same way as the (common but nonstandard)
C function stricmp()</quote>.
</para>
- <programlisting>
+<programlisting>
ci_string s( "AbCdE" );
// case insensitive
type parameters, which take default arguments based on the character
type (called <code>CharT</code> here):
</para>
- <programlisting>
+<programlisting>
template <typename CharT,
typename Traits = char_traits<CharT>,
typename Alloc = allocator<CharT> >
template is <emphasis>declared</emphasis> but not <emphasis>defined</emphasis>.
That means there is only
</para>
- <programlisting>
+<programlisting>
template <typename CharT>
struct char_traits
{
</para>
- <programlisting>
+<programlisting>
std::list<string> ls;
stringtok (ls, " this \t is\t\n a test ");
for (std::list<string>const_iterator i = ls.begin();
} </programlisting>
<para>You would see this as output:
</para>
- <programlisting>
+<programlisting>
:this:
:is:
:a:
<para>This behaviour is suggested, but not required by the standard. Prior
to GCC 3.4 the following alternative can be used instead
</para>
- <programlisting>
+<programlisting>
std::string(str.data(), str.size()).swap(str);
- </programlisting>
+</programlisting>
<para>This is similar to the idiom for reducing
a <code>vector</code>'s memory usage
(see <link linkend="faq.size_equals_capacity">this FAQ
streams seamlessly because they inherit from the iostream
hierarchy. An quick example:
</para>
- <programlisting>
+<programlisting>
#include <iostream>
#include <string>
#include <sstream>
<para>A serious problem with CString is a design bug in its memory
allocation. Specifically, quoting from that same message:
</para>
- <programlisting>
+<programlisting>
CString suffers from a common programming error that results in
poor performance. Consider the following code:
If you replace CString with string in the above function, the
performance is O(n).
- </programlisting>
+</programlisting>
<para>Joe Buck also pointed out some other things to keep in mind when
comparing CString and the Standard string class:
</para>
and defined as follows:
</para>
- <programlisting>
+<programlisting>
template<typename T>
struct class
{
static const bool tinyness_before;
static const float_round_style round_style;
};
- </programlisting>
+</programlisting>
</section>
<section xml:id="std.support.types.null" xreflabel="NULL"><info><title>NULL</title></info>
by registering a <quote>new-handler</quote>, because what
<function>operator new</function> actually does is something like:
</para>
- <programlisting>
+<programlisting>
while (true)
{
if (void* p = /* try to allocate memory */)
else
throw bad_alloc{};
}
- </programlisting>
+</programlisting>
<para>
This means you can influence what happens on allocation failure by
writing your own new-handler and then registering it with
<function>std::set_new_handler</function>:
</para>
- <programlisting>
+<programlisting>
typedef void (*PFV)();
static char* safety;
old_handler = set_new_handler (&my_new_handler);
...
}
- </programlisting>
+</programlisting>
<section xml:id="std.support.memory.notes" xreflabel="Dynamic Memory Notes"><info><title>Additional Notes</title></info>
<filename class="headerfile"><cstdlib></filename>, and call
</para>
- <programlisting>
+<programlisting>
std::set_terminate(std::abort);
- </programlisting>
+</programlisting>
<para>
After this, all calls to <function>terminate</function> will use
of the C++ standard (ISO 14882) are files within the following
directories:
- <programlisting>
+<programlisting>
17_intro
18_support
19_diagnostics
28_regex
29_atomics
30_threads
- </programlisting>
+</programlisting>
</para>
<para>
This test case expects some kind of interactive input in order
to finish or pass. At the moment, the interactive tests are not
run by default. Instead, they are run by hand, like:
- <programlisting>
+<programlisting>
g++ 27_io/objects/char/3_xin.cc
cat 27_io/objects/char/3_xin.in | a.out</programlisting>
</listitem>
Also, here is an example of how to run the libstdc++ testsuite
for a multilibed build directory with different ABI settings:
- <programlisting>
+<programlisting>
make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board \"unix{-mabi=32,,-mabi=64}\"'
</programlisting>
</para>
run programs on, e.g. <code>x86_64-pc-linux-gnu</code>, as a few tests
still execute the code they build. Here's an example of how to run the
testsuite with libstdc++ in freestanding mode:
- <programlisting>
+<programlisting>
make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board=unix/-ffreestanding'
- </programlisting>
+</programlisting>
</para>
<para>
into great detail, here is an example which requires user-level
locks:
</para>
- <programlisting>
+<programlisting>
library_class_a shared_object_a;
void thread_main () {
another thread, here is an example that does not require any
user-level locks:
</para>
- <programlisting>
+<programlisting>
void thread_main () {
library_class_a object_a;
library_class_b *object_b = new library_class_b;
globally-visible object, the library ensures that the reference
count updates are atomic and do not introduce data races:
</para>
- <programlisting>
+<programlisting>
std::shared_ptr<int> global_sp;
void thread_main() {
t1.join();
t2.join();
}
- </programlisting>
+</programlisting>
<para>For further details of the C++11 memory model see Hans-J. Boehm's
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://www.hboehm.info/c++mm/">Threads
<para>Construction is simple. The default ctor initializes each member
with its respective default ctor. The other simple ctor,
</para>
- <programlisting>
+<programlisting>
pair (const T1& x, const T2& y);
- </programlisting>
+</programlisting>
<para>does what you think it does, <code>first</code> getting <code>x</code>
and <code>second</code> getting <code>y</code>.
</para>
<para>There is a constructor template for copying pairs of other types:
</para>
- <programlisting>
+<programlisting>
template <class U, class V> pair (const pair<U,V>& p);
- </programlisting>
+</programlisting>
<para>The compiler will convert as necessary from U to T1 and from
V to T2 in order to perform the respective initializations.
</para>
The less-than operator is a bit odd the first time you see it. It
is defined as evaluating to:
</para>
- <programlisting>
+<programlisting>
x.first < y.first ||
( !(y.first < x.first) && x.second < y.second )
- </programlisting>
+</programlisting>
<para>The other operators are not defined using the <code>rel_ops</code>
functions above, but their semantics are the same.
</para>
that takes two references-to-const objects and returns an
instance of a pair instantiated on their respective types:
</para>
- <programlisting>
+<programlisting>
pair<int,MyClass> p = make_pair(4,myobject);
- </programlisting>
+</programlisting>
</section>