Commit 51122a42 by Phil Edwards

acinclude.m4: Minor comment tweaks.

2002-08-31  Phil Edwards  <pme@gcc.gnu.org>

	* acinclude.m4:  Minor comment tweaks.

	* docs/html/makedoc.awk:  New file...
	* docs/html/Makefile:  ...called from here...
	* docs/html/documentation.html:  ...to help generate this.

	* docs/html/21_strings/howto.html:  Prepare for new entry.
	* include/bits/basic_string.h:  Initial basic_stirng hook for
	doxygen.  Remove trailing whitespace.
	* include/bits/char_traits.h:  Point to onlinedocs for new entry.
	* include/bits/stringfwd.h:  Add doxygen hooks for string and
	wstring typedefs.

From-SVN: r56711
parent 98c0d8d1
2002-08-31 Phil Edwards <pme@gcc.gnu.org>
* acinclude.m4: Minor comment tweaks.
* docs/html/makedoc.awk: New file...
* docs/html/Makefile: ...called from here...
* docs/html/documentation.html: ...to help generate this.
* docs/html/21_strings/howto.html: Prepare for new entry.
* include/bits/basic_string.h: Initial basic_stirng hook for
doxygen. Remove trailing whitespace.
* include/bits/char_traits.h: Point to onlinedocs for new entry.
* include/bits/stringfwd.h: Add doxygen hooks for string and
wstring typedefs.
2002-08-29 Richard Earnshaw <rearnshaw@arm.com> 2002-08-29 Richard Earnshaw <rearnshaw@arm.com>
* config/cpu/arm/cpu_limits.h: New file. * config/cpu/arm/cpu_limits.h: New file.
......
dnl dnl
dnl Initialize configure bits. dnl Initialize basic configure bits, set toplevel_srcdir for Makefiles.
dnl dnl
dnl GLIBCPP_TOPREL_CONFIGURE dnl GLIBCPP_TOPREL_CONFIGURE
AC_DEFUN(GLIBCPP_TOPREL_CONFIGURE, [ AC_DEFUN(GLIBCPP_TOPREL_CONFIGURE, [
...@@ -37,13 +37,10 @@ AC_DEFUN(GLIBCPP_TOPREL_CONFIGURE, [ ...@@ -37,13 +37,10 @@ AC_DEFUN(GLIBCPP_TOPREL_CONFIGURE, [
]) ])
dnl dnl
dnl Initialize configure bits. dnl Initialize the rest of the library configury.
dnl dnl
dnl GLIBCPP_CONFIGURE dnl GLIBCPP_CONFIGURE
AC_DEFUN(GLIBCPP_CONFIGURE, [ AC_DEFUN(GLIBCPP_CONFIGURE, [
#possibly test for the presence of the compiler sources here?
# Export build and source directories. # Export build and source directories.
# These need to be absolute paths, yet at the same time need to # These need to be absolute paths, yet at the same time need to
# canonicalize only relative paths, because then amd will not unmount # canonicalize only relative paths, because then amd will not unmount
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
<li><a href="#2">A case-insensitive string class</a> <li><a href="#2">A case-insensitive string class</a>
<li><a href="#3">Breaking a C++ string into tokens</a> <li><a href="#3">Breaking a C++ string into tokens</a>
<li><a href="#4">Simple transformations</a> <li><a href="#4">Simple transformations</a>
<li><a href="#5">Making strings of arbitrary character types</a>
</ul> </ul>
<hr> <hr>
...@@ -321,6 +322,15 @@ ...@@ -321,6 +322,15 @@
<a href="../faq/index.html">to the FAQ</a>. <a href="../faq/index.html">to the FAQ</a>.
</p> </p>
<hr>
<h2><a name="5">Making strings of arbitrary character types</a></h2>
<p>how to work with char_traits -- in the archives, just need to
go through and pull the examples together
</p>
<p>Return <a href="#top">to top of page</a> or
<a href="../faq/index.html">to the FAQ</a>.
</p>
<!-- ####################################################### --> <!-- ####################################################### -->
......
PWD=$${PWDCMD-pwd}
PWD=$${PWDCMD-pwd}
MAKEINFO=makeinfo MAKEINFO=makeinfo
INC=../../../gcc/doc/include INC=../../../gcc/doc/include
all: faq/index.txt 17_intro/porting.html 17_intro/porting-howto.html all: documentation.html \
faq/index.txt \
17_intro/porting.html \
17_intro/porting-howto.html
# chock full of GNUism, probably
documentation.html: $(wildcard */howto.html)
sed -n '1,/beginlist/p' $@ > tmp.top
sed -n '/endlist/,$$p' $@ > tmp.bottom
echo ' <ul>' > tmp.middle
for i in [[:digit:]]*/howto.html; do \
title=`grep 'h1 ' $$i |\
sed 's=.*\(Chapter [[:digit:]]*\):[[:space:]]*\(.*\)</a>.*=\2 (\1)='` ;\
awk -v file=$$i -v "title=$$title" -f makedoc.awk $$i >> tmp.middle ;\
done
awk -v file=ext/howto.html -v "title=Extensions to the Standard Library"\
-f makedoc.awk ext/howto.html >> tmp.middle ;\
echo ' </ul>' >> tmp.middle
cat tmp.top tmp.middle tmp.bottom > $@
rm tmp.top tmp.middle tmp.bottom
faq/index.txt: faq/index.html faq/index.txt: faq/index.html
lynx -dump $< | sed "s%file://localhost`${PWD}`%..%" > $@ lynx -dump $< | sed "s%file://localhost`${PWD}`%..%" > $@
...@@ -16,3 +34,4 @@ faq/index.txt: faq/index.html ...@@ -16,3 +34,4 @@ faq/index.txt: faq/index.html
17_intro/porting-howto.html: 17_intro/porting-howto.xml 17_intro/porting-howto.html: 17_intro/porting-howto.xml
xltproc -o $@ /usr/share/xml/docbook/xsl-stylesheets-1.48-2/html/docbook.xsl $< xltproc -o $@ /usr/share/xml/docbook/xsl-stylesheets-1.48-2/html/docbook.xsl $<
# vim:noet ts=4
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<ul> <ul>
<li><a href="17_intro/COPYING">License</a> <li><a href="17_intro/COPYING">License</a>
- GPL v2 license terms - GPL v2 license terms
<li><a href="abi.txt">ABI Policy and Guidelines</a> <li><a href="abi.txt">ABI Policy and Guidelines</a>
<li><a href="17_intro/BUGS">BUGS</a> <li><a href="17_intro/BUGS">BUGS</a>
<li><a href="17_intro/PROBLEMS">PROBLEMS</a> <li><a href="17_intro/PROBLEMS">PROBLEMS</a>
- target-specific known issues - target-specific known issues
...@@ -84,121 +84,127 @@ ...@@ -84,121 +84,127 @@
<br> <br>
<h2><a name="3">Chapter-Specific Documentation</a></h2> <h2><a name="3">Chapter-Specific Documentation</a></h2>
<p>Information, extensions, notes and advice on specific implementation <p>Information, extensions, notes and advice on specific implementation
capabilites and or liabilities broken down into chapter names based on the capabilites and/or liabilities broken down into chapter names based on the
C++ standard. C++ standard.
</p> </p>
<ul> <!--
<li>Intro (Chapter 17) The list below is automatically generated. To make changes in the text,
<ul> edit the appropriate HOWTO file and run "make" in this directory. In
<li><a href="17_intro/howto.html#1">Header files</a> those files, you may reorder entries as you like, but DO NOT change the
<li><a href="17_intro/howto.html#3">Using &lt;foo&gt; vs &lt;foo.h&gt;</a> "#number"s in anchors, for they are used elsewhere and in bookmarks.
<li><a href="17_intro/howto.html#2">Multithreading</a> -->
<li><a href="17_intro/howto.html#4">Porting</a> <!-- beginlist -->
<li><a href="17_intro/howto.html#5">Implementation-specific behavior</a> <ul>
<li><a href="17_intro/howto.html#6">Using preprocessor macros to change behavior of the library</a> <li>Library Introduction (Chapter 17)</li>
</ul> <ul>
<li><a href="17_intro/howto.html#2">The Standard C++ header files</a></li>
<li>Library Support (Chapter 18) <li><a href="17_intro/howto.html#3">The Standard C++ library and multithreading</a></li>
<ul> <li><a href="17_intro/howto.html#4"><code>&lt;foo&gt;</code> vs <code>&lt;foo.h&gt;</code></a></li>
<li><a href="18_support/howto.html#1">Types</a> <li><a href="17_intro/porting-howto.html">Porting HOWTO</a></li>
<li><a href="18_support/howto.html#2">Implementation properties</a> <li><a href="17_intro/howto.html#5">Behavior specific to libstdc++-v3</a></li>
<li><a href="18_support/howto.html#3">Start and Termination</a> <li><a href="17_intro/howto.html#6">Preprocessor macros controlling the library</a></li>
<li><a href="18_support/howto.html#4">Dynamic memory management</a> </ul>
<li><a href="18_support/howto.html#5">RTTI, the ABI, and demangling</a>
</ul> <li>Library Support (Chapter 18)</li>
<ul>
<li><a href="18_support/howto.html#1">Types</a></li>
<li>Diagnostics (Chapter 19) <li><a href="18_support/howto.html#2">Implementation properties</a></li>
<ul> <li><a href="18_support/howto.html#3">Start and Termination</a></li>
<li><a href="19_diagnostics/howto.html#1">Adding data to exceptions</a> <li><a href="18_support/howto.html#4">Dynamic memory management</a></li>
<li><a href="19_diagnostics/howto.html#2">Exception class hierarchy diagram</a> <li><a href="18_support/howto.html#5">RTTI, the ABI, and demangling</a></li>
<li><a href="19_diagnostics/howto.html#3">Concept checkers -- new and improved!</a> </ul>
<li><a href="19_diagnostics/howto.html#4">Verbose terminate</a>
</ul> <li>Diagnostics (Chapter 19)</li>
<ul>
<li>Utilities (Chapter 20) <li><a href="19_diagnostics/howto.html#1">Adding data to exceptions</a></li>
<ul> <li><a href="19_diagnostics/howto.html#2">Exception class hierarchy diagram</a></li>
<li><a href="20_util/howto.html#1">auto_ptr is not omnipotent</a> <li><a href="19_diagnostics/howto.html#3">Concept checkers -- <strong>new and improved!</strong></a></li>
<li><a href="20_util/howto.html#1">auto_ptr inside container classes</a> <li><a href="19_diagnostics/howto.html#4">Verbose <code>terminate</code></a></li>
<li><a href="20_util/howto.html#1">Functors</a> </ul>
<li><a href="20_util/howto.html#1">Pairs</a>
</ul> <li>General Utilities (Chapter 20)</li>
<ul>
<li><a href="20_util/howto.html#1"><code>auto_ptr</code> is not omnipotent</a></li>
<li>Strings (Chapter 21) <li><a href="20_util/howto.html#2"><code>auto_ptr</code> inside container classes</a></li>
<ul> <li><a href="20_util/howto.html#3">Functors</a></li>
<li><a href="21_strings/howto.html#1">MFC's CString</a> <li><a href="20_util/howto.html#4">Pairs</a></li>
<li><a href="21_strings/howto.html#2">A case-insensitive string class</a> </ul>
<li><a href="21_strings/howto.html#3">Breaking a C++ string into tokens</a>
<li><a href="21_strings/howto.html#4">Simple transformations</a> <li>Strings (Chapter 21)</li>
</ul> <ul>
<li><a href="21_strings/howto.html#1">MFC's CString</a></li>
<li>Localization (Chapter 22) <li><a href="21_strings/howto.html#2">A case-insensitive string class</a></li>
<ul> <li><a href="21_strings/howto.html#3">Breaking a C++ string into tokens</a></li>
<li><a href="22_locale/howto.html#1">Class locale</a> <li><a href="21_strings/howto.html#4">Simple transformations</a></li>
<li><a href="22_locale/howto.html#2">Class codecvt</a> <li><a href="21_strings/howto.html#5">Making strings of arbitrary character types</a></li>
<li><a href="22_locale/howto.html#3">Class ctype</a> </ul>
<li><a href="22_locale/howto.html#4">Class messages</a>
<li><a href="22_locale/howto.html#5">Bjarne Stroustrup on Locales</a> <li>Localization (Chapter 22)</li>
<li><a href="22_locale/howto.html#6">Nathan Myers on Locales</a> <ul>
<li><a href="22_locale/howto.html#7">Correct Transformations </a> <li><a href="22_locale/howto.html#1">class locale</a></li>
</ul> <li><a href="22_locale/howto.html#2">class codecvt</a></li>
<li><a href="22_locale/howto.html#3">class ctype</a></li>
<li>Containers (Chapter 23) <li><a href="22_locale/howto.html#4">class messages</a></li>
<ul> <li><a href="22_locale/howto.html#5">Bjarne Stroustrup on Locales</a></li>
<li><a href="23_containers/howto.html#1">Making code unaware of the container/array difference</a> <li><a href="22_locale/howto.html#6">Nathan Myers on Locales </a></li>
<li><a href="23_containers/howto.html#2">Variable-sized bitmasks</a> <li><a href="22_locale/howto.html#7">Correct Transformations</a></li>
<li><a href="23_containers/howto.html#3">Containers and multithreading</a> </ul>
<li><a href="23_containers/howto.html#4">&quot;Hinting&quot; during insertion</a>
<li><a href="23_containers/howto.html#5">Bitmasks and string arguments</a> <li>Containers (Chapter 23)</li>
<li><a href="23_containers/howto.html#6"><code>std::list::size()</code> is O(n)!</a> <ul>
<li><a href="23_containers/howto.html#7">Space overhead management for vectors </a> <li><a href="23_containers/howto.html#1">Making code unaware of the container/array difference</a></li>
</ul> <li><a href="23_containers/howto.html#2">Variable-sized bitmasks</a></li>
<li><a href="23_containers/howto.html#3">Containers and multithreading</a></li>
<li>Iterators (Chapter24) <li><a href="23_containers/howto.html#4">&quot;Hinting&quot; during insertion</a></li>
<ul> <li><a href="23_containers/howto.html#5">Bitmasks and string arguments</a></li>
<li><a href="24_iterators/howto.html#1">They aren't pointers!</a> <li><a href="23_containers/howto.html#6"><code>std::list::size()</code> is O(n)!</a></li>
<li><a href="24_iterators/howto.html#1">It ends where?</a> <li><a href="23_containers/howto.html#7">Space overhead management for vectors</a></li>
</ul> </ul>
<li>Algorithms (Chapter 25) <li>Iterators (Chapter 24)</li>
<ul> <ul>
<li><a href="25_algorithms/howto.html#1">Prerequisites</a> <li><a href="24_iterators/howto.html#1">They ain't pointers!</a></li>
<li><a href="25_algorithms/howto.html#2">Special swaps</a> <li><a href="24_iterators/howto.html#2">It ends <em>where?</em></a></li>
</ul> </ul>
<li>Numerics (Chapter 26) <li>Algorithms (Chapter 25)</li>
<ul> <ul>
<li><a href="26_numerics/howto.html#1">Complex Number Processing</a> <li><a href="25_algorithms/howto.html#1">Prerequisites</a></li>
<li><a href="26_numerics/howto.html#2">Array Processing</a> <li><a href="25_algorithms/howto.html#2">Special <code>swap</code>s</a></li>
<li><a href="26_numerics/howto.html#3">Numerical Functions</a> </ul>
<li><a href="26_numerics/howto.html#4">C99</a>
</ul> <li>Numerics (Chapter 26)</li>
<ul>
<li>I/O (Chapter 27) <li><a href="26_numerics/howto.html#1">Complex Number Processing</a></li>
<ul> <li><a href="26_numerics/howto.html#2">Array Processing</a></li>
<li><a href="27_io/howto.html#1">Copying a file</a> <li><a href="26_numerics/howto.html#3">Numerical Functions</a></li>
<li><a href="27_io/howto.html#2">The buffering is screwing up my program!</a> <li><a href="26_numerics/howto.html#4">C99</a></li>
</ul> </ul>
<ul>
<li><a href="27_io/howto.html#3">Binary I/O</a> <li>Input/Output (Chapter 27)</li>
<li><a href="27_io/howto.html#6">More on binary I/O</a> <ul>
<li><a href="27_io/howto.html#5">Deriving a stream buffer</a> <li><a href="27_io/howto.html#1">Copying a file</a></li>
<li><a href="27_io/howto.html#4">What is this &lt;sstream&gt;/stringstreams thing?</a> <li><a href="27_io/howto.html#2">The buffering is screwing up my program!</a></li>
<li><a href="27_io/howto.html#7">Pathetic performance? Ditch C.</a> <li><a href="27_io/howto.html#3">Binary I/O</a></li>
<li><a href="27_io/howto.html#8">Threads and I/O</a> <li><a href="27_io/howto.html#5">What is this &lt;sstream&gt;/stringstreams thing?</a></li>
</ul> <li><a href="27_io/howto.html#6">Deriving a stream buffer</a></li>
<li><a href="27_io/howto.html#7">More on binary I/O</a></li>
<li>Extensions to the Standard Library <li><a href="27_io/howto.html#8">Pathetic performance? Ditch C.</a></li>
<ul> <li><a href="27_io/howto.html#9">Threads and I/O</a></li>
<li><a href="ext/howto.html#1">Ropes and trees and hashes, oh my!</a> </ul>
<li><a href="ext/howto.html#2">Added members and types</a>
<li><a href="ext/howto.html#3">Allocators (versions 3.0, 3.1, 3.2)</a> <li>Extensions to the Standard Library</li>
<li><a href="ext/howto.html#4">Allocators (version 3.3)</a> <ul>
<li><a href="ext/howto.html#5">Compile-time checks</a> <li><a href="ext/howto.html#1">Ropes and trees and hashes, oh my!</a></li>
<li><a href="ext/howto.html#6">LWG Issues</a> <li><a href="ext/howto.html#2">Added members and types</a></li>
</ul> <li><a href="ext/howto.html#3">Allocators (versions 3.0, 3.1, 3.2)</a></li>
</ul> <li><a href="ext/howto.html#6">Allocators (version 3.3)</a></li>
<li><a href="ext/howto.html#4">Compile-time checks</a></li>
<li><a href="ext/howto.html#5">LWG Issues</a></li>
</ul>
</ul>
<!-- endlist -->
<hr /> <hr />
<br> <br>
......
# Take apart bits of HTML and puts them back together again in new and
# fascinating ways. Copyright (C) 2002 Free Software Foundation, Inc.
# Contributed by Phil Edwards <pme@gcc.gnu.org>. Simple two-state automaton
# inspired by Richard Henderson's gcc/mkmap-symver.awk.
# 'file' is the name of the file on stdin
# 'title' is the text to print at the start of the list
BEGIN {
state = "looking";
entries = 0;
printf (" <li>%s</li>\n", title);
printf (" <ul>\n");
}
# Searching for the little table of contents at the top.
state == "looking" && /^<h1>Contents/ {
state = "entries";
next;
}
# Ignore everything else up to that point.
state == "looking" {
next;
}
# An entry in the table of contents. Pull that line apart.
state == "entries" && /<li>/ {
extract_info($0);
next;
}
# End of the list. Don't bother reading the rest of the file. (It could
# also contain more <li>'s, so that would be incorrect as well as wasteful.)
state == "entries" && /^<\/ul>/ {
exit;
}
END {
for (i = 0; i < entries; i++)
printf (" %s\n", entry[i]);
printf (" </ul>\n\n");
}
function extract_info(line) {
# thistarget will be things like "#5" or "elsewhere.html"
match(line,"href=\".*\"");
thistarget = substr(line,RSTART+6,RLENGTH-7);
# take apart the filename
split(file,X,"/");
if (thistarget ~ /^#/) {
# local name, use directory and filename
target = file thistarget
} else {
# different file, only use directory
target = X[1] "/" thistarget
}
# visible text
gsub("</a>","",line);
start = index(line,"\">") + 2;
thistext = substr(line,start);
# Assemble and store the HTML for later output.
entry[entries++] = "<li><a href=\"" target "\">" thistext "</a></li>"
}
# vim:sw=2
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
*/ */
#ifndef _CPP_BITS_STRING_H #ifndef _CPP_BITS_STRING_H
#define _CPP_BITS_STRING_H 1 #define _CPP_BITS_STRING_H 1
#pragma GCC system_header #pragma GCC system_header
...@@ -46,44 +46,64 @@ ...@@ -46,44 +46,64 @@
namespace std namespace std
{ {
// Documentation? What's that? /**
// Nathan Myers <ncm@cantrip.org>. * @class basic_string basic_string.h <string>
// * @brief Managing sequences of characters and character-like objects.
// A string looks like this: *
// * @ingroup Containers
// [_Rep] * @ingroup Sequences
// _M_length *
// [basic_string<char_type>] _M_capacity * Meets the requirements of a <a href="tables.html#65">container</a>, a
// _M_dataplus _M_state * <a href="tables.html#66">reversible container</a>, and a
// _M_p ----------------> unnamed array of char_type * <a href="tables.html#67">sequence</a>. Of the
* <a href="tables.html#68">optional sequence requirements</a>, only
// Where the _M_p points to the first character in the string, and * @c push_back, @c at, and array access are supported.
// you cast it to a pointer-to-_Rep and subtract 1 to get a *
// pointer to the header. * @doctodo
*
// This approach has the enormous advantage that a string object *
// requires only one allocation. All the ugliness is confined * @if maint
// within a single pair of inline functions, which each compile to * Documentation? What's that?
// a single "add" instruction: _Rep::_M_data(), and * Nathan Myers <ncm@cantrip.org>.
// string::_M_rep(); and the allocation function which gets a *
// block of raw bytes and with room enough and constructs a _Rep * A string looks like this:
// object at the front. *
* @code
// The reason you want _M_data pointing to the character array and * [_Rep]
// not the _Rep is so that the debugger can see the string * _M_length
// contents. (Probably we should add a non-inline member to get * [basic_string<char_type>] _M_capacity
// the _Rep for the debugger to use, so users can check the actual * _M_dataplus _M_state
// string length.) * _M_p ----------------> unnamed array of char_type
* @endcode
// Note that the _Rep object is a POD so that you can have a *
// static "empty string" _Rep object already "constructed" before * Where the _M_p points to the first character in the string, and
// static constructors have run. The reference-count encoding is * you cast it to a pointer-to-_Rep and subtract 1 to get a
// chosen so that a 0 indicates one reference, so you never try to * pointer to the header.
// destroy the empty-string _Rep object. *
* This approach has the enormous advantage that a string object
// All but the last paragraph is considered pretty conventional * requires only one allocation. All the ugliness is confined
// for a C++ string implementation. * within a single pair of inline functions, which each compile to
* a single "add" instruction: _Rep::_M_data(), and
* string::_M_rep(); and the allocation function which gets a
* block of raw bytes and with room enough and constructs a _Rep
* object at the front.
*
* The reason you want _M_data pointing to the character array and
* not the _Rep is so that the debugger can see the string
* contents. (Probably we should add a non-inline member to get
* the _Rep for the debugger to use, so users can check the actual
* string length.)
*
* Note that the _Rep object is a POD so that you can have a
* static "empty string" _Rep object already "constructed" before
* static constructors have run. The reference-count encoding is
* chosen so that a 0 indicates one reference, so you never try to
* destroy the empty-string _Rep object.
*
* All but the last paragraph is considered pretty conventional
* for a C++ string implementation.
* @endif
*/
// 21.3 Template class basic_string // 21.3 Template class basic_string
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string class basic_string
...@@ -104,7 +124,7 @@ namespace std ...@@ -104,7 +124,7 @@ namespace std
const_iterator; const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator; typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator; typedef reverse_iterator<iterator> reverse_iterator;
private: private:
// _Rep: string representation // _Rep: string representation
// Invariants: // Invariants:
...@@ -125,7 +145,7 @@ namespace std ...@@ -125,7 +145,7 @@ namespace std
// Types: // Types:
typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc; typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
// (Public) Data members: // (Public) Data members:
// The maximum number of individual char_type elements of an // The maximum number of individual char_type elements of an
// individual string is determined by _S_max_size. This is the // individual string is determined by _S_max_size. This is the
...@@ -133,10 +153,10 @@ namespace std ...@@ -133,10 +153,10 @@ namespace std
// is the maximum number of bytes the allocator can allocate.) // is the maximum number of bytes the allocator can allocate.)
// If one was to divvy up the theoretical largest size string, // If one was to divvy up the theoretical largest size string,
// with a terminating character and m _CharT elements, it'd // with a terminating character and m _CharT elements, it'd
// look like this: // look like this:
// npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
// Solving for m: // Solving for m:
// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
// In addition, this implementation quarters this ammount. // In addition, this implementation quarters this ammount.
static const size_type _S_max_size; static const size_type _S_max_size;
static const _CharT _S_terminal; static const _CharT _S_terminal;
...@@ -144,7 +164,7 @@ namespace std ...@@ -144,7 +164,7 @@ namespace std
size_type _M_length; size_type _M_length;
size_type _M_capacity; size_type _M_capacity;
_Atomic_word _M_references; _Atomic_word _M_references;
bool bool
_M_is_leaked() const _M_is_leaked() const
{ return _M_references < 0; } { return _M_references < 0; }
...@@ -154,50 +174,50 @@ namespace std ...@@ -154,50 +174,50 @@ namespace std
{ return _M_references > 0; } { return _M_references > 0; }
void void
_M_set_leaked() _M_set_leaked()
{ _M_references = -1; } { _M_references = -1; }
void void
_M_set_sharable() _M_set_sharable()
{ _M_references = 0; } { _M_references = 0; }
_CharT* _CharT*
_M_refdata() throw() _M_refdata() throw()
{ return reinterpret_cast<_CharT*>(this + 1); } { return reinterpret_cast<_CharT*>(this + 1); }
_CharT& _CharT&
operator[](size_t __s) throw() operator[](size_t __s) throw()
{ return _M_refdata() [__s]; } { return _M_refdata() [__s]; }
_CharT* _CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
{ {
return (!_M_is_leaked() && __alloc1 == __alloc2) return (!_M_is_leaked() && __alloc1 == __alloc2)
? _M_refcopy() : _M_clone(__alloc1); ? _M_refcopy() : _M_clone(__alloc1);
} }
// Create & Destroy // Create & Destroy
static _Rep* static _Rep*
_S_create(size_t, const _Alloc&); _S_create(size_t, const _Alloc&);
void void
_M_dispose(const _Alloc& __a) _M_dispose(const _Alloc& __a)
{ {
if (__exchange_and_add(&_M_references, -1) <= 0) if (__exchange_and_add(&_M_references, -1) <= 0)
_M_destroy(__a); _M_destroy(__a);
} // XXX MT } // XXX MT
void void
_M_destroy(const _Alloc&) throw(); _M_destroy(const _Alloc&) throw();
_CharT* _CharT*
_M_refcopy() throw() _M_refcopy() throw()
{ {
__atomic_add(&_M_references, 1); __atomic_add(&_M_references, 1);
return _M_refdata(); return _M_refdata();
} // XXX MT } // XXX MT
_CharT* _CharT*
_M_clone(const _Alloc&, size_type __res = 0); _M_clone(const _Alloc&, size_type __res = 0);
}; };
...@@ -224,45 +244,45 @@ namespace std ...@@ -224,45 +244,45 @@ namespace std
// (carefully) in an empty string with one reference. // (carefully) in an empty string with one reference.
static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
_CharT* _CharT*
_M_data() const _M_data() const
{ return _M_dataplus._M_p; } { return _M_dataplus._M_p; }
_CharT* _CharT*
_M_data(_CharT* __p) _M_data(_CharT* __p)
{ return (_M_dataplus._M_p = __p); } { return (_M_dataplus._M_p = __p); }
_Rep* _Rep*
_M_rep() const _M_rep() const
{ return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
// For the internal use we have functions similar to `begin'/`end' // For the internal use we have functions similar to `begin'/`end'
// but they do not call _M_leak. // but they do not call _M_leak.
iterator iterator
_M_ibegin() const { return iterator(_M_data()); } _M_ibegin() const { return iterator(_M_data()); }
iterator iterator
_M_iend() const { return iterator(_M_data() + this->size()); } _M_iend() const { return iterator(_M_data() + this->size()); }
void void
_M_leak() // for use in begin() & non-const op[] _M_leak() // for use in begin() & non-const op[]
{ {
if (!_M_rep()->_M_is_leaked()) if (!_M_rep()->_M_is_leaked())
_M_leak_hard(); _M_leak_hard();
} }
iterator iterator
_M_check(size_type __pos) const _M_check(size_type __pos) const
{ {
if (__pos > this->size()) if (__pos > this->size())
__throw_out_of_range("basic_string::_M_check"); __throw_out_of_range("basic_string::_M_check");
return _M_ibegin() + __pos; return _M_ibegin() + __pos;
} }
// NB: _M_fold doesn't check for a bad __pos1 value. // NB: _M_fold doesn't check for a bad __pos1 value.
iterator iterator
_M_fold(size_type __pos, size_type __off) const _M_fold(size_type __pos, size_type __off) const
{ {
bool __testoff = __off < this->size() - __pos; bool __testoff = __off < this->size() - __pos;
size_type __newoff = __testoff ? __off : this->size() - __pos; size_type __newoff = __testoff ? __off : this->size() - __pos;
return (_M_ibegin() + __pos + __newoff); return (_M_ibegin() + __pos + __newoff);
...@@ -273,8 +293,8 @@ namespace std ...@@ -273,8 +293,8 @@ namespace std
template<class _Iterator> template<class _Iterator>
static void static void
_S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
{ {
for (; __k1 != __k2; ++__k1, ++__p) for (; __k1 != __k2; ++__k1, ++__p)
traits_type::assign(*__p, *__k1); // These types are off. traits_type::assign(*__p, *__k1); // These types are off.
} }
...@@ -285,7 +305,7 @@ namespace std ...@@ -285,7 +305,7 @@ namespace std
static void static void
_S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2)
{ _S_copy_chars(__p, __k1.base(), __k2.base()); } { _S_copy_chars(__p, __k1.base(), __k2.base()); }
static void static void
_S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2)
{ traits_type::copy(__p, __k1, __k2 - __k1); } { traits_type::copy(__p, __k1, __k2 - __k1); }
...@@ -294,13 +314,13 @@ namespace std ...@@ -294,13 +314,13 @@ namespace std
_S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
{ traits_type::copy(__p, __k1, __k2 - __k1); } { traits_type::copy(__p, __k1, __k2 - __k1); }
void void
_M_mutate(size_type __pos, size_type __len1, size_type __len2); _M_mutate(size_type __pos, size_type __len1, size_type __len2);
void void
_M_leak_hard(); _M_leak_hard();
static _Rep& static _Rep&
_S_empty_rep() _S_empty_rep()
{ return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
...@@ -309,10 +329,10 @@ namespace std ...@@ -309,10 +329,10 @@ namespace std
// NB: We overload ctors in some cases instead of using default // NB: We overload ctors in some cases instead of using default
// arguments, per 17.4.4.4 para. 2 item 2. // arguments, per 17.4.4.4 para. 2 item 2.
inline inline
basic_string(); basic_string();
explicit explicit
basic_string(const _Alloc& __a); basic_string(const _Alloc& __a);
// NB: per LWG issue 42, semantics different from IS: // NB: per LWG issue 42, semantics different from IS:
...@@ -331,154 +351,154 @@ namespace std ...@@ -331,154 +351,154 @@ namespace std
basic_string(_InputIterator __beg, _InputIterator __end, basic_string(_InputIterator __beg, _InputIterator __end,
const _Alloc& __a = _Alloc()); const _Alloc& __a = _Alloc());
~basic_string() ~basic_string()
{ _M_rep()->_M_dispose(this->get_allocator()); } { _M_rep()->_M_dispose(this->get_allocator()); }
basic_string& basic_string&
operator=(const basic_string& __str) { return this->assign(__str); } operator=(const basic_string& __str) { return this->assign(__str); }
basic_string& basic_string&
operator=(const _CharT* __s) { return this->assign(__s); } operator=(const _CharT* __s) { return this->assign(__s); }
basic_string& basic_string&
operator=(_CharT __c) { return this->assign(1, __c); } operator=(_CharT __c) { return this->assign(1, __c); }
// Iterators: // Iterators:
iterator iterator
begin() begin()
{ {
_M_leak(); _M_leak();
return iterator(_M_data()); return iterator(_M_data());
} }
const_iterator const_iterator
begin() const begin() const
{ return const_iterator(_M_data()); } { return const_iterator(_M_data()); }
iterator iterator
end() end()
{ {
_M_leak(); _M_leak();
return iterator(_M_data() + this->size()); return iterator(_M_data() + this->size());
} }
const_iterator const_iterator
end() const end() const
{ return const_iterator(_M_data() + this->size()); } { return const_iterator(_M_data() + this->size()); }
reverse_iterator reverse_iterator
rbegin() rbegin()
{ return reverse_iterator(this->end()); } { return reverse_iterator(this->end()); }
const_reverse_iterator const_reverse_iterator
rbegin() const rbegin() const
{ return const_reverse_iterator(this->end()); } { return const_reverse_iterator(this->end()); }
reverse_iterator reverse_iterator
rend() rend()
{ return reverse_iterator(this->begin()); } { return reverse_iterator(this->begin()); }
const_reverse_iterator const_reverse_iterator
rend() const rend() const
{ return const_reverse_iterator(this->begin()); } { return const_reverse_iterator(this->begin()); }
public: public:
// Capacity: // Capacity:
size_type size_type
size() const { return _M_rep()->_M_length; } size() const { return _M_rep()->_M_length; }
size_type size_type
length() const { return _M_rep()->_M_length; } length() const { return _M_rep()->_M_length; }
size_type size_type
max_size() const { return _Rep::_S_max_size; } max_size() const { return _Rep::_S_max_size; }
void void
resize(size_type __n, _CharT __c); resize(size_type __n, _CharT __c);
void void
resize(size_type __n) { this->resize(__n, _CharT()); } resize(size_type __n) { this->resize(__n, _CharT()); }
size_type size_type
capacity() const { return _M_rep()->_M_capacity; } capacity() const { return _M_rep()->_M_capacity; }
void void
reserve(size_type __res_arg = 0); reserve(size_type __res_arg = 0);
void void
clear() { _M_mutate(0, this->size(), 0); } clear() { _M_mutate(0, this->size(), 0); }
bool bool
empty() const { return this->size() == 0; } empty() const { return this->size() == 0; }
// Element access: // Element access:
const_reference const_reference
operator[] (size_type __pos) const operator[] (size_type __pos) const
{ return _M_data()[__pos]; } { return _M_data()[__pos]; }
reference reference
operator[](size_type __pos) operator[](size_type __pos)
{ {
_M_leak(); _M_leak();
return _M_data()[__pos]; return _M_data()[__pos];
} }
const_reference const_reference
at(size_type __n) const at(size_type __n) const
{ {
if (__n >= this->size()) if (__n >= this->size())
__throw_out_of_range("basic_string::at"); __throw_out_of_range("basic_string::at");
return _M_data()[__n]; return _M_data()[__n];
} }
reference reference
at(size_type __n) at(size_type __n)
{ {
if (__n >= size()) if (__n >= size())
__throw_out_of_range("basic_string::at"); __throw_out_of_range("basic_string::at");
_M_leak(); _M_leak();
return _M_data()[__n]; return _M_data()[__n];
} }
// Modifiers: // Modifiers:
basic_string& basic_string&
operator+=(const basic_string& __str) { return this->append(__str); } operator+=(const basic_string& __str) { return this->append(__str); }
basic_string& basic_string&
operator+=(const _CharT* __s) { return this->append(__s); } operator+=(const _CharT* __s) { return this->append(__s); }
basic_string& basic_string&
operator+=(_CharT __c) { return this->append(size_type(1), __c); } operator+=(_CharT __c) { return this->append(size_type(1), __c); }
basic_string& basic_string&
append(const basic_string& __str); append(const basic_string& __str);
basic_string& basic_string&
append(const basic_string& __str, size_type __pos, size_type __n); append(const basic_string& __str, size_type __pos, size_type __n);
basic_string& basic_string&
append(const _CharT* __s, size_type __n); append(const _CharT* __s, size_type __n);
basic_string& basic_string&
append(const _CharT* __s) append(const _CharT* __s)
{ return this->append(__s, traits_type::length(__s)); } { return this->append(__s, traits_type::length(__s)); }
basic_string& basic_string&
append(size_type __n, _CharT __c); append(size_type __n, _CharT __c);
template<class _InputIterator> template<class _InputIterator>
basic_string& basic_string&
append(_InputIterator __first, _InputIterator __last) append(_InputIterator __first, _InputIterator __last)
{ return this->replace(_M_iend(), _M_iend(), __first, __last); } { return this->replace(_M_iend(), _M_iend(), __first, __last); }
void void
push_back(_CharT __c) push_back(_CharT __c)
{ this->replace(_M_iend(), _M_iend(), 1, __c); } { this->replace(_M_iend(), _M_iend(), 1, __c); }
basic_string& basic_string&
assign(const basic_string& __str); assign(const basic_string& __str);
basic_string& basic_string&
assign(const basic_string& __str, size_type __pos, size_type __n) assign(const basic_string& __str, size_type __pos, size_type __n)
{ {
const size_type __strsize = __str.size(); const size_type __strsize = __str.size();
...@@ -489,7 +509,7 @@ namespace std ...@@ -489,7 +509,7 @@ namespace std
return this->assign(__str._M_data() + __pos, __newsize); return this->assign(__str._M_data() + __pos, __newsize);
} }
basic_string& basic_string&
assign(const _CharT* __s, size_type __n) assign(const _CharT* __s, size_type __n)
{ {
if (__n > this->max_size()) if (__n > this->max_size())
...@@ -511,20 +531,20 @@ namespace std ...@@ -511,20 +531,20 @@ namespace std
} }
} }
basic_string& basic_string&
assign(const _CharT* __s) assign(const _CharT* __s)
{ return this->assign(__s, traits_type::length(__s)); } { return this->assign(__s, traits_type::length(__s)); }
basic_string& basic_string&
assign(size_type __n, _CharT __c) assign(size_type __n, _CharT __c)
{ return this->replace(_M_ibegin(), _M_iend(), __n, __c); } { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
template<class _InputIterator> template<class _InputIterator>
basic_string& basic_string&
assign(_InputIterator __first, _InputIterator __last) assign(_InputIterator __first, _InputIterator __last)
{ return this->replace(_M_ibegin(), _M_iend(), __first, __last); } { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
void void
insert(iterator __p, size_type __n, _CharT __c) insert(iterator __p, size_type __n, _CharT __c)
{ this->replace(__p, __p, __n, __c); } { this->replace(__p, __p, __n, __c); }
...@@ -532,11 +552,11 @@ namespace std ...@@ -532,11 +552,11 @@ namespace std
void insert(iterator __p, _InputIterator __beg, _InputIterator __end) void insert(iterator __p, _InputIterator __beg, _InputIterator __end)
{ this->replace(__p, __p, __beg, __end); } { this->replace(__p, __p, __beg, __end); }
basic_string& basic_string&
insert(size_type __pos1, const basic_string& __str) insert(size_type __pos1, const basic_string& __str)
{ return this->insert(__pos1, __str, 0, __str.size()); } { return this->insert(__pos1, __str, 0, __str.size()); }
basic_string& basic_string&
insert(size_type __pos1, const basic_string& __str, insert(size_type __pos1, const basic_string& __str,
size_type __pos2, size_type __n) size_type __pos2, size_type __n)
{ {
...@@ -545,10 +565,10 @@ namespace std ...@@ -545,10 +565,10 @@ namespace std
__throw_out_of_range("basic_string::insert"); __throw_out_of_range("basic_string::insert");
const bool __testn = __n < __strsize - __pos2; const bool __testn = __n < __strsize - __pos2;
const size_type __newsize = __testn ? __n : __strsize - __pos2; const size_type __newsize = __testn ? __n : __strsize - __pos2;
return this->insert(__pos1, __str._M_data() + __pos2, __newsize); return this->insert(__pos1, __str._M_data() + __pos2, __newsize);
} }
basic_string& basic_string&
insert(size_type __pos, const _CharT* __s, size_type __n) insert(size_type __pos, const _CharT* __s, size_type __n)
{ {
const size_type __size = this->size(); const size_type __size = this->size();
...@@ -582,43 +602,43 @@ namespace std ...@@ -582,43 +602,43 @@ namespace std
} }
} }
basic_string& basic_string&
insert(size_type __pos, const _CharT* __s) insert(size_type __pos, const _CharT* __s)
{ return this->insert(__pos, __s, traits_type::length(__s)); } { return this->insert(__pos, __s, traits_type::length(__s)); }
basic_string& basic_string&
insert(size_type __pos, size_type __n, _CharT __c) insert(size_type __pos, size_type __n, _CharT __c)
{ {
this->insert(_M_check(__pos), __n, __c); this->insert(_M_check(__pos), __n, __c);
return *this; return *this;
} }
iterator iterator
insert(iterator __p, _CharT __c = _CharT()) insert(iterator __p, _CharT __c = _CharT())
{ {
size_type __pos = __p - _M_ibegin(); size_type __pos = __p - _M_ibegin();
this->insert(_M_check(__pos), size_type(1), __c); this->insert(_M_check(__pos), size_type(1), __c);
_M_rep()->_M_set_leaked(); _M_rep()->_M_set_leaked();
return this->_M_ibegin() + __pos; return this->_M_ibegin() + __pos;
} }
basic_string& basic_string&
erase(size_type __pos = 0, size_type __n = npos) erase(size_type __pos = 0, size_type __n = npos)
{ {
return this->replace(_M_check(__pos), _M_fold(__pos, __n), return this->replace(_M_check(__pos), _M_fold(__pos, __n),
_M_data(), _M_data()); _M_data(), _M_data());
} }
iterator iterator
erase(iterator __position) erase(iterator __position)
{ {
size_type __i = __position - _M_ibegin(); size_type __i = __position - _M_ibegin();
this->replace(__position, __position + 1, _M_data(), _M_data()); this->replace(__position, __position + 1, _M_data(), _M_data());
_M_rep()->_M_set_leaked(); _M_rep()->_M_set_leaked();
return _M_ibegin() + __i; return _M_ibegin() + __i;
} }
iterator iterator
erase(iterator __first, iterator __last) erase(iterator __first, iterator __last)
{ {
size_type __i = __first - _M_ibegin(); size_type __i = __first - _M_ibegin();
...@@ -627,18 +647,18 @@ namespace std ...@@ -627,18 +647,18 @@ namespace std
return _M_ibegin() + __i; return _M_ibegin() + __i;
} }
basic_string& basic_string&
replace(size_type __pos, size_type __n, const basic_string& __str) replace(size_type __pos, size_type __n, const basic_string& __str)
{ return this->replace(__pos, __n, __str._M_data(), __str.size()); } { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
basic_string& basic_string&
replace(size_type __pos1, size_type __n1, const basic_string& __str, replace(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2); size_type __pos2, size_type __n2);
basic_string& basic_string&
replace(size_type __pos, size_type __n1, const _CharT* __s, replace(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2) size_type __n2)
{ {
const size_type __size = this->size(); const size_type __size = this->size();
if (__pos > __size) if (__pos > __size)
__throw_out_of_range("basic_string::replace"); __throw_out_of_range("basic_string::replace");
...@@ -657,32 +677,32 @@ namespace std ...@@ -657,32 +677,32 @@ namespace std
typename iterator_traits<const _CharT*>::iterator_category()); typename iterator_traits<const _CharT*>::iterator_category());
} }
basic_string& basic_string&
replace(size_type __pos, size_type __n1, const _CharT* __s) replace(size_type __pos, size_type __n1, const _CharT* __s)
{ return this->replace(__pos, __n1, __s, traits_type::length(__s)); } { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
basic_string& basic_string&
replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
{ return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); } { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, const basic_string& __str) replace(iterator __i1, iterator __i2, const basic_string& __str)
{ return this->replace(__i1, __i2, __str._M_data(), __str.size()); } { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, replace(iterator __i1, iterator __i2,
const _CharT* __s, size_type __n) const _CharT* __s, size_type __n)
{ return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, const _CharT* __s) replace(iterator __i1, iterator __i2, const _CharT* __s)
{ return this->replace(__i1, __i2, __s, traits_type::length(__s)); } { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, size_type __n, _CharT __c); replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
template<class _InputIterator> template<class _InputIterator>
basic_string& basic_string&
replace(iterator __i1, iterator __i2, replace(iterator __i1, iterator __i2,
_InputIterator __k1, _InputIterator __k2) _InputIterator __k1, _InputIterator __k2)
{ return _M_replace(__i1, __i2, __k1, __k2, { return _M_replace(__i1, __i2, __k1, __k2,
...@@ -690,23 +710,23 @@ namespace std ...@@ -690,23 +710,23 @@ namespace std
// Specializations for the common case of pointer and iterator: // Specializations for the common case of pointer and iterator:
// useful to avoid the overhead of temporary buffering in _M_replace. // useful to avoid the overhead of temporary buffering in _M_replace.
basic_string& basic_string&
replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
{ return this->replace(__i1 - _M_ibegin(), __i2 - __i1, { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
__k1, __k2 - __k1); } __k1, __k2 - __k1); }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2) replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
{ return this->replace(__i1 - _M_ibegin(), __i2 - __i1, { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
__k1, __k2 - __k1); } __k1, __k2 - __k1); }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
{ return this->replace(__i1 - _M_ibegin(), __i2 - __i1, { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
__k1.base(), __k2 - __k1); __k1.base(), __k2 - __k1);
} }
basic_string& basic_string&
replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2) replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
{ return this->replace(__i1 - _M_ibegin(), __i2 - __i1, { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
__k1.base(), __k2 - __k1); __k1.base(), __k2 - __k1);
...@@ -714,13 +734,13 @@ namespace std ...@@ -714,13 +734,13 @@ namespace std
private: private:
template<class _InputIterator> template<class _InputIterator>
basic_string& basic_string&
_M_replace(iterator __i1, iterator __i2, _InputIterator __k1, _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
_InputIterator __k2, input_iterator_tag); _InputIterator __k2, input_iterator_tag);
template<class _ForwardIterator> template<class _ForwardIterator>
basic_string& basic_string&
_M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1, _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1,
_ForwardIterator __k2); _ForwardIterator __k2);
// _S_construct_aux is used to implement the 21.3.1 para 15 which // _S_construct_aux is used to implement the 21.3.1 para 15 which
...@@ -733,7 +753,7 @@ namespace std ...@@ -733,7 +753,7 @@ namespace std
typedef typename iterator_traits<_InIter>::iterator_category _Tag; typedef typename iterator_traits<_InIter>::iterator_category _Tag;
return _S_construct(__beg, __end, __a, _Tag()); return _S_construct(__beg, __end, __a, _Tag());
} }
template<class _InIter> template<class _InIter>
static _CharT* static _CharT*
_S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a, _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a,
...@@ -742,7 +762,7 @@ namespace std ...@@ -742,7 +762,7 @@ namespace std
return _S_construct(static_cast<size_type>(__beg), return _S_construct(static_cast<size_type>(__beg),
static_cast<value_type>(__end), __a); static_cast<value_type>(__end), __a);
} }
template<class _InIter> template<class _InIter>
static _CharT* static _CharT*
_S_construct(_InIter __beg, _InIter __end, const _Alloc& __a) _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a)
...@@ -756,7 +776,7 @@ namespace std ...@@ -756,7 +776,7 @@ namespace std
static _CharT* static _CharT*
_S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
input_iterator_tag); input_iterator_tag);
// For forward_iterators up to random_access_iterators, used for // For forward_iterators up to random_access_iterators, used for
// string::iterator, _CharT*, etc. // string::iterator, _CharT*, etc.
template<class _FwdIter> template<class _FwdIter>
...@@ -764,19 +784,19 @@ namespace std ...@@ -764,19 +784,19 @@ namespace std
_S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a, _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a,
forward_iterator_tag); forward_iterator_tag);
static _CharT* static _CharT*
_S_construct(size_type __req, _CharT __c, const _Alloc& __a); _S_construct(size_type __req, _CharT __c, const _Alloc& __a);
public: public:
size_type size_type
copy(_CharT* __s, size_type __n, size_type __pos = 0) const; copy(_CharT* __s, size_type __n, size_type __pos = 0) const;
void void
swap(basic_string<_CharT, _Traits, _Alloc>& __s); swap(basic_string<_CharT, _Traits, _Alloc>& __s);
// String operations: // String operations:
const _CharT* const _CharT*
c_str() const c_str() const
{ {
// MT: This assumes concurrent writes are OK. // MT: This assumes concurrent writes are OK.
...@@ -785,137 +805,137 @@ namespace std ...@@ -785,137 +805,137 @@ namespace std
return _M_data(); return _M_data();
} }
const _CharT* const _CharT*
data() const { return _M_data(); } data() const { return _M_data(); }
allocator_type allocator_type
get_allocator() const { return _M_dataplus; } get_allocator() const { return _M_dataplus; }
size_type size_type
find(const _CharT* __s, size_type __pos, size_type __n) const; find(const _CharT* __s, size_type __pos, size_type __n) const;
size_type size_type
find(const basic_string& __str, size_type __pos = 0) const find(const basic_string& __str, size_type __pos = 0) const
{ return this->find(__str.data(), __pos, __str.size()); } { return this->find(__str.data(), __pos, __str.size()); }
size_type size_type
find(const _CharT* __s, size_type __pos = 0) const find(const _CharT* __s, size_type __pos = 0) const
{ return this->find(__s, __pos, traits_type::length(__s)); } { return this->find(__s, __pos, traits_type::length(__s)); }
size_type size_type
find(_CharT __c, size_type __pos = 0) const; find(_CharT __c, size_type __pos = 0) const;
size_type size_type
rfind(const basic_string& __str, size_type __pos = npos) const rfind(const basic_string& __str, size_type __pos = npos) const
{ return this->rfind(__str.data(), __pos, __str.size()); } { return this->rfind(__str.data(), __pos, __str.size()); }
size_type size_type
rfind(const _CharT* __s, size_type __pos, size_type __n) const; rfind(const _CharT* __s, size_type __pos, size_type __n) const;
size_type size_type
rfind(const _CharT* __s, size_type __pos = npos) const rfind(const _CharT* __s, size_type __pos = npos) const
{ return this->rfind(__s, __pos, traits_type::length(__s)); } { return this->rfind(__s, __pos, traits_type::length(__s)); }
size_type size_type
rfind(_CharT __c, size_type __pos = npos) const; rfind(_CharT __c, size_type __pos = npos) const;
size_type size_type
find_first_of(const basic_string& __str, size_type __pos = 0) const find_first_of(const basic_string& __str, size_type __pos = 0) const
{ return this->find_first_of(__str.data(), __pos, __str.size()); } { return this->find_first_of(__str.data(), __pos, __str.size()); }
size_type size_type
find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
size_type size_type
find_first_of(const _CharT* __s, size_type __pos = 0) const find_first_of(const _CharT* __s, size_type __pos = 0) const
{ return this->find_first_of(__s, __pos, traits_type::length(__s)); } { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
size_type size_type
find_first_of(_CharT __c, size_type __pos = 0) const find_first_of(_CharT __c, size_type __pos = 0) const
{ return this->find(__c, __pos); } { return this->find(__c, __pos); }
size_type size_type
find_last_of(const basic_string& __str, size_type __pos = npos) const find_last_of(const basic_string& __str, size_type __pos = npos) const
{ return this->find_last_of(__str.data(), __pos, __str.size()); } { return this->find_last_of(__str.data(), __pos, __str.size()); }
size_type size_type
find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
size_type size_type
find_last_of(const _CharT* __s, size_type __pos = npos) const find_last_of(const _CharT* __s, size_type __pos = npos) const
{ return this->find_last_of(__s, __pos, traits_type::length(__s)); } { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
size_type size_type
find_last_of(_CharT __c, size_type __pos = npos) const find_last_of(_CharT __c, size_type __pos = npos) const
{ return this->rfind(__c, __pos); } { return this->rfind(__c, __pos); }
size_type size_type
find_first_not_of(const basic_string& __str, size_type __pos = 0) const find_first_not_of(const basic_string& __str, size_type __pos = 0) const
{ return this->find_first_not_of(__str.data(), __pos, __str.size()); } { return this->find_first_not_of(__str.data(), __pos, __str.size()); }
size_type size_type
find_first_not_of(const _CharT* __s, size_type __pos, find_first_not_of(const _CharT* __s, size_type __pos,
size_type __n) const; size_type __n) const;
size_type size_type
find_first_not_of(const _CharT* __s, size_type __pos = 0) const find_first_not_of(const _CharT* __s, size_type __pos = 0) const
{ return this->find_first_not_of(__s, __pos, traits_type::length(__s)); } { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
size_type size_type
find_first_not_of(_CharT __c, size_type __pos = 0) const; find_first_not_of(_CharT __c, size_type __pos = 0) const;
size_type size_type
find_last_not_of(const basic_string& __str, size_type __pos = npos) const find_last_not_of(const basic_string& __str, size_type __pos = npos) const
{ return this->find_last_not_of(__str.data(), __pos, __str.size()); } { return this->find_last_not_of(__str.data(), __pos, __str.size()); }
size_type size_type
find_last_not_of(const _CharT* __s, size_type __pos, find_last_not_of(const _CharT* __s, size_type __pos,
size_type __n) const; size_type __n) const;
size_type size_type
find_last_not_of(const _CharT* __s, size_type __pos = npos) const find_last_not_of(const _CharT* __s, size_type __pos = npos) const
{ return this->find_last_not_of(__s, __pos, traits_type::length(__s)); } { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
size_type size_type
find_last_not_of(_CharT __c, size_type __pos = npos) const; find_last_not_of(_CharT __c, size_type __pos = npos) const;
basic_string basic_string
substr(size_type __pos = 0, size_type __n = npos) const substr(size_type __pos = 0, size_type __n = npos) const
{ {
if (__pos > this->size()) if (__pos > this->size())
__throw_out_of_range("basic_string::substr"); __throw_out_of_range("basic_string::substr");
return basic_string(*this, __pos, __n); return basic_string(*this, __pos, __n);
} }
int int
compare(const basic_string& __str) const compare(const basic_string& __str) const
{ {
size_type __size = this->size(); size_type __size = this->size();
size_type __osize = __str.size(); size_type __osize = __str.size();
size_type __len = min(__size, __osize); size_type __len = min(__size, __osize);
int __r = traits_type::compare(_M_data(), __str.data(), __len); int __r = traits_type::compare(_M_data(), __str.data(), __len);
if (!__r) if (!__r)
__r = __size - __osize; __r = __size - __osize;
return __r; return __r;
} }
int int
compare(size_type __pos, size_type __n, const basic_string& __str) const; compare(size_type __pos, size_type __n, const basic_string& __str) const;
int int
compare(size_type __pos1, size_type __n1, const basic_string& __str, compare(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2) const; size_type __pos2, size_type __n2) const;
int int
compare(const _CharT* __s) const; compare(const _CharT* __s) const;
// _GLIBCPP_RESOLVE_LIB_DEFECTS // _GLIBCPP_RESOLVE_LIB_DEFECTS
// 5. String::compare specification questionable // 5. String::compare specification questionable
int int
compare(size_type __pos, size_type __n1, const _CharT* __s) const; compare(size_type __pos, size_type __n1, const _CharT* __s) const;
int int
compare(size_type __pos, size_type __n1, const _CharT* __s, compare(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2) const; size_type __n2) const;
}; };
......
...@@ -42,17 +42,21 @@ ...@@ -42,17 +42,21 @@
#pragma GCC system_header #pragma GCC system_header
#include <cstring> // For memmove, memset, memchr #include <cstring> // For memmove, memset, memchr
#include <bits/fpos.h> // For streampos #include <bits/fpos.h> // For streampos
namespace std namespace std
{ {
// 21.1.2 // 21.1
/** /**
* @brief Basis for explicit traits specializations. * @brief Basis for explicit traits specializations.
* *
* @note For any given actual character type, this definition is * @note For any given actual character type, this definition is
* probably wrong. * probably wrong.
*
* See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
* for advice on how to make use of this class for "unusual" character
* types.
*/ */
template<class _CharT> template<class _CharT>
struct char_traits struct char_traits
...@@ -108,7 +112,7 @@ namespace std ...@@ -108,7 +112,7 @@ namespace std
}; };
/// 21.1.4 char_traits specializations /// 21.1.3.1 char_traits specializations
template<> template<>
struct char_traits<char> struct char_traits<char>
{ {
...@@ -178,6 +182,7 @@ namespace std ...@@ -178,6 +182,7 @@ namespace std
#ifdef _GLIBCPP_USE_WCHAR_T #ifdef _GLIBCPP_USE_WCHAR_T
/// 21.1.3.2 char_traits specializations
template<> template<>
struct char_traits<wchar_t> struct char_traits<wchar_t>
{ {
......
...@@ -60,7 +60,9 @@ namespace std ...@@ -60,7 +60,9 @@ namespace std
typename _Alloc = allocator<_CharT> > typename _Alloc = allocator<_CharT> >
class basic_string; class basic_string;
/// 99%% of %string users only ever [need to] see the typedef.
typedef basic_string<char> string; typedef basic_string<char> string;
/// 99%% of %wstring users only ever [need to] see the typedef.
typedef basic_string<wchar_t> wstring; typedef basic_string<wchar_t> wstring;
} // namespace std } // namespace std
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment