Convert documentation to DocBook.

2008-02-10  Benjamin Kosnik  <bkoz@redhat.com>

	Convert documentation to DocBook.
	* doc/Makefile.am (doc-doxygen-html): Changed to doc-html-doxygen.
	(doc-doxygen-man): Changed to doc-man-doxygen.
	(doc-performance): Changed to doc-html-performance.
	(doc-xml-doxygen): New.
	(doc-xml-single): New.
	(doc-xml-validate): New.
	(doc-html): New.
	(doc-html-single): New.
	(doc-fo): New.
	(doc-pdf): New.
	(doc-pdf-fop-xml): New.
	(doc-pdf-fop-fo): New.
	(doc-pdf-xmlto): New.
	(doc-pdf-xmlroff): New.
	(doc-pdf-prince): New.
	* doc/xml: New directory.
	* doc/xml/authors.xml: New.
	* doc/xml/images: New directory.
	* doc/xml/images/confdeps.png: Add.
	* doc/xml/images/confdeps.dot: Add.
	* doc/xml/faq.xml: New.
	* doc/xml/api.xml: New.
	* doc/xml/gnu: New directory.
	* doc/xml/gnu/gpl-3.0.xml: New.
	* doc/xml/gnu/fdl-1.2.xml: New.
	* doc/xml/gnu/gpl-2.0.xml: New.
	* doc/xml/manual: New directory.
	* doc/xml/manual/mt_allocator.xml: New.
	* doc/xml/manual/allocator.xml: New.
	* doc/xml/manual/ctype.xml: New.
	* doc/xml/manual/numerics.xml: New.
	* doc/xml/manual/codecvt.xml: New.
	* doc/xml/manual/concurrency.xml: New.
	* doc/xml/manual/backwards_compatibility.xml: New.
	* doc/xml/manual/intro.xml: New.
	* doc/xml/manual/shared_ptr.xml: New.
	* doc/xml/manual/abi.xml: New.
	* doc/xml/manual/status_cxxtr1.xml: New.
	* doc/xml/manual/auto_ptr.xml: New.
	* doc/xml/manual/build.xml: New.
	* doc/xml/manual/internals.xml: New.
	* doc/xml/manual/parallel_mode.xml: New.
	* doc/xml/manual/status_cxx1998.xml: New.
	* doc/xml/manual/containers.xml: New.
	* doc/xml/manual/io.xml: New.
	* doc/xml/manual/appendix_porting.xml: New.
	* doc/xml/manual/utilities.xml: New.
	* doc/xml/manual/bitmap_allocator.xml: New.
	* doc/xml/manual/support.xml: New.
	* doc/xml/manual/configure.xml: New.
	* doc/xml/manual/build_hacking.xml: New.
	* doc/xml/manual/evolution.xml: New.
	* doc/xml/manual/using.xml: New.
	* doc/xml/manual/debug.xml: New.
	* doc/xml/manual/localization.xml: New.
	* doc/xml/manual/strings.xml: New.
	* doc/xml/manual/debug_mode.xml: New.
	* doc/xml/manual/locale.xml: New.
	* doc/xml/manual/extensions.xml: New.
	* doc/xml/manual/appendix_contributing.xml: New.
	* doc/xml/manual/messages.xml: New.
	* doc/xml/manual/diagnostics.xml: New.
	* doc/xml/manual/appendix_free.xml: New.
	* doc/xml/manual/algorithms.xml: New.
	* doc/xml/manual/iterators.xml: New.
	* doc/xml/manual/spine.xml: New.
	* doc/xml/manual/test.xml: New.
	* doc/xml/manual/status_cxx200x.xml: New.
	* doc/xml/spine.xml: New.

	* doc/xml/book.txml: New. Template file.
	* doc/xml/chapter.txml: Same.
	* doc/xml/class.txml: Same.

	* doc/doxygen/guide.html: Removed, integrated into other docs.
	* doc/doxygen/user.cfg.in: Clean up XML generation.
	* doc/doxygen/run_doxygen: Move to..	
	* scripts/run_doxygen: ...here.
	
	* configure: Regenerate.
	* Makefile.in: Regenerate.
	* src/Makefile.in: Regenerate.
	* doc/Makefile.in: Regenerate.	
	* po/Makefile.in: Regenerate.
	* libmath/Makefile.in: Regenerate.
	* include/Makefile.in: Regenerate.
	* libsupc++/Makefile.in: Regenerate.
	* testsuite/Makefile.in: Regenerate.
	* aclocal.m4: Regenerate.

From-SVN: r132226
This commit is contained in:
Benjamin Kosnik 2008-02-11 00:01:33 +00:00 committed by Benjamin Kosnik
parent 71a9ddca7a
commit 8a165db0c0
68 changed files with 63083 additions and 35051 deletions

View file

@ -1,3 +1,96 @@
2008-02-10 Benjamin Kosnik <bkoz@redhat.com>
Convert documentation to DocBook.
* doc/Makefile.am (doc-doxygen-html): Changed to doc-html-doxygen.
(doc-doxygen-man): Changed to doc-man-doxygen.
(doc-performance): Changed to doc-html-performance.
(doc-xml-doxygen): New.
(doc-xml-single): New.
(doc-xml-validate): New.
(doc-html): New.
(doc-html-single): New.
(doc-fo): New.
(doc-pdf): New.
(doc-pdf-fop-xml): New.
(doc-pdf-fop-fo): New.
(doc-pdf-xmlto): New.
(doc-pdf-xmlroff): New.
(doc-pdf-prince): New.
* doc/xml: New directory.
* doc/xml/authors.xml: New.
* doc/xml/images: New directory.
* doc/xml/images/confdeps.png: Add.
* doc/xml/images/confdeps.dot: Add.
* doc/xml/faq.xml: New.
* doc/xml/api.xml: New.
* doc/xml/gnu: New directory.
* doc/xml/gnu/gpl-3.0.xml: New.
* doc/xml/gnu/fdl-1.2.xml: New.
* doc/xml/gnu/gpl-2.0.xml: New.
* doc/xml/manual: New directory.
* doc/xml/manual/mt_allocator.xml: New.
* doc/xml/manual/allocator.xml: New.
* doc/xml/manual/ctype.xml: New.
* doc/xml/manual/numerics.xml: New.
* doc/xml/manual/codecvt.xml: New.
* doc/xml/manual/concurrency.xml: New.
* doc/xml/manual/backwards_compatibility.xml: New.
* doc/xml/manual/intro.xml: New.
* doc/xml/manual/shared_ptr.xml: New.
* doc/xml/manual/abi.xml: New.
* doc/xml/manual/status_cxxtr1.xml: New.
* doc/xml/manual/auto_ptr.xml: New.
* doc/xml/manual/build.xml: New.
* doc/xml/manual/internals.xml: New.
* doc/xml/manual/parallel_mode.xml: New.
* doc/xml/manual/status_cxx1998.xml: New.
* doc/xml/manual/containers.xml: New.
* doc/xml/manual/io.xml: New.
* doc/xml/manual/appendix_porting.xml: New.
* doc/xml/manual/utilities.xml: New.
* doc/xml/manual/bitmap_allocator.xml: New.
* doc/xml/manual/support.xml: New.
* doc/xml/manual/configure.xml: New.
* doc/xml/manual/build_hacking.xml: New.
* doc/xml/manual/evolution.xml: New.
* doc/xml/manual/using.xml: New.
* doc/xml/manual/debug.xml: New.
* doc/xml/manual/localization.xml: New.
* doc/xml/manual/strings.xml: New.
* doc/xml/manual/debug_mode.xml: New.
* doc/xml/manual/locale.xml: New.
* doc/xml/manual/extensions.xml: New.
* doc/xml/manual/appendix_contributing.xml: New.
* doc/xml/manual/messages.xml: New.
* doc/xml/manual/diagnostics.xml: New.
* doc/xml/manual/appendix_free.xml: New.
* doc/xml/manual/algorithms.xml: New.
* doc/xml/manual/iterators.xml: New.
* doc/xml/manual/spine.xml: New.
* doc/xml/manual/test.xml: New.
* doc/xml/manual/status_cxx200x.xml: New.
* doc/xml/spine.xml: New.
* doc/xml/book.txml: New. Template file.
* doc/xml/chapter.txml: Same.
* doc/xml/class.txml: Same.
* doc/doxygen/guide.html: Removed, integrated into other docs.
* doc/doxygen/user.cfg.in: Clean up XML generation
* doc/doxygen/run_doxygen: Move to..
* scripts/run_doxygen: ...here.
* configure: Regenerate.
* Makefile.in: Regenerate.
* src/Makefile.in: Regenerate.
* doc/Makefile.in: Regenerate.
* po/Makefile.in: Regenerate.
* libmath/Makefile.in: Regenerate.
* include/Makefile.in: Regenerate.
* libsupc++/Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.
* aclocal.m4: Regenerate.
2008-02-10 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/16251

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -13,15 +13,11 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -63,7 +59,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
configure.lineno config.status.lineno
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = scripts/testsuite_flags
depcomp =
@ -78,10 +74,13 @@ MULTIDO = true
MULTICLEAN = true
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = include libsupc++ libmath doc src po testsuite
@ -142,42 +141,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -194,9 +164,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -222,13 +191,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -239,8 +208,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -260,29 +233,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -397,7 +377,7 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@ -438,7 +418,6 @@ distclean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
maintainer-clean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
@ -471,8 +450,7 @@ $(RECURSIVE_TARGETS):
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
$(RECURSIVE_CLEAN_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
@ -545,24 +523,22 @@ distclean-tags:
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkdir_p) $(distdir)/.. $(distdir)/../config $(distdir)/scripts
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
test -d $(distdir) || mkdir $(distdir)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -576,7 +552,7 @@ distdir: $(DISTFILES)
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
@ -584,6 +560,8 @@ distdir: $(DISTFILES)
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
am__remove_distdir=: \
am__skip_length_check=: \
distdir) \
|| exit 1; \
fi; \
@ -591,7 +569,7 @@ distdir: $(DISTFILES)
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
@ -666,7 +644,7 @@ distcheck: dist
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
@ -736,12 +714,20 @@ info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-exec-am: install-multi
install-html: install-html-recursive
install-info: install-info-recursive
install-man:
install-pdf: install-pdf-recursive
install-ps: install-ps-recursive
installcheck-am:
maintainer-clean: maintainer-clean-multi maintainer-clean-recursive
@ -762,26 +748,29 @@ ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-am:
uninstall-info: uninstall-info-recursive
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all-multi \
clean-multi distclean-multi install-am install-multi \
install-strip maintainer-clean-multi mostlyclean-multi
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am all-multi \
am--refresh check check-am clean clean-generic clean-libtool \
clean-multi clean-recursive ctags ctags-recursive dist \
dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip \
distcheck distclean distclean-generic distclean-hdr \
distclean-libtool distclean-multi distclean-recursive \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man install-multi \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
maintainer-clean-multi maintainer-clean-recursive mostlyclean \
mostlyclean-generic mostlyclean-libtool mostlyclean-multi \
mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am uninstall-info-am
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am all-multi am--refresh check check-am clean \
clean-generic clean-libtool clean-multi ctags ctags-recursive \
dist dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ \
dist-zip distcheck distclean distclean-generic distclean-hdr \
distclean-libtool distclean-multi distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-multi install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic \
maintainer-clean-multi mostlyclean mostlyclean-generic \
mostlyclean-libtool mostlyclean-multi pdf pdf-am ps ps-am tags \
tags-recursive uninstall uninstall-am
# Handy forwarding targets.

View file

@ -1,7 +1,7 @@
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
# generated automatically by aclocal 1.10 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005 Free Software Foundation, Inc.
# 2005, 2006 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -11,7 +11,12 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
m4_if(m4_PACKAGE_VERSION, [2.61],,
[m4_fatal([this file was generated for autoconf 2.61.
You have another version of autoconf. If you want to use that,
you should regenerate the build system entirely.], [63])])
# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -21,14 +26,29 @@
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.10'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.10], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
# _AM_AUTOCONF_VERSION(VERSION)
# -----------------------------
# aclocal traces this macro to find the Autoconf version.
# This is a private macro too. Using m4_define simplifies
# the logic in aclocal, which can simply ignore this definition.
m4_define([_AM_AUTOCONF_VERSION], [])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.9.6])])
[AM_AUTOMAKE_VERSION([1.10])dnl
_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
@ -85,14 +105,14 @@ am_aux_dir=`cd $ac_aux_dir && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 7
# serial 8
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
@ -101,8 +121,10 @@ AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
if $2; then
$1_TRUE=
$1_FALSE='#'
@ -118,8 +140,8 @@ fi])])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -142,16 +164,20 @@ fi])])
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.58])dnl
[AC_PREREQ([2.60])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
# test to see if srcdir already configured
if test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
fi
# test whether we have cygpath
@ -171,6 +197,9 @@ m4_ifval([$2],
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
@ -206,6 +235,10 @@ AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES(OBJC)],
[define([AC_PROG_OBJC],
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
])
])
@ -241,7 +274,7 @@ echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
@ -275,14 +308,14 @@ AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 4
# serial 5
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
@ -298,6 +331,7 @@ AC_SUBST($1)])
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
@ -308,7 +342,7 @@ else
fi
])
# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -316,60 +350,23 @@ fi
# AM_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
#
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
# This was a mistake. There are at least two reasons why we must not
# use `-m 0755':
# - it causes special bits like SGID to be ignored,
# - it may be too restrictive (some setups expect 775 directories).
#
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
# Some implementations (such as Solaris 8's) are not thread-safe: if a
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to GNU make (using the --version option ensures
# this.)
# Check for `mkdir -p'.
AC_DEFUN([AM_PROG_MKDIR_P],
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
# We used to keeping the `.' as first argument, in order to
# allow $(mkdir_p) to be used without argument. As in
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined. However this is wrong
# for two reasons:
# 1. if the package is installed by a user who cannot write `.'
# make install will fail,
# 2. the above comment should most certainly read
# $(mkdir_p) $(DESTDIR)$(somedir)
# so it does not work when $(somedir) is undefined and
# $(DESTDIR) is not.
# To support the latter case, we have to write
# test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
# so the `.' trick is pointless.
mkdir_p='mkdir -p --'
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
for d in ./-p ./--version;
do
test -d $d && rmdir $d
done
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
if test -f "$ac_aux_dir/mkinstalldirs"; then
mkdir_p='$(mkinstalldirs)'
else
mkdir_p='$(install_sh) -d'
fi
fi
AC_SUBST([mkdir_p])])
[AC_PREREQ([2.60])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
dnl while keeping a definition of mkdir_p for backward compatibility.
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
dnl Makefile.ins that do not define MKDIR_P, so we do our own
dnl adjustment using top_builddir (which is defined more often than
dnl MKDIR_P).
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
case $mkdir_p in
[[\\/$]]* | ?:[[\\/]]*) ;;
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
esac
])
# Helper functions for option handling. -*- Autoconf -*-
@ -481,9 +478,21 @@ dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.

62911
libstdc++-v3/configure vendored

File diff suppressed because it is too large Load diff

View file

@ -23,28 +23,210 @@
include $(top_srcdir)/fragment.am
# These rules are messy, but are hella worth it.
doc-doxygen-html:
# Doxygen configuration
# Assumes doxygen, graphviz (with dot) installed
doc_doxygen_script=${top_srcdir}/scripts/run_doxygen
doc-html-doxygen:
-(srcdir=`cd ${top_srcdir}; ${PWD_COMMAND}`; \
builddir=`cd ..; ${PWD_COMMAND}`; \
${SHELL} ${top_srcdir}/doc/doxygen/run_doxygen \
${SHELL} ${doc_doxygen_script} \
--host_alias=${host_alias} --mode=html $${srcdir} $${builddir})
doc-doxygen-man:
doc-man-doxygen:
-(srcdir=`cd ${top_srcdir}; ${PWD_COMMAND}`; \
builddir=`cd ..; ${PWD_COMMAND}`; \
${SHELL} ${top_srcdir}/doc/doxygen/run_doxygen \
${SHELL} ${doc_doxygen_script} \
--host_alias=${host_alias} --mode=man $${srcdir} $${builddir})
doc-xml-doxygen:
-(srcdir=`cd ${top_srcdir}; ${PWD_COMMAND}`; \
builddir=`cd ..; ${PWD_COMMAND}`; \
${SHELL} ${doc_doxygen_script} \
--host_alias=${host_alias} --mode=xml $${srcdir} $${builddir})
doxygen_xmldir = ${glibcxx_builddir}/doc/doxygen/xml
doc-xml-doxygen-single: doc-xml-doxygen
@echo "Generating doxygen xml single file..."
$(XSLTPROC) ${doxygen_xmldir}/combine.xslt ${doxygen_xmldir}/spine.xml > ${doxygen_xmldir}/all.xml;
# Performance doc and graph configuration.
# Assumes pychart, beautiful soup installed.
# Generates the plots and graphs for performance testing.
doc_performance_script=${top_srcdir}/scripts/make_graphs.py
doc-performance:
doc-html-performance:
-@(chmod + ${doc_performance_script}; \
${doc_performance_script} ${top_srcdir} \
${glibcxx_builddir}/testsuite \
${top_srcdir}/testsuite/data/make_graph_htmls.xml \
${top_srcdir}/testsuite/data/make_graph_test_infos.xml local g++)
# Docbook configuration.
# Assumes
# libxslt
# docbook-style-xsl
# emacs-nxml-mode
# xmlto passivetex
xml_srcdir = ${glibcxx_srcdir}/doc/xml
xml_sources = \
${xml_srcdir}/spine.xml \
${xml_srcdir}/authors.xml \
${xml_srcdir}/manual/spine.xml \
${xml_srcdir}/manual/abi.xml \
${xml_srcdir}/manual/algorithms.xml \
${xml_srcdir}/manual/allocator.xml \
${xml_srcdir}/manual/auto_ptr.xml \
${xml_srcdir}/manual/backwards_compatibility.xml \
${xml_srcdir}/manual/bitmap_allocator.xml \
${xml_srcdir}/manual/build.xml \
${xml_srcdir}/manual/build_hacking.xml \
${xml_srcdir}/manual/codecvt.xml \
${xml_srcdir}/manual/concurrency.xml \
${xml_srcdir}/manual/configure.xml \
${xml_srcdir}/manual/containers.xml \
${xml_srcdir}/manual/ctype.xml \
${xml_srcdir}/manual/debug_mode.xml \
${xml_srcdir}/manual/debug.xml \
${xml_srcdir}/manual/diagnostics.xml \
${xml_srcdir}/manual/evolution.xml \
${xml_srcdir}/manual/extensions.xml \
${xml_srcdir}/manual/internals.xml \
${xml_srcdir}/manual/intro.xml \
${xml_srcdir}/manual/io.xml \
${xml_srcdir}/manual/iterators.xml \
${xml_srcdir}/manual/locale.xml \
${xml_srcdir}/manual/localization.xml \
${xml_srcdir}/manual/messages.xml \
${xml_srcdir}/manual/mt_allocator.xml \
${xml_srcdir}/manual/numerics.xml \
${xml_srcdir}/manual/parallel_mode.xml \
${xml_srcdir}/manual/internals.xml \
${xml_srcdir}/manual/shared_ptr.xml \
${xml_srcdir}/manual/spine.xml \
${xml_srcdir}/manual/status_cxx1998.xml \
${xml_srcdir}/manual/status_cxx200x.xml \
${xml_srcdir}/manual/status_cxxtr1.xml \
${xml_srcdir}/manual/strings.xml \
${xml_srcdir}/manual/support.xml \
${xml_srcdir}/manual/test.xml \
${xml_srcdir}/manual/using.xml \
${xml_srcdir}/manual/utilities.xml \
${xml_srcdir}/manual/appendix_free.xml \
${xml_srcdir}/manual/appendix_contributing.xml \
${xml_srcdir}/manual/appendix_porting.xml \
${xml_srcdir}/api.xml \
${xml_srcdir}/faq.xml
xml_sources_extra = \
${xml_srcdir}/gnu/fdl-1.2.xml \
${xml_srcdir}/gnu/gpl-2.0.xml
xml_noinst = \
${xml_srcdir}/book.txml \
${xml_srcdir}/chapter.txml \
${xml_srcdir}/class.txml
XSLTPROC = xsltproc
XSLTPROC_FLAGS = --nonet --xinclude
XSL_STYLE_DIR = /usr/share/sgml/docbook/xsl-stylesheets
XSL_FO_STYLE = $(XSL_STYLE_DIR)/fo/docbook.xsl
XSL_HTML_STYLE = $(XSL_STYLE_DIR)/xhtml/chunk.xsl
#XSL_HTML_SINGLE_STYLE = $(XSL_STYLE_DIR)/xhtml/onechunk.xsl
XSL_HTML_SINGLE_STYLE = $(XSL_STYLE_DIR)/xhtml/docbook.xsl
${glibcxx_builddir}/doc/html:
mkdir ${glibcxx_builddir}/doc/html
${glibcxx_builddir}/doc/pdf:
mkdir ${glibcxx_builddir}/doc/pdf
${glibcxx_builddir}/doc/fo:
mkdir ${glibcxx_builddir}/doc/fo
${glibcxx_builddir}/doc/xml:
mkdir ${glibcxx_builddir}/doc/xml
# Validate existing XML structure.
XMLLINT = xmllint
#LINT_FLAGS = --debug --nonet --xinclude --nsclean --postvalid --nowarning
#LINT_FLAGS = --noblanks --noout --xinclude --postvalid --noent
LINT_FLAGS = --postvalid --debug --xinclude --noent --noblanks --nonet --noout
VALID_FLAGS = --dtdvalid http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd
XMLLINT_FLAGS = $(LINT_FLAGS) $(VALID_FLAGS)
doc-xml-validate: $(xml_sources)
@echo "Generating XML validation log..."
$(XMLLINT) $(XMLLINT_FLAGS) ${top_srcdir}/doc/xml/spine.xml
doc-xml-single: $(xml_sources) ${glibcxx_builddir}/doc/xml
@echo "Generating XML single..."
$(XMLLINT) --xinclude --noent --noblanks \
-o ${glibcxx_builddir}/doc/xml/spine-single.xml \
${top_srcdir}/doc/xml/spine.xml
# HTML, index plus chapters
doc-html: $(xml_sources) ${glibcxx_builddir}/doc/html
@echo "Generating html files..."
$(XSLTPROC) $(XSLTPROC_FLAGS) -o ${glibcxx_builddir}/doc/html/ \
$(XSL_HTML_STYLE) ${top_srcdir}/doc/xml/spine.xml
# HTML, all one page
doc-html-single: $(xml_sources) ${glibcxx_builddir}/doc/html
@echo "Generating html single file..."
$(XSLTPROC) $(XSLTPROC_FLAGS) -o ${glibcxx_builddir}/doc/html/ \
$(XSL_HTML_SINGLE_STYLE) ${top_srcdir}/doc/xml/spine.xml
# FO
doc-fo: $(xml_sources) ${glibcxx_builddir}/doc/fo
@echo "Generating FO files..."
$(XSLTPROC) $(XSLTPROC_FLAGS) -o ${glibcxx_builddir}/doc/fo/spine.fo \
$(XSL_FO_STYLE) ${top_srcdir}/doc/xml/spine.xml
# PDF
# Points to current best xml to PDF generation process.
doc-pdf: doc-pdf-xmlto
# PDF 1
# fop
FOP = fop
FOP_FLAGS = -d -r
doc-pdf-fop-xml: $(xml_sources) ${glibcxx_builddir}/doc/pdf
@echo "Generating pdf fop files from xml..."
$(FOP) $(FOP_FLAGS) -xml ${top_srcdir}/doc/xml/spine.xml \
-xsl $(XSL_FO_STYLE) -pdf ${glibcxx_builddir}/doc/pdf/spine.pdf
doc-pdf-fop-fo: $(xml_sources) ${glibcxx_builddir}/doc/pdf doc-fo
@echo "Generating pdf fop files from fo..."
$(FOP) $(FOP_FLAGS) -fo ${glibcxx_builddir}/doc/fo/spine.fo \
-pdf ${glibcxx_builddir}/doc/pdf/spine.pdf
# PDF 2
# xmlto
XML2PDF = xmlto
XML2PDF_FLAGS = -v pdf --skip-validation -o pdf
doc-pdf-xmlto: $(xml_sources) ${glibcxx_builddir}/doc/pdf
@echo "Generating pdf xmlto files..."
$(XML2PDF) $(XML2PDF_FLAGS) ${top_srcdir}/doc/xml/spine.xml
# PDF 3
# xmlroff
XMLROFF = xmlroff
XMLROFF_FLAGS = --format=pdf --backend=cairo --warn=1 --debug=1 --continue
doc-pdf-xmlroff: $(xml_sources) doc-fo
@echo "Generating pdf xmlroff files..."
$(XMLROFF) $(XMLROFF_FLAGS) ${glibcxx_builddir}/doc/fo/spine.fo
# PDF 4
# prince
PRINCE = prince
PRINCE_FLAGS = --log prince.log -o pdf/spine.pdf
doc-pdf-prince: $(xml_sources) ${glibcxx_builddir}/doc/pdf
@echo "Generating pdf prince files..."
$(PRINCE) $(PRINCE_FLAGS) ${top_srcdir}/doc/xml/spine.xml
# No install-pdf, install-html support in automake yet
install-pdf:
install-html:
@ -55,8 +237,8 @@ install-html:
doc-doxygen-html doc-doxygen-man doc-performance
# By adding these files here, automake will remove them for 'make clean'
CLEANFILES =
CLEANFILES = *.log
# To remove directories.
clean-local:
rm -rf man doxygen
rm -rf man html pdf fo doxygen xml

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -13,15 +13,11 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -110,42 +106,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -162,9 +129,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -190,13 +156,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -207,8 +173,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -228,29 +198,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -274,11 +251,119 @@ WARN_CXXFLAGS = \
# -I/-D flags to pass when compiling.
AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
# Doxygen configuration
# Assumes doxygen, graphviz (with dot) installed
doc_doxygen_script = ${top_srcdir}/scripts/run_doxygen
doxygen_xmldir = ${glibcxx_builddir}/doc/doxygen/xml
# Performance doc and graph configuration.
# Assumes pychart, beautiful soup installed.
# Generates the plots and graphs for performance testing.
doc_performance_script = ${top_srcdir}/scripts/make_graphs.py
# Docbook configuration.
# Assumes
# libxslt
# docbook-style-xsl
# emacs-nxml-mode
# xmlto passivetex
xml_srcdir = ${glibcxx_srcdir}/doc/xml
xml_sources = \
${xml_srcdir}/spine.xml \
${xml_srcdir}/authors.xml \
${xml_srcdir}/manual/spine.xml \
${xml_srcdir}/manual/abi.xml \
${xml_srcdir}/manual/algorithms.xml \
${xml_srcdir}/manual/allocator.xml \
${xml_srcdir}/manual/auto_ptr.xml \
${xml_srcdir}/manual/backwards_compatibility.xml \
${xml_srcdir}/manual/bitmap_allocator.xml \
${xml_srcdir}/manual/build.xml \
${xml_srcdir}/manual/build_hacking.xml \
${xml_srcdir}/manual/codecvt.xml \
${xml_srcdir}/manual/concurrency.xml \
${xml_srcdir}/manual/configure.xml \
${xml_srcdir}/manual/containers.xml \
${xml_srcdir}/manual/ctype.xml \
${xml_srcdir}/manual/debug_mode.xml \
${xml_srcdir}/manual/debug.xml \
${xml_srcdir}/manual/diagnostics.xml \
${xml_srcdir}/manual/evolution.xml \
${xml_srcdir}/manual/extensions.xml \
${xml_srcdir}/manual/internals.xml \
${xml_srcdir}/manual/intro.xml \
${xml_srcdir}/manual/io.xml \
${xml_srcdir}/manual/iterators.xml \
${xml_srcdir}/manual/locale.xml \
${xml_srcdir}/manual/localization.xml \
${xml_srcdir}/manual/messages.xml \
${xml_srcdir}/manual/mt_allocator.xml \
${xml_srcdir}/manual/numerics.xml \
${xml_srcdir}/manual/parallel_mode.xml \
${xml_srcdir}/manual/internals.xml \
${xml_srcdir}/manual/shared_ptr.xml \
${xml_srcdir}/manual/spine.xml \
${xml_srcdir}/manual/status_cxx1998.xml \
${xml_srcdir}/manual/status_cxx200x.xml \
${xml_srcdir}/manual/status_cxxtr1.xml \
${xml_srcdir}/manual/strings.xml \
${xml_srcdir}/manual/support.xml \
${xml_srcdir}/manual/test.xml \
${xml_srcdir}/manual/using.xml \
${xml_srcdir}/manual/utilities.xml \
${xml_srcdir}/manual/appendix_free.xml \
${xml_srcdir}/manual/appendix_contributing.xml \
${xml_srcdir}/manual/appendix_porting.xml \
${xml_srcdir}/api.xml \
${xml_srcdir}/faq.xml
xml_sources_extra = \
${xml_srcdir}/gnu/fdl-1.2.xml \
${xml_srcdir}/gnu/gpl-2.0.xml
xml_noinst = \
${xml_srcdir}/book.txml \
${xml_srcdir}/chapter.txml \
${xml_srcdir}/class.txml
XSLTPROC = xsltproc
XSLTPROC_FLAGS = --nonet --xinclude
XSL_STYLE_DIR = /usr/share/sgml/docbook/xsl-stylesheets
XSL_FO_STYLE = $(XSL_STYLE_DIR)/fo/docbook.xsl
XSL_HTML_STYLE = $(XSL_STYLE_DIR)/xhtml/chunk.xsl
#XSL_HTML_SINGLE_STYLE = $(XSL_STYLE_DIR)/xhtml/onechunk.xsl
XSL_HTML_SINGLE_STYLE = $(XSL_STYLE_DIR)/xhtml/docbook.xsl
# Validate existing XML structure.
XMLLINT = xmllint
#LINT_FLAGS = --debug --nonet --xinclude --nsclean --postvalid --nowarning
#LINT_FLAGS = --noblanks --noout --xinclude --postvalid --noent
LINT_FLAGS = --postvalid --debug --xinclude --noent --noblanks --nonet --noout
VALID_FLAGS = --dtdvalid http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd
XMLLINT_FLAGS = $(LINT_FLAGS) $(VALID_FLAGS)
# PDF 1
# fop
FOP = fop
FOP_FLAGS = -d -r
# PDF 2
# xmlto
XML2PDF = xmlto
XML2PDF_FLAGS = -v pdf --skip-validation -o pdf
# PDF 3
# xmlroff
XMLROFF = xmlroff
XMLROFF_FLAGS = --format=pdf --backend=cairo --warn=1 --debug=1 --continue
# PDF 4
# prince
PRINCE = prince
PRINCE_FLAGS = --log prince.log -o pdf/spine.pdf
# By adding these files here, automake will remove them for 'make clean'
CLEANFILES =
CLEANFILES = *.log
all: all-am
.SUFFIXES:
@ -317,10 +402,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
tags: TAGS
TAGS:
@ -329,23 +410,21 @@ CTAGS:
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -391,7 +470,7 @@ clean-am: clean-generic clean-libtool clean-local mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool
distclean-am: clean-am distclean-generic
dvi: dvi-am
@ -405,12 +484,16 @@ info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am:
install-info: install-info-am
install-man:
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -429,38 +512,110 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
clean-local distclean distclean-generic distclean-libtool \
distdir dvi dvi-am html html-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-info-am
uninstall uninstall-am
# These rules are messy, but are hella worth it.
doc-doxygen-html:
doc-html-doxygen:
-(srcdir=`cd ${top_srcdir}; ${PWD_COMMAND}`; \
builddir=`cd ..; ${PWD_COMMAND}`; \
${SHELL} ${top_srcdir}/doc/doxygen/run_doxygen \
${SHELL} ${doc_doxygen_script} \
--host_alias=${host_alias} --mode=html $${srcdir} $${builddir})
doc-doxygen-man:
doc-man-doxygen:
-(srcdir=`cd ${top_srcdir}; ${PWD_COMMAND}`; \
builddir=`cd ..; ${PWD_COMMAND}`; \
${SHELL} ${top_srcdir}/doc/doxygen/run_doxygen \
${SHELL} ${doc_doxygen_script} \
--host_alias=${host_alias} --mode=man $${srcdir} $${builddir})
doc-performance:
doc-xml-doxygen:
-(srcdir=`cd ${top_srcdir}; ${PWD_COMMAND}`; \
builddir=`cd ..; ${PWD_COMMAND}`; \
${SHELL} ${doc_doxygen_script} \
--host_alias=${host_alias} --mode=xml $${srcdir} $${builddir})
doc-xml-doxygen-single: doc-xml-doxygen
@echo "Generating doxygen xml single file..."
$(XSLTPROC) ${doxygen_xmldir}/combine.xslt ${doxygen_xmldir}/spine.xml > ${doxygen_xmldir}/all.xml;
doc-html-performance:
-@(chmod + ${doc_performance_script}; \
${doc_performance_script} ${top_srcdir} \
${glibcxx_builddir}/testsuite \
${top_srcdir}/testsuite/data/make_graph_htmls.xml \
${top_srcdir}/testsuite/data/make_graph_test_infos.xml local g++)
${glibcxx_builddir}/doc/html:
mkdir ${glibcxx_builddir}/doc/html
${glibcxx_builddir}/doc/pdf:
mkdir ${glibcxx_builddir}/doc/pdf
${glibcxx_builddir}/doc/fo:
mkdir ${glibcxx_builddir}/doc/fo
${glibcxx_builddir}/doc/xml:
mkdir ${glibcxx_builddir}/doc/xml
doc-xml-validate: $(xml_sources)
@echo "Generating XML validation log..."
$(XMLLINT) $(XMLLINT_FLAGS) ${top_srcdir}/doc/xml/spine.xml
doc-xml-single: $(xml_sources) ${glibcxx_builddir}/doc/xml
@echo "Generating XML single..."
$(XMLLINT) --xinclude --noent --noblanks \
-o ${glibcxx_builddir}/doc/xml/spine-single.xml \
${top_srcdir}/doc/xml/spine.xml
# HTML, index plus chapters
doc-html: $(xml_sources) ${glibcxx_builddir}/doc/html
@echo "Generating html files..."
$(XSLTPROC) $(XSLTPROC_FLAGS) -o ${glibcxx_builddir}/doc/html/ \
$(XSL_HTML_STYLE) ${top_srcdir}/doc/xml/spine.xml
# HTML, all one page
doc-html-single: $(xml_sources) ${glibcxx_builddir}/doc/html
@echo "Generating html single file..."
$(XSLTPROC) $(XSLTPROC_FLAGS) -o ${glibcxx_builddir}/doc/html/ \
$(XSL_HTML_SINGLE_STYLE) ${top_srcdir}/doc/xml/spine.xml
# FO
doc-fo: $(xml_sources) ${glibcxx_builddir}/doc/fo
@echo "Generating FO files..."
$(XSLTPROC) $(XSLTPROC_FLAGS) -o ${glibcxx_builddir}/doc/fo/spine.fo \
$(XSL_FO_STYLE) ${top_srcdir}/doc/xml/spine.xml
# PDF
# Points to current best xml to PDF generation process.
doc-pdf: doc-pdf-xmlto
doc-pdf-fop-xml: $(xml_sources) ${glibcxx_builddir}/doc/pdf
@echo "Generating pdf fop files from xml..."
$(FOP) $(FOP_FLAGS) -xml ${top_srcdir}/doc/xml/spine.xml \
-xsl $(XSL_FO_STYLE) -pdf ${glibcxx_builddir}/doc/pdf/spine.pdf
doc-pdf-fop-fo: $(xml_sources) ${glibcxx_builddir}/doc/pdf doc-fo
@echo "Generating pdf fop files from fo..."
$(FOP) $(FOP_FLAGS) -fo ${glibcxx_builddir}/doc/fo/spine.fo \
-pdf ${glibcxx_builddir}/doc/pdf/spine.pdf
doc-pdf-xmlto: $(xml_sources) ${glibcxx_builddir}/doc/pdf
@echo "Generating pdf xmlto files..."
$(XML2PDF) $(XML2PDF_FLAGS) ${top_srcdir}/doc/xml/spine.xml
doc-pdf-xmlroff: $(xml_sources) doc-fo
@echo "Generating pdf xmlroff files..."
$(XMLROFF) $(XMLROFF_FLAGS) ${glibcxx_builddir}/doc/fo/spine.fo
doc-pdf-prince: $(xml_sources) ${glibcxx_builddir}/doc/pdf
@echo "Generating pdf prince files..."
$(PRINCE) $(PRINCE_FLAGS) ${top_srcdir}/doc/xml/spine.xml
# No install-pdf, install-html support in automake yet
install-pdf:
install-html:
@ -472,7 +627,7 @@ install-html:
# To remove directories.
clean-local:
rm -rf man doxygen
rm -rf man html pdf fo doxygen xml
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View file

@ -1,111 +0,0 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Build and Writing Guide for libstdc++ Doxygen</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="#ffffff">
<h1>libstdc++ Source Documentation</h1>
<p>This file is docs/doxygen/guide.html in the libstdc++ source tree. It
is not included in the generated pages (no real point to doing that).
</p>
<ul>
<li><a href="#creating">Creating the pages</a></li>
<li><a href="#writing">Writing the markup</a></li>
</ul>
<hr />
<a name="creating"><h2>Creating the pages</h2></a>
<p>The Makefile rules <code>'make doc-doxygen-html'</code>,
and <code>'make doc-doxygen-man'</code> in the libstdc++ build
directory generate the HTML docs, the and the man pages,
respectively. Prerequisite tools are Bash 2.x,
<a href="http://www.doxygen.org/">
<!-- snagged from the generated page -->
<img src="doxygen.png" alt="Doxygen" align=center border=0 width=110 height=53>
</a>, a working version of <code>g++</code> somewhere in the PATH, and
the <a href="http://www.gnu.org/software/coreutils/">GNU coreutils</a>.
In addition, to generate the pretty pictures and hierarchy graphs, the
<a href=
"http://www.research.att.com/sw/tools/graphviz/download.html">Graphviz</a>
package will need to be installed.
(g++ is used to build a program which manipulates man pages. GNU versions
of find, xargs, and possibly sed and grep are used, just because the GNU
versions make things very easy.)
</p>
<p>Careful observers will see that the Makefile rules simply call a script
from the source tree, <code>run_doxygen</code>, which does the actual work
of running Doxygen and then (most importantly) massaging the output files.
If for some reason you prefer to not go through the Makefile, you can call
this script directly. (Start by passing <code>'--help'</code>.)
</p>
<p>If you wish to tweak the Doxygen settings, do so by editing
<code>docs/doxygen/user.cfg.in</code>. Notes to v3-hackers are written in
triple-# comments.
</p>
<a name="writing"><h2>Writing the markup</h2></a>
<p>In general, libstdc++ files should be formatted according to the GNU
C++ Coding Standard rules found in the file
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/C++STYLE">C++STYLE</a>.
Before any doxygen-specific formatting tweaks are made, please try to make
sure that the initial formatting is sound.
</p>
<p>Adding Doxygen markup to a file (informally called "doxygenating") is very
simple. The Doxygen manual can be found
<a href="http://www.stack.nl/~dimitri/doxygen/download.html#latestman">here</a>.
We try to use a very-recent version of Doxygen.
</p>
<h3>Doxygen style guide</h3>
<p>[incomplete and constantly evolving]</p>
<p>For classes, use deque/vector/list and std::pair as examples. For
functions, see their member functions, and the free functions in
<code>stl_algobase.h</code>. Member functions of other container-like
types should read similarly to these member functions.
</p>
<p>These points accompany the first list in section 3.1 of the Doxygen manual:
</p>
<ol>
<li>Use the Javadoc style...</li>
<li>...not the Qt style. The intermediate *'s are preferred.</li>
<li>Use the triple-slash style only for one-line comments (the "brief" mode).
Very recent versions of Doxygen permit full-mode comments in triple-slash
blocks, but the formatting still comes out wonky.</li>
<li>This is disgusting. Don't do this.</li>
</ol>
<p>Use the @-style of commands, not the !-style. Please be careful about
whitespace in your markup comments. Most of the time it doesn't matter;
doxygen absorbs most whitespace, and both HTML and *roff are agnostic about
whitespace. However, in &lt;pre&gt; blocks and @code/@endcode sections,
spacing can have "interesting" effects.
</p>
<p>Use either kind of grouping, as appropriate. <code>doxygroups.cc</code>
exists for this purpose. See <code>stl_iterator.h</code> for a good
example of the "other" kind of grouping.
</p>
<p>Please use markup tags like @p and @a when referring to things such as the
names of function parameters. Use @e for emphasis when necessary. Use @c
to refer to other standard names. (Examples of all these abound in the
present code.)
</p>
</body>
</html>

View file

@ -1108,7 +1108,7 @@ MAN_LINKS = NO
# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML = NO
GENERATE_XML = @do_xml@
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
@ -1120,6 +1120,7 @@ XML_OUTPUT = xml
# which can be used by a validating XML parser to check the
# syntax of the XML files.
#XML_SCHEMA =
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
@ -1127,6 +1128,7 @@ XML_SCHEMA =
# syntax of the XML files.
XML_DTD =
#XML_DTD = http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting

View file

@ -0,0 +1,94 @@
<?xml version='1.0'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<book>
<article id="api" xreflabel="API">
<?dbhtml filename="api.html"?>
<articleinfo>
<title>API and Source Level Documentation</title>
<copyright>
<year>
2008
</year>
<holder>
<ulink url="http://fsf.org">FSF
</ulink>
</holder>
</copyright>
<legalnotice>
<para>
<ulink url="17_intro/license.html">License
</ulink>
</para>
</legalnotice>
</articleinfo>
<para>
The GNU C++ library sources have been specially formatted so that with the
proper invocation of another tool (Doxygen), a set of HTML pages
are generated from the sources files themselves. The resultant
documentation is referred to as Source Level Documentation, and is
useful for examining the signatures of public member functions for
the library classes, finding out what is in a particular include
file, looking at inheritance diagrams, etc.
</para>
<para>
The source-level documentation for the most recent releases can be
viewed online:
</para>
<itemizedlist>
<listitem>
<para>
<ulink url="libstdc++-html-USERS-3.4/index.html">for the 3.4 release
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="libstdc++-html-USERS-4.1/index.html">for the 4.1 release
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="libstdc++-html-USERS-4.2/index.html">for the 4.2 release
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="latest-doxygen/index.html">&quot;the latest collection&quot;
</ulink>
(For the main development tree; see the date on the first page.)
</para>
</listitem>
</itemizedlist>
<para>
This generated HTML collection, as above, is also available for download in the libstdc++ snapshots directory at
<literal>&lt;URL:ftp://gcc.gnu.org/pub/gcc/libstdc++/doxygen/&gt;</literal>.
You will almost certainly need to use one of the
<ulink url="http://gcc.gnu.org/mirrors.html">mirror sites</ulink> to download
the tarball. After unpacking, simply load libstdc++-html-*/index.html
into a browser.
</para>
<para>
Documentation for older releases is available for download only, not
online viewing.
</para>
<para>
In addition, an initial set of man pages are also available in the
same place as the HTML collections. Start with C++Intro(3).
</para>
</article>
</book>

View file

@ -0,0 +1,174 @@
<authorgroup>
<!--
<author>
<firstname>Benjamin</firstname>
<surname>Kosnik</surname>
<affiliation>
<shortaffil>Red Hat</shortaffil>
<orgname>Red Hat, Inc.</orgname>
<address>
<email>libstdc++@gcc.gnu.org</email>
</address>
</affiliation>
<authorblurb>
<para>
</para>
</authorblurb>
</author>
-->
<author>
<firstname>Paolo</firstname>
<surname>Carlini</surname>
<authorblurb>
<para>
TR1, LWG Active, Closed, Defects lists.
</para>
</authorblurb>
</author>
<author>
<firstname>Phil</firstname>
<surname>Edwards</surname>
<authorblurb>
<para>
Originating author, started HOWTO and FAQ, worked on sections
Demangling, Macros, Strings, Iterators, Backwards
Compatibility, SGI Extensions, Configure, Build, Install.
</para>
</authorblurb>
</author>
<author>
<firstname>Doug</firstname>
<surname>Gregor</surname>
<authorblurb>
<para>
Debug Mode, TR1 function objects
</para>
</authorblurb>
</author>
<author>
<firstname>Benjamin</firstname>
<surname>Kosnik</surname>
<authorblurb>
<para>
Allocators, ABI, API evolution and deprecation history,
Backwards Compatibility, Thread, Debug Support, Locales,
Facets, Parallel Mode, Headers, Namespaces, Construction and
Structure, DocBook conversion and layout.
</para>
</authorblurb>
</author>
<author>
<firstname>Dhruv</firstname>
<surname>Matani</surname>
<authorblurb>
<para>
bitmap_allocator
</para>
</authorblurb>
</author>
<author>
<firstname>Jason</firstname>
<surname>Merrill</surname>
<authorblurb>
<para>
License, __verbose_terminate_handler
</para>
</authorblurb>
</author>
<author>
<firstname>Mark</firstname>
<surname>Mitchell</surname>
<authorblurb>
<para>
Porting
</para>
</authorblurb>
</author>
<author>
<firstname>Nathan</firstname>
<surname>Myers</surname>
<authorblurb>
<para>
Referenced counted string, C++1998 implementation status.
</para>
</authorblurb>
</author>
<author>
<firstname>Felix</firstname>
<surname>Natter</surname>
<authorblurb>
<para>
Namespace composition, Backwards Compatibility.
</para>
</authorblurb>
</author>
<author>
<firstname>Stefan</firstname>
<surname>Olsson</surname>
<authorblurb>
<para>
mt_allocator
</para>
</authorblurb>
</author>
<author>
<firstname>Johannes</firstname>
<surname>Singler</surname>
<authorblurb>
<para>
Parallel mode
</para>
</authorblurb>
</author>
<author>
<firstname>Ami</firstname>
<surname>Tavory</surname>
<authorblurb>
<para>
Policy Based Datastructures, Associative Containers, Unordered
Containers.
</para>
</authorblurb>
</author>
<author>
<firstname>Jonathan</firstname>
<surname>Wakely</surname>
<authorblurb>
<para>
shared_ptr, markup editing and styling
</para>
</authorblurb>
</author>
</authorgroup>

View file

@ -0,0 +1,33 @@
<?xml version='1.0'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<book id="api" xreflabel="Source Level Documentation">
<title>Source Level Documentation</title>
<bookinfo>
<copyright>
<year>2007</year>
<holder>
<ulink url="fsf.org">FSF
</ulink>
</holder>
</copyright>
<legalnotice>
<para>
<ulink url="17_intro/license.html">License
</ulink>
</para>
</legalnotice>
</bookinfo>
<part>
<title></title>
<chapter>
<title></title>
<para></para>
</chapter>
</part>
</book>

View file

@ -0,0 +1,54 @@
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<chapter id="manual.intro" xreflabel="Introduction">
<chapterinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</chapterinfo>
<title>Introduction</title>
<sect1 id="manual.intro.status" xreflabel="Status">
<title>Status</title>
<para>
The GNU C++ ...
</para>
</sect1>
<sect1 id="manual.intro.setup" xreflabel="Setup">
<title>Setup</title>
<para>
The GNU C++ ...
</para>
<sect2 id="manual.intro.setup.next1" xreflabel="Next1">
<title>Next1</title>
<para>
The GNU C++ ...
</para>
</sect2>
<sect2 id="manual.intro.setup.next2" xreflabel="Next2">
<title>Next2</title>
<para>
The GNU C++ ...
</para>
</sect2>
</sect1>
<sect1 id="manual.intro.using" xreflabel="Using">
<title>Using</title>
<para>
The GNU C++ ...
</para>
</sect1>
</chapter>

View file

@ -0,0 +1,154 @@
<sect1 id="manual.util.memory.allocator" xreflabel="allocator">
<?dbhtml filename="allocator.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
allocator
</keyword>
</keywordset>
</sect1info>
<title>allocator</title>
<para>
</para>
<sect2 id="allocator.req" xreflabel="allocator.req">
<title>Requirements</title>
<para>
</para>
<itemizedlist>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
</itemizedlist>
<para>
</para>
</sect2>
<sect2 id="allocator.design_issues" xreflabel="allocator.design_issues">
<title>Design Issues</title>
<para>
</para>
<para>
</para>
</sect2>
<sect2 id="allocator.impl" xreflabel="allocator.impl">
<title>Implementation</title>
<sect3>
<title>Interface Design</title>
<para>
</para>
<para>
</para>
</sect3>
<sect3>
<title>Selecting Default Allocation Strategy</title>
<para>
</para>
<orderedlist>
<listitem>
</listitem>
<listitem>
</listitem>
<listitem>
</listitem>
</orderedlist>
</sect3>
<sect3>
<title>Disabling Memory Caching</title>
<para>
</para>
<para>
</para>
</sect3>
</sect2>
<sect2 id="allocator.using" xreflabel="allocator.using">
<title>Using</title>
<para>
</para>
</sect2>
<sect2 id="allocator.custom" xreflabel="allocator.custom">
<title>Custom Allocators</title>
<para>
</para>
<para>
</para>
</sect2>
<bibliography id="allocator.biblio" xreflabel="allocator.biblio">
<title>Bibliography</title>
<!--
<biblioentry>
<abbrev>
</abbrev>
<title>
</title>
<editor>
<firstname></firstname>
<surname></surname>
</editor>
<author>
<surname></surname>
<firstname></firstname>
</author>
<copyright>
<year></year>
<holder></holder>
</copyright>
<pagenums></pagenums>
<publisher>
<publishername>
</publishername>
</publisher>
<biblioid>
<ulink url="">
</ulink>
</biblioid>
</biblioentry>
-->
<biblioentry>
</biblioentry>
</bibliography>
</sect1>

1254
libstdc++-v3/doc/xml/faq.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,502 @@
<appendix id="appendix.gfdl-1.2">
<title>GNU Free Documentation License</title>
<para>
Copyright (C) 2000, 2001, 2002 Free Software Foundation,
<abbrev>Inc.</abbrev> 51 Franklin <abbrev>St</abbrev>, Fifth Floor,
Boston, <abbrev>MA</abbrev> 02110-1301 <abbrev
role="initialism">USA</abbrev>. Everyone is permitted to copy and
distribute verbatim copies of this license document, but changing it is
not allowed.
</para>
<bridgehead id="Preamble" renderas="sect1">
0. PREAMBLE
</bridgehead>
<para>
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to assure
everyone the effective freedom to copy and redistribute it, with or
without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way to
get credit for their work, while not being considered responsible for
modifications made by others.
</para>
<para>
This License is a kind of "copyleft", which means that derivative works of
the document must themselves be free in the same sense. It complements
the GNU General Public License, which is a copyleft license designed for
free software.
</para>
<para>
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free program
should come with manuals providing the same freedoms that the software
does. But this License is not limited to software manuals; it can be used
for any textual work, regardless of subject matter or whether it is
published as a printed book. We recommend this License principally for
works whose purpose is instruction or reference.</para>
<bridgehead id="Definitions" renderas="sect1">
1. APPLICABILITY AND DEFINITIONS
</bridgehead>
<para>
This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that work
under the conditions stated herein. The "Document", below, refers to any
such manual or work. Any member of the public is a licensee, and is
addressed as "you". You accept the license if you copy, modify or
distribute the work in a way requiring permission under copyright
law.
</para>
<para>
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with modifications
and/or translated into another language.
</para>
<para>
A "Secondary Section" is a named appendix or a front-matter section of the
Document that deals exclusively with the relationship of the publishers or
authors of the Document to the Document's overall subject (or to related
matters) and contains nothing that could fall directly within that overall
subject. (Thus, if the Document is in part a textbook of mathematics, a
Secondary Section may not explain any mathematics.) The relationship
could be a matter of historical connection with the subject or with
related matters, or of legal, commercial, philosophical, ethical or
political position regarding them.
</para>
<para>
The "Invariant Sections" are certain Secondary Sections whose titles are
designated, as being those of Invariant Sections, in the notice that says
that the Document is released under this License. If a section does not
fit the above definition of Secondary then it is not allowed to be
designated as Invariant. The Document may contain zero Invariant
Sections. If the Document does not identify any Invariant Sections then
there are none.
</para>
<para>
The "Cover Texts" are certain short passages of text that are listed, as
Front-Cover Texts or Back-Cover Texts, in the notice that says that the
Document is released under this License. A Front-Cover Text may be at
most 5 words, and a Back-Cover Text may be at most 25 words.
</para>
<para>
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the general
public, that is suitable for revising the document straightforwardly with
generic text editors or (for images composed of pixels) generic paint
programs or (for drawings) some widely available drawing editor, and that
is suitable for input to text formatters or for automatic translation to a
variety of formats suitable for input to text formatters. A copy made in
an otherwise Transparent file format whose markup, or absence of markup,
has been arranged to thwart or discourage subsequent modification by
readers is not Transparent. An image format is not Transparent if used
for any substantial amount of text. A copy that is not "Transparent" is
called "Opaque".
</para>
<para>
Examples of suitable formats for Transparent copies include plain ASCII
without markup, Texinfo input format, LaTeX input format, SGML or XML
using a publicly available DTD, and standard-conforming simple HTML,
PostScript or PDF designed for human modification. Examples of
transparent image formats include PNG, XCF and JPG. Opaque formats
include proprietary formats that can be read and edited only by
proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the machine-generated
HTML, PostScript or PDF produced by some word processors for output
purposes only.
</para>
<para>
The "Title Page" means, for a printed book, the title page itself, plus
such following pages as are needed to hold, legibly, the material this
License requires to appear in the title page. For works in formats which
do not have any title page as such, "Title Page" means the text near the
most prominent appearance of the work's title, preceding the beginning of
the body of the text.
</para>
<para>
A section "Entitled XYZ" means a named subunit of the Document whose title
either is precisely XYZ or contains XYZ in parentheses following text that
translates XYZ in another language. (Here XYZ stands for a specific
section name mentioned below, such as "Acknowledgements", "Dedications",
"Endorsements", or "History".) To "Preserve the Title" of such a section
when you modify the Document means that it remains a section "Entitled
XYZ" according to this definition.
</para>
<para>
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this License,
but only as regards disclaiming warranties: any other implication that
these Warranty Disclaimers may have is void and has no effect on the
meaning of this License.
</para>
<bridgehead id="VerbatimCopying" renderas="sect1">
2. VERBATIM COPYING
</bridgehead>
<para>
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the copyright
notices, and the license notice saying this License applies to the
Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License. You may not use technical
measures to obstruct or control the reading or further copying of the
copies you make or distribute. However, you may accept compensation in
exchange for copies. If you distribute a large enough number of copies
you must also follow the conditions in section 3.
</para>
<para>
You may also lend copies, under the same conditions stated above, and you
may publicly display copies.
</para>
<bridgehead id="QuantityCopying" renderas="sect1">
3. COPYING IN QUANTITY
</bridgehead>
<para>
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
Document's license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover Texts:
Front-Cover Texts on the front cover, and Back-Cover Texts on the back
cover. Both covers must also clearly and legibly identify you as the
publisher of these copies. The front cover must present the full title
with all words of the title equally prominent and visible. You may add
other material on the covers in addition. Copying with changes limited to
the covers, as long as they preserve the title of the Document and satisfy
these conditions, can be treated as verbatim copying in other
respects.
</para>
<para>
If the required texts for either cover are too voluminous to fit legibly,
you should put the first ones listed (as many as fit reasonably) on the
actual cover, and continue the rest onto adjacent pages.
</para>
<para>
If you publish or distribute Opaque copies of the Document numbering more
than 100, you must either include a machine-readable Transparent copy
along with each Opaque copy, or state in or with each Opaque copy a
computer-network location from which the general network-using public has
access to download using public-standard network protocols a complete
Transparent copy of the Document, free of added material. If you use the
latter option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this Transparent
copy will remain thus accessible at the stated location until at least one
year after the last time you distribute an Opaque copy (directly or
through your agents or retailers) of that edition to the public.
</para>
<para>
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the
Document.
</para>
<bridgehead id="Modifications" renderas="sect1">
4. MODIFICATIONS
</bridgehead>
<para>
You may copy and distribute a Modified Version of the Document under the
conditions of sections 2 and 3 above, provided that you release the
Modified Version under precisely this License, with the Modified Version
filling the role of the Document, thus licensing distribution and
modification of the Modified Version to whoever possesses a copy of it.
In addition, you must do these things in the Modified Version:
</para>
<orderedlist numeration="upperalpha">
<listitem>
<simpara>
Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions (which
should, if there were any, be listed in the History section of the
Document). You may use the same title as a previous version if the
original publisher of that version gives permission.
</simpara>
</listitem>
<listitem>
<simpara>
List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
</simpara>
</listitem>
<listitem>
<simpara>
State on the Title page the name of the publisher of the Modified
Version, as the publisher.
</simpara>
</listitem>
<listitem>
<simpara>
Preserve all the copyright notices of the Document.
</simpara>
</listitem>
<listitem>
<simpara>
Add an appropriate copyright notice for your modifications adjacent to
the other copyright notices.
</simpara>
</listitem>
<listitem>
<simpara>
Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
</simpara>
</listitem>
<listitem>
<simpara>
Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
</simpara>
</listitem>
<listitem>
<simpara>
Include an unaltered copy of this License.
</simpara>
</listitem>
<listitem>
<simpara>
Preserve the section Entitled "History", Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section Entitled "History" in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
</simpara>
</listitem>
<listitem>
<simpara>
Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise the
network locations given in the Document for previous versions it was
based on. These may be placed in the "History" section. You may omit
a network location for a work that was published at least four years
before the Document itself, or if the original publisher of the
version it refers to gives permission.
</simpara>
</listitem>
<listitem>
<simpara>
For any section Entitled "Acknowledgements" or "Dedications", Preserve
the Title of the section, and preserve in the section all the
substance and tone of each of the contributor acknowledgements and/or
dedications given therein.
</simpara>
</listitem>
<listitem>
<simpara>
Preserve all the Invariant Sections of the Document, unaltered in
their text and in their titles. Section numbers or the equivalent are
not considered part of the section titles.
</simpara>
</listitem>
<listitem>
<simpara>
Delete any section Entitled "Endorsements". Such a section may not be
included in the Modified Version.
</simpara>
</listitem>
<listitem>
<simpara>
Do not retitle any existing section to be Entitled "Endorsements" or
to conflict in title with any Invariant Section.
</simpara>
</listitem>
<listitem>
<simpara>
Preserve any Warranty Disclaimers.
</simpara>
</listitem>
</orderedlist>
<para>
If the Modified Version includes new front-matter sections or appendices
that qualify as Secondary Sections and contain no material copied from the
Document, you may at your option designate some or all of these sections
as invariant. To do this, add their titles to the list of Invariant
Sections in the Modified Version's license notice. These titles must be
distinct from any other section titles.
</para>
<para>
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various parties--for
example, statements of peer review or that the text has been approved by
an organization as the authoritative definition of a standard.
</para>
<para>
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list of
Cover Texts in the Modified Version. Only one passage of Front-Cover Text
and one of Back-Cover Text may be added by (or through arrangements made
by) any one entity. If the Document already includes a cover text for the
same cover, previously added by you or by arrangement made by the same
entity you are acting on behalf of, you may not add another; but you may
replace the old one, on explicit permission from the previous publisher
that added the old one.
</para>
<para>
The author(s) and publisher(s) of the Document do not by this License give
permission to use their names for publicity for or to assert or imply
endorsement of any Modified Version.
</para>
<bridgehead id="Combining" renderas="sect1">
5. COMBINING DOCUMENTS
</bridgehead>
<para>
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified versions,
provided that you include in the combination all of the Invariant Sections
of all of the original documents, unmodified, and list them all as
Invariant Sections of your combined work in its license notice, and that
you preserve all their Warranty Disclaimers.
</para>
<para>
The combined work need only contain one copy of this License, and multiple
identical Invariant Sections may be replaced with a single copy. If there
are multiple Invariant Sections with the same name but different contents,
make the title of each such section unique by adding at the end of it, in
parentheses, the name of the original author or publisher of that section
if known, or else a unique number. Make the same adjustment to the
section titles in the list of Invariant Sections in the license notice of
the combined work.
</para>
<para>
In the combination, you must combine any sections Entitled "History" in
the various original documents, forming one section Entitled "History";
likewise combine any sections Entitled "Acknowledgements", and any
sections Entitled "Dedications". You must delete all sections Entitled
"Endorsements".
</para>
<bridgehead id="Collections" renderas="sect1">
6. COLLECTIONS OF DOCUMENTS
</bridgehead>
<para>
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.
</para>
<para>
You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all other
respects regarding verbatim copying of that document.
</para>
<bridgehead id="Aggregation" renderas="sect1">
7. AGGREGATION WITH INDEPENDENT WORKS
</bridgehead>
<para>
A compilation of the Document or its derivatives with other separate and
independent documents or works, in or on a volume of a storage or
distribution medium, is called an "aggregate" if the copyright resulting
from the compilation is not used to limit the legal rights of the
compilation's users beyond what the individual works permit. When the
Document is included in an aggregate, this License does not apply to the
other works in the aggregate which are not themselves derivative works of
the Document.
</para>
<para>
If the Cover Text requirement of section 3 is applicable to these copies
of the Document, then if the Document is less than one half of the entire
aggregate, the Document's Cover Texts may be placed on covers that bracket
the Document within the aggregate, or the electronic equivalent of covers
if the Document is in electronic form. Otherwise they must appear on
printed covers that bracket the whole aggregate.
</para>
<bridgehead id="Translation" renderas="sect1">
8. TRANSLATION
</bridgehead>
<para>
Translation is considered a kind of modification, so you may distribute
translations of the Document under the terms of section 4. Replacing
Invariant Sections with translations requires special permission from
their copyright holders, but you may include translations of some or all
Invariant Sections in addition to the original versions of these Invariant
Sections. You may include a translation of this License, and all the
license notices in the Document, and any Warranty Disclaimers, provided
that you also include the original English version of this License and the
original versions of those notices and disclaimers. In case of a
disagreement between the translation and the original version of this
License or a notice or disclaimer, the original version will prevail.
</para>
<para>
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to Preserve its
Title (section 1) will typically require changing the actual title.
</para>
<bridgehead id="Termination" renderas="sect1">
9. TERMINATION
</bridgehead>
<para>
You may not copy, modify, sublicense, or distribute the Document except as
expressly provided for under this License. Any other attempt to copy,
modify, sublicense or distribute the Document is void, and will
automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full
compliance.
</para>
<bridgehead id="FutureRevisions" renderas="sect1">
10. FUTURE REVISIONS OF THIS LICENSE
</bridgehead>
<para>
The Free Software Foundation may publish new, revised versions of the GNU
Free Documentation License from time to time. Such new versions will be
similar in spirit to the present version, but may differ in detail to
address new problems or concerns. See <ulink
url="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</ulink>.
</para>
<para>
Each version of the License is given a distinguishing version number. If
the Document specifies that a particular numbered version of this License
"or any later version" applies to it, you have the option of following the
terms and conditions either of that specified version or of any later
version that has been published (not as a draft) by the Free Software
Foundation. If the Document does not specify a version number of this
License, you may choose any version ever published (not as a draft) by the
Free Software Foundation.
</para>
<bridgehead id="HowToUse" renderas="sect1">
ADDENDUM: How to use this License for your documents
</bridgehead>
<para>
To use this License in a document you have written, include a copy of the
License in the document and put the following copyright and license
notices just after the title page:
</para>
<blockquote>
<para>
Copyright (C) YEAR YOUR NAME.
</para>
<para>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the section entitled "GNU Free
Documentation License".
</para>
</blockquote>
<para>
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the "with...Texts." line with this:
</para>
<blockquote>
<para>
with the Invariant Sections being LIST THEIR TITLES, with the
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
</para>
</blockquote>
<para>
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
</para>
<para>
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit their
use in free software.
</para>
</appendix>

View file

@ -0,0 +1,366 @@
<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<appendix id="appendix.gpl-2.0">
<appendixinfo>
<title>GNU General Public License</title>
<pubdate>Version 2, June 1991</pubdate>
<copyright>
<year>1989, 1991</year>
<holder>Free Software Foundation, Inc.</holder>
</copyright>
<legalnotice id="gpl-legalnotice">
<para>
<address>Free Software Foundation, Inc.
<street>51 Franklin Street, Fifth Floor</street>,
<city>Boston</city>, <state>MA</state> <postcode>02110-1301</postcode>
<country>USA</country>
</address>
</para>
<para>Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</para>
</legalnotice>
<releaseinfo>Version 2, June 1991</releaseinfo>
</appendixinfo>
<title>GNU General Public License</title>
<section id="gpl-1">
<title>Preamble</title>
<para>The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change
free software - to make sure the software is free for all its users.
This General Public License applies to most of the Free Software
Foundation&apos;s software and to any other program whose authors commit
to using it. (Some other Free Software Foundation software is covered
by the GNU Library General Public License instead.) You can apply it
to your programs, too.</para>
<para>When we speak of free software, we are referring to freedom, not price.
Our General Public Licenses are designed to make sure that you have the
freedom to distribute copies of free software (and charge for this
service if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.</para>
<para>To protect your rights, we need to make restrictions that forbid anyone
to deny you these rights or to ask you to surrender the rights. These
restrictions translate to certain responsibilities for you if you distribute
copies of the software, or if you modify it.</para>
<para>For example, if you distribute copies of such a program, whether gratis or
for a fee, you must give the recipients all the rights that you have. You
must make sure that they, too, receive or can get the source code. And you
must show them these terms so they know their rights.</para>
<para>We protect your rights with two steps:
<orderedlist>
<listitem>
<para>copyright the software, and</para>
</listitem>
<listitem>
<para>offer you this license which gives you legal permission to copy,
distribute and/or modify the software.</para>
</listitem>
</orderedlist>
</para>
<para>Also, for each author&apos;s protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If
the software is modified by someone else and passed on, we want its
recipients to know that what they have is not the original, so that any
problems introduced by others will not reflect on the original authors&apos;
reputations.</para>
<para>Finally, any free program is threatened constantly by software patents.
We wish to avoid the danger that redistributors of a free program will
individually obtain patent licenses, in effect making the program
proprietary. To prevent this, we have made it clear that any patent must be
licensed for everyone&apos;s free use or not licensed at all.</para>
<para>The precise terms and conditions for copying, distribution and modification
follow.</para>
</section>
<section id="gpl-2">
<title>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</title>
<section id="gpl-2-0">
<title>Section 0</title>
<para>This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms
of this General Public License. The <quote>Program</quote>, below, refers to any such
program or work, and a
<quote>work based on the Program</quote> means either
the Program or any derivative work under copyright law: that is to say, a
work containing the Program or a portion of it, either verbatim or with
modifications and/or translated into another language. (Hereinafter, translation
is included without limitation in the term
<quote>modification</quote>.) Each licensee is addressed as <quote>you</quote>.</para>
<para>Activities other than copying, distribution and modification are not covered by
this License; they are outside its scope. The act of running the Program is not
restricted, and the output from the Program is covered only if its contents
constitute a work based on the Program (independent of having been made by running
the Program). Whether that is true depends on what the Program does.</para>
</section>
<section id="gpl-2-1">
<title>Section 1</title>
<para>You may copy and distribute verbatim copies of the Program&apos;s source code as you
receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice and disclaimer of warranty;
keep intact all the notices that refer to this License and to the absence of any
warranty; and give any other recipients of the Program a copy of this License
along with the Program.</para>
<para>You may charge a fee for the physical act of transferring a copy, and you may at
your option offer warranty protection in exchange for a fee.</para>
</section>
<section id="gpl-2-2">
<title>Section 2</title>
<para>You may modify your copy or copies of the Program or any portion of it, thus
forming a work based on the Program, and copy and distribute such modifications
or work under the terms of
<link linkend="gpl-2-1">Section 1</link> above, provided
that you also meet all of these conditions:
<orderedlist numeration="loweralpha">
<listitem>
<para>You must cause the modified files to carry prominent notices stating that
you changed the files and the date of any change.</para>
</listitem>
<listitem>
<para>You must cause any work that you distribute or publish, that in whole or
in part contains or is derived from the Program or any part thereof, to be
licensed as a whole at no charge to all third parties under the terms of
this License.</para>
</listitem>
<listitem>
<para>If the modified program normally reads commands interactively when run, you
must cause it, when started running for such interactive use in the most
ordinary way, to print or display an announcement including an appropriate
copyright notice and a notice that there is no warranty (or else, saying
that you provide a warranty) and that users may redistribute the program
under these conditions, and telling the user how to view a copy of this
License. (Exception: If the Program itself is interactive but does not
normally print such an announcement, your work based on the Program is not
required to print an announcement.)</para>
</listitem>
</orderedlist>
</para>
<para>These requirements apply to the modified work as a whole. If identifiable sections
of that work are not derived from the Program, and can be reasonably considered
independent and separate works in themselves, then this License, and its terms,
do not apply to those sections when you distribute them as separate works. But when
you distribute the same sections as part of a whole which is a work based on the
Program, the distribution of the whole must be on the terms of this License, whose
permissions for other licensees extend to the entire whole, and thus to each and
every part regardless of who wrote it.</para>
<para>Thus, it is not the intent of this section to claim rights or contest your rights
to work written entirely by you; rather, the intent is to exercise the right to control
the distribution of derivative or collective works based on the Program.</para>
<para>In addition, mere aggregation of another work not based on the Program with the Program
(or with a work based on the Program) on a volume of a storage or distribution medium
does not bring the other work under the scope of this License.</para>
</section>
<section id="gpl-2-3">
<title>Section 3</title>
<para>You may copy and distribute the Program (or a work based on it, under
<link linkend="gpl-2-2">Section 2</link> in object code or executable form under the terms of
<link linkend="gpl-2-1">Sections 1</link> and
<link linkend="gpl-2-2">2</link> above provided that you also do one of the following:
<orderedlist numeration="loweralpha">
<listitem>
<para>Accompany it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,</para>
</listitem>
<listitem>
<para>Accompany it with a written offer, valid for at least three years, to give any
third party, for a charge no more than your cost of physically performing source
distribution, a complete machine-readable copy of the corresponding source code,
to be distributed under the terms of Sections 1 and 2 above on a medium customarily
used for software interchange; or,</para>
</listitem>
<listitem>
<para>Accompany it with the information you received as to the offer to distribute
corresponding source code. (This alternative is allowed only for noncommercial
distribution and only if you received the program in object code or executable form
with such an offer, in accord with Subsection b above.)</para>
</listitem>
</orderedlist>
</para>
<para>The source code for a work means the preferred form of the work for making modifications
to it. For an executable work, complete source code means all the source code for all modules
it contains, plus any associated interface definition files, plus the scripts used to control
compilation and installation of the executable. However, as a special exception, the source
code distributed need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the operating system
on which the executable runs, unless that component itself accompanies the executable.</para>
<para>If distribution of executable or object code is made by offering access to copy from a
designated place, then offering equivalent access to copy the source code from the same place
counts as distribution of the source code, even though third parties are not compelled to
copy the source along with the object code.</para>
</section>
<section id="gpl-2-4">
<title>Section 4</title>
<para>You may not copy, modify, sublicense, or distribute the Program except as expressly provided
under this License. Any attempt otherwise to copy, modify, sublicense or distribute the
Program is void, and will automatically terminate your rights under this License. However,
parties who have received copies, or rights, from you under this License will not have their
licenses terminated so long as such parties remain in full compliance.</para>
</section>
<section id="gpl-2-5">
<title>Section 5</title>
<para>You are not required to accept this License, since you have not signed it. However, nothing
else grants you permission to modify or distribute the Program or its derivative works.
These actions are prohibited by law if you do not accept this License. Therefore, by modifying
or distributing the Program (or any work based on the Program), you indicate your acceptance
of this License to do so, and all its terms and conditions for copying, distributing or
modifying the Program or works based on it.</para>
</section>
<section id="gpl-2-6">
<title>Section 6</title>
<para>Each time you redistribute the Program (or any work based on the Program), the recipient
automatically receives a license from the original licensor to copy, distribute or modify
the Program subject to these terms and conditions. You may not impose any further restrictions
on the recipients&apos; exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties to this License.</para>
</section>
<section id="gpl-2-7">
<title>Section 7</title>
<para>If, as a consequence of a court judgment or allegation of patent infringement or for any other
reason (not limited to patent issues), conditions are imposed on you (whether by court order,
agreement or otherwise) that contradict the conditions of this License, they do not excuse you
from the conditions of this License. If you cannot distribute so as to satisfy simultaneously
your obligations under this License and any other pertinent obligations, then as a consequence
you may not distribute the Program at all. For example, if a patent license would not permit
royalty-free redistribution of the Program by all those who receive copies directly or
indirectly through you, then the only way you could satisfy both it and this License would be
to refrain entirely from distribution of the Program.</para>
<para>If any portion of this section is held invalid or unenforceable under any particular circumstance,
the balance of the section is intended to apply and the section as a whole is intended to apply
in other circumstances.</para>
<para>It is not the purpose of this section to induce you to infringe any patents or other property
right claims or to contest validity of any such claims; this section has the sole purpose of
protecting the integrity of the free software distribution system, which is implemented by public
license practices. Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that system; it is up
to the author/donor to decide if he or she is willing to distribute software through any other
system and a licensee cannot impose that choice.</para>
<para>This section is intended to make thoroughly clear what is believed to be a consequence of the
rest of this License.</para>
</section>
<section id="gpl-2-8">
<title>Section 8</title>
<para>If the distribution and/or use of the Program is restricted in certain countries either by patents
or by copyrighted interfaces, the original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding those countries, so that
distribution is permitted only in or among countries not thus excluded. In such case, this License
incorporates the limitation as if written in the body of this License.</para>
</section>
<section id="gpl-2-9">
<title>Section 9</title>
<para>The Free Software Foundation may publish revised and/or new versions of the General Public License
from time to time. Such new versions will be similar in spirit to the present version, but may differ
in detail to address new problems or concerns.</para>
<para>Each version is given a distinguishing version number. If the Program specifies a version number of
this License which applies to it and <quote>any later version</quote>, you have the option of following the terms
and conditions either of that version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of this License, you may choose any
version ever published by the Free Software Foundation.</para>
</section>
<section id="gpl-2-10">
<title>Section 10</title>
<para>If you wish to incorporate parts of the Program into other free programs whose distribution
conditions are different, write to the author to ask for permission. For software which is copyrighted
by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions
for this. Our decision will be guided by the two goals of preserving the free status of all
derivatives of our free software and of promoting the sharing and reuse of software generally.</para>
</section>
<section id="gpl-2-11">
<title>NO WARRANTY Section 11</title>
<para>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM <quote>AS IS</quote> WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</para>
</section>
<section id="gpl-2-12">
<title>Section 12</title>
<para>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH
ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.</para>
<para>END OF TERMS AND CONDITIONS</para>
</section>
</section>
<section id="gpl-3">
<title>How to Apply These Terms to Your New Programs</title>
<para>If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.</para>
<para>To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the <quote>copyright</quote> line and a pointer to where the full notice is found.</para>
<para>&lt;one line to give the program&apos;s name and a brief idea of what it does.&gt;
Copyright (C) &lt;year&gt; &lt;name of author&gt;</para>
<para>This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.</para>
<para>This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.</para>
<para>You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</para>
<para>Also add information on how to contact you by electronic and paper mail.</para>
<para>If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:</para>
<para>Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type <quote>show w</quote>.
This is free software, and you are welcome to redistribute it
under certain conditions; type <quote>show c</quote> for details.</para>
<para>The hypothetical commands <quote>show w</quote> and <quote>show c</quote> should
show the appropriate parts of the General Public License. Of course, the commands you
use may be called something other than <quote>show w</quote> and <quote>show c</quote>;
they could even be mouse-clicks or menu items--whatever suits your program.</para>
<para>You should also get your employer (if you work as a programmer) or your
school, if any, to sign a <quote>copyright disclaimer</quote> for the program, if
necessary. Here is a sample; alter the names:</para>
<para>Yoyodyne, Inc., hereby disclaims all copyright interest in the program
<quote>Gnomovision</quote> (which makes passes at compilers) written by James Hacker.</para>
<para>&lt;signature of Ty Coon&gt;, 1 April 1989
Ty Coon, President of Vice</para>
<para>This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.</para>
</section>
</appendix>

View file

@ -0,0 +1,836 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<appendix>
<title>
<acronym>GNU</acronym> General Public License version 3
</title>
<para>
Version 3, 29 June 2007
</para>
<para>
Copyright &copy; 2007 Free Software Foundation, Inc.
<ulink url="http://fsf.org/">http://fsf.org/</ulink>
</para>
<para>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
</para>
<bridgehead id="Preamble" renderas="sect1">
Preamble
</bridgehead>
<para>
The <acronym>GNU</acronym> General Public License is a free, copyleft
license for software and other kinds of works.
</para>
<para>
The licenses for most software and other practical works are designed to
take away your freedom to share and change the works. By contrast, the
<acronym>GNU</acronym> General Public License is intended to guarantee your
freedom to share and change all versions of a program&mdash;to make sure it
remains free software for all its users. We, the Free Software Foundation,
use the <acronym>GNU</acronym> General Public License for most of our
software; it applies also to any other work released this way by its
authors. You can apply it to your programs, too.
</para>
<para>
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for them if you wish),
that you receive source code or can get it if you want it, that you can
change the software or use pieces of it in new free programs, and that you
know you can do these things.
</para>
<para>
To protect your rights, we need to prevent others from denying you these
rights or asking you to surrender the rights. Therefore, you have certain
responsibilities if you distribute copies of the software, or if you modify
it: responsibilities to respect the freedom of others.
</para>
<para>
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must pass on to the recipients the same freedoms that you
received. You must make sure that they, too, receive or can get the source
code. And you must show them these terms so they know their rights.
</para>
<para>
Developers that use the <acronym>GNU</acronym> <acronym>GPL</acronym>
protect your rights with two steps: (1) assert copyright on the software,
and (2) offer you this License giving you legal permission to copy,
distribute and/or modify it.
</para>
<para>
For the developers&rsquo; and authors&rsquo; protection, the
<acronym>GPL</acronym> clearly explains that there is no warranty for this
free software. For both users&rsquo; and authors&rsquo; sake, the
<acronym>GPL</acronym> requires that modified versions be marked as changed,
so that their problems will not be attributed erroneously to authors of
previous versions.
</para>
<para>
Some devices are designed to deny users access to install or run modified
versions of the software inside them, although the manufacturer can do so.
This is fundamentally incompatible with the aim of protecting users&rsquo;
freedom to change the software. The systematic pattern of such abuse occurs
in the area of products for individuals to use, which is precisely where it
is most unacceptable. Therefore, we have designed this version of the
<acronym>GPL</acronym> to prohibit the practice for those products. If such
problems arise substantially in other domains, we stand ready to extend this
provision to those domains in future versions of the <acronym>GPL</acronym>,
as needed to protect the freedom of users.
</para>
<para>
Finally, every program is threatened constantly by software patents. States
should not allow patents to restrict development and use of software on
general-purpose computers, but in those that do, we wish to avoid the
special danger that patents applied to a free program could make it
effectively proprietary. To prevent this, the <acronym>GPL</acronym>
assures that patents cannot be used to render the program non-free.
</para>
<para>
The precise terms and conditions for copying, distribution and modification
follow.
</para>
<bridgehead>
TERMS AND CONDITIONS
</bridgehead>
<bridgehead id="Definitions" renderas="sect1">
0. Definitions.
</bridgehead>
<para>
&ldquo;This License&rdquo; refers to version 3 of the <acronym>GNU</acronym>
General Public License.
</para>
<para>
&ldquo;Copyright&rdquo; also means copyright-like laws that apply to other
kinds of works, such as semiconductor masks.
</para>
<para>
&ldquo;The Program&rdquo; refers to any copyrightable work licensed under
this License. Each licensee is addressed as &ldquo;you&rdquo;.
&ldquo;Licensees&rdquo; and &ldquo;recipients&rdquo; may be individuals or
organizations.
</para>
<para>
To &ldquo;modify&rdquo; a work means to copy from or adapt all or part of
the work in a fashion requiring copyright permission, other than the making
of an exact copy. The resulting work is called a &ldquo;modified
version&rdquo; of the earlier work or a work &ldquo;based on&rdquo; the
earlier work.
</para>
<para>
A &ldquo;covered work&rdquo; means either the unmodified Program or a work
based on the Program.
</para>
<para>
To &ldquo;propagate&rdquo; a work means to do anything with it that, without
permission, would make you directly or secondarily liable for infringement
under applicable copyright law, except executing it on a computer or
modifying a private copy. Propagation includes copying, distribution (with
or without modification), making available to the public, and in some
countries other activities as well.
</para>
<para>
To &ldquo;convey&rdquo; a work means any kind of propagation that enables
other parties to make or receive copies. Mere interaction with a user
through a computer network, with no transfer of a copy, is not conveying.
</para>
<para>
An interactive user interface displays &ldquo;Appropriate Legal
Notices&rdquo; to the extent that it includes a convenient and prominently
visible feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the extent
that warranties are provided), that licensees may convey the work under this
License, and how to view a copy of this License. If the interface presents
a list of user commands or options, such as a menu, a prominent item in the
list meets this criterion.
</para>
<bridgehead id="SourceCode" renderas="sect1">
1. Source Code.
</bridgehead>
<para>
The &ldquo;source code&rdquo; for a work means the preferred form of the
work for making modifications to it. &ldquo;Object code&rdquo; means any
non-source form of a work.
</para>
<para>
A &ldquo;Standard Interface&rdquo; means an interface that either is an
official standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that is
widely used among developers working in that language.
</para>
<para>
The &ldquo;System Libraries&rdquo; of an executable work include anything,
other than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major Component,
and (b) serves only to enable use of the work with that Major Component, or
to implement a Standard Interface for which an implementation is available
to the public in source code form. A &ldquo;Major Component&rdquo;, in this
context, means a major essential component (kernel, window system, and so
on) of the specific operating system (if any) on which the executable work
runs, or a compiler used to produce the work, or an object code interpreter
used to run it.
</para>
<para>
The &ldquo;Corresponding Source&rdquo; for a work in object code form means
all the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work&rsquo;s
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but which
are not part of the work. For example, Corresponding Source includes
interface definition files associated with source files for the work, and
the source code for shared libraries and dynamically linked subprograms that
the work is specifically designed to require, such as by intimate data
communication or control flow between those subprograms and other parts of
the work.
</para>
<para>
The Corresponding Source need not include anything that users can regenerate
automatically from other parts of the Corresponding Source.
</para>
<para>
The Corresponding Source for a work in source code form is that same work.
</para>
<bridgehead id="BasicPermissions" renderas="sect1">
2. Basic Permissions.
</bridgehead>
<para>
All rights granted under this License are granted for the term of copyright
on the Program, and are irrevocable provided the stated conditions are met.
This License explicitly affirms your unlimited permission to run the
unmodified Program. The output from running a covered work is covered by
this License only if the output, given its content, constitutes a covered
work. This License acknowledges your rights of fair use or other
equivalent, as provided by copyright law.
</para>
<para>
You may make, run and propagate covered works that you do not convey,
without conditions so long as your license otherwise remains in force. You
may convey covered works to others for the sole purpose of having them make
modifications exclusively for you, or provide you with facilities for
running those works, provided that you comply with the terms of this License
in conveying all material for which you do not control copyright. Those
thus making or running the covered works for you must do so exclusively on
your behalf, under your direction and control, on terms that prohibit them
from making any copies of your copyrighted material outside their
relationship with you.
</para>
<para>
Conveying under any other circumstances is permitted solely under the
conditions stated below. Sublicensing is not allowed; section 10 makes it
unnecessary.
</para>
<bridgehead id="Protecting" renderas="sect1">
3. Protecting Users&rsquo; Legal Rights From Anti-Circumvention Law.
</bridgehead>
<para>
No covered work shall be deemed part of an effective technological measure
under any applicable law fulfilling obligations under article 11 of the WIPO
copyright treaty adopted on 20 December 1996, or similar laws prohibiting or
restricting circumvention of such measures.
</para>
<para>
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention is
effected by exercising rights under this License with respect to the covered
work, and you disclaim any intention to limit operation or modification of
the work as a means of enforcing, against the work&rsquo;s users, your or
third parties&rsquo; legal rights to forbid circumvention of technological
measures.
</para>
<bridgehead id="ConveyingVerbatim" renderas="sect1">
4. Conveying Verbatim Copies.
</bridgehead>
<para>
You may convey verbatim copies of the Program&rsquo;s source code as you
receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice; keep intact all
notices stating that this License and any non-permissive terms added in
accord with section 7 apply to the code; keep intact all notices of the
absence of any warranty; and give all recipients a copy of this License
along with the Program.
</para>
<para>
You may charge any price or no price for each copy that you convey, and you
may offer support or warranty protection for a fee.
</para>
<bridgehead id="ConveyingModified" renderas="sect1">
5. Conveying Modified Source Versions.
</bridgehead>
<para>
You may convey a work based on the Program, or the modifications to produce
it from the Program, in the form of source code under the terms of section
4, provided that you also meet all of these conditions:
</para>
<orderedlist numeration="loweralpha">
<listitem>
<para>
The work must carry prominent notices stating that you modified it, and
giving a relevant date.
</para>
</listitem>
<listitem>
<para>
The work must carry prominent notices stating that it is released under
this License and any conditions added under section 7. This requirement
modifies the requirement in section 4 to &ldquo;keep intact all
notices&rdquo;.
</para>
</listitem>
<listitem>
<para>
You must license the entire work, as a whole, under this License to
anyone who comes into possession of a copy. This License will therefore
apply, along with any applicable section 7 additional terms, to the
whole of the work, and all its parts, regardless of how they are
packaged. This License gives no permission to license the work in any
other way, but it does not invalidate such permission if you have
separately received it.
</para>
</listitem>
<listitem>
<para>
If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your work need
not make them do so.
</para>
</listitem>
</orderedlist>
<para>
A compilation of a covered work with other separate and independent works,
which are not by their nature extensions of the covered work, and which are
not combined with it such as to form a larger program, in or on a volume of
a storage or distribution medium, is called an &ldquo;aggregate&rdquo; if
the compilation and its resulting copyright are not used to limit the access
or legal rights of the compilation&rsquo;s users beyond what the individual works
permit. Inclusion of a covered work in an aggregate does not cause
this License to apply to the other parts of the aggregate.
</para>
<bridgehead id="ConveyingNonSource" renderas="sect1">
6. Conveying Non-Source Forms.
</bridgehead>
<para>
You may convey a covered work in object code form under the terms of
sections 4 and 5, provided that you also convey the machine-readable
Corresponding Source under the terms of this License, in one of these ways:
</para>
<orderedlist numeration="loweralpha">
<listitem>
<para>
Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by the Corresponding Source
fixed on a durable physical medium customarily used for software
interchange.
</para>
</listitem>
<listitem>
<para>
Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by a written offer, valid
for at least three years and valid for as long as you offer spare parts
or customer support for that product model, to give anyone who possesses
the object code either (1) a copy of the Corresponding Source for all
the software in the product that is covered by this License, on a
durable physical medium customarily used for software interchange, for a
price no more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding Source from
a network server at no charge.
</para>
</listitem>
<listitem>
<para>
Convey individual copies of the object code with a copy of the written
offer to provide the Corresponding Source. This alternative is allowed
only occasionally and noncommercially, and only if you received the
object code with such an offer, in accord with subsection 6b.
</para>
</listitem>
<listitem>
<para>
Convey the object code by offering access from a designated place
(gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to copy
the object code is a network server, the Corresponding Source may be on
a different server (operated by you or a third party) that supports
equivalent copying facilities, provided you maintain clear directions
next to the object code saying where to find the Corresponding Source.
Regardless of what server hosts the Corresponding Source, you remain
obligated to ensure that it is available for as long as needed to
satisfy these requirements.
</para>
</listitem>
<listitem>
<para>
Convey the object code using peer-to-peer transmission, provided you
inform other peers where the object code and Corresponding Source of the
work are being offered to the general public at no charge under
subsection 6d.
</para>
</listitem>
</orderedlist>
<para>
A separable portion of the object code, whose source code is excluded from
the Corresponding Source as a System Library, need not be included in
conveying the object code work.
</para>
<para>
A &ldquo;User Product&rdquo; is either (1) a &ldquo;consumer product&rdquo;,
which means any tangible personal property which is normally used for
personal, family, or household purposes, or (2) anything designed or sold
for incorporation into a dwelling. In determining whether a product is a
consumer product, doubtful cases shall be resolved in favor of coverage.
For a particular product received by a particular user, &ldquo;normally
used&rdquo; refers to a typical or common use of that class of product,
regardless of the status of the particular user or of the way in which the
particular user actually uses, or expects or is expected to use, the
product. A product is a consumer product regardless of whether the product
has substantial commercial, industrial or non-consumer uses, unless such
uses represent the only significant mode of use of the product.
</para>
<para>
&ldquo;Installation Information&rdquo; for a User Product means any methods,
procedures, authorization keys, or other information required to install and
execute modified versions of a covered work in that User Product from a
modified version of its Corresponding Source. The information must suffice
to ensure that the continued functioning of the modified object code is in
no case prevented or interfered with solely because modification has been
made.
</para>
<para>
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as part of
a transaction in which the right of possession and use of the User Product
is transferred to the recipient in perpetuity or for a fixed term
(regardless of how the transaction is characterized), the Corresponding
Source conveyed under this section must be accompanied by the Installation
Information. But this requirement does not apply if neither you nor any
third party retains the ability to install modified object code on the User
Product (for example, the work has been installed in
<acronym>ROM</acronym>).
</para>
<para>
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates for
a work that has been modified or installed by the recipient, or for the User
Product in which it has been modified or installed. Access to a network may
be denied when the modification itself materially and adversely affects the
operation of the network or violates the rules and protocols for
communication across the network.
</para>
<para>
Corresponding Source conveyed, and Installation Information provided, in
accord with this section must be in a format that is publicly documented
(and with an implementation available to the public in source code form),
and must require no special password or key for unpacking, reading or
copying.
</para>
<bridgehead id="AdditionalTerms" renderas="sect1">
7. Additional Terms.
</bridgehead>
<para>
&ldquo;Additional permissions&rdquo; are terms that supplement the terms of
this License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall be
treated as though they were included in this License, to the extent that
they are valid under applicable law. If additional permissions apply only
to part of the Program, that part may be used separately under those
permissions, but the entire Program remains governed by this License
without regard to the additional permissions.
</para>
<para>
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional
permissions may be written to require their own removal in certain cases
when you modify the work.) You may place additional permissions on
material, added by you to a covered work, for which you have or can give
appropriate copyright permission.
</para>
<para>
Notwithstanding any other provision of this License, for material you add
to a covered work, you may (if authorized by the copyright holders of that
material) supplement the terms of this License with terms:
</para>
<orderedlist numeration="loweralpha">
<listitem>
<para>
Disclaiming warranty or limiting liability differently from the terms
of sections 15 and 16 of this License; or
</para>
</listitem>
<listitem>
<para>
Requiring preservation of specified reasonable legal notices or author
attributions in that material or in the Appropriate Legal Notices
displayed by works containing it; or
</para>
</listitem>
<listitem>
<para>
Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
</para>
</listitem>
<listitem>
<para>
Limiting the use for publicity purposes of names of licensors or
authors of the material; or
</para>
</listitem>
<listitem>
<para>
Declining to grant rights under trademark law for use of some trade
names, trademarks, or service marks; or
</para>
</listitem>
<listitem>
<para>
Requiring indemnification of licensors and authors of that material by
anyone who conveys the material (or modified versions of it) with
contractual assumptions of liability to the recipient, for any
liability that these contractual assumptions directly impose on those
licensors and authors.
</para>
</listitem>
</orderedlist>
<para>
All other non-permissive additional terms are considered &ldquo;further
restrictions&rdquo; within the meaning of section 10. If the Program as
you received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further restriction,
you may remove that term. If a license document contains a further
restriction but permits relicensing or conveying under this License, you
may add to a covered work material governed by the terms of that license
document, provided that the further restriction does not survive such
relicensing or conveying.
</para>
<para>
If you add terms to a covered work in accord with this section, you must
place, in the relevant source files, a statement of the additional terms
that apply to those files, or a notice indicating where to find the
applicable terms.
</para>
<para>
Additional terms, permissive or non-permissive, may be stated in the form
of a separately written license, or stated as exceptions; the above
requirements apply either way.
</para>
<bridgehead id="Termination" renderas="sect1">
8. Termination.
</bridgehead>
<para>
You may not propagate or modify a covered work except as expressly provided
under this License. Any attempt otherwise to propagate or modify it is
void, and will automatically terminate your rights under this License
(including any patent licenses granted under the third paragraph of section
11).
</para>
<para>
However, if you cease all violation of this License, then your license from
a particular copyright holder is reinstated (a) provisionally, unless and
until the copyright holder explicitly and finally terminates your license,
and (b) permanently, if the copyright holder fails to notify you of the
violation by some reasonable means prior to 60 days after the cessation.
</para>
<para>
Moreover, your license from a particular copyright holder is reinstated
permanently if the copyright holder notifies you of the violation by some
reasonable means, this is the first time you have received notice of
violation of this License (for any work) from that copyright holder, and
you cure the violation prior to 30 days after your receipt of the notice.
</para>
<para>
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under this
License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
</para>
<bridgehead id="AcceptanceNotRequired" renderas="sect1">
9. Acceptance Not Required for Having Copies.
</bridgehead>
<para>
You are not required to accept this License in order to receive or run a
copy of the Program. Ancillary propagation of a covered work occurring
solely as a consequence of using peer-to-peer transmission to receive a
copy likewise does not require acceptance. However, nothing other than
this License grants you permission to propagate or modify any covered work.
These actions infringe copyright if you do not accept this License.
Therefore, by modifying or propagating a covered work, you indicate your
acceptance of this License to do so.
</para>
<bridgehead id="AutomaticDownstream" renderas="sect1">
10. Automatic Licensing of Downstream Recipients.
</bridgehead>
<para>
Each time you convey a covered work, the recipient automatically receives a
license from the original licensors, to run, modify and propagate that
work, subject to this License. You are not responsible for enforcing
compliance by third parties with this License.
</para>
<para>
An &ldquo;entity transaction&rdquo; is a transaction transferring control
of an organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered work
results from an entity transaction, each party to that transaction who
receives a copy of the work also receives whatever licenses to the work the
party&rsquo;s predecessor in interest had or could give under the previous
paragraph, plus a right to possession of the Corresponding Source of the
work from the predecessor in interest, if the predecessor has it or can get
it with reasonable efforts.
</para>
<para>
You may not impose any further restrictions on the exercise of the rights
granted or affirmed under this License. For example, you may not impose a
license fee, royalty, or other charge for exercise of rights granted under
this License, and you may not initiate litigation (including a cross-claim
or counterclaim in a lawsuit) alleging that any patent claim is infringed
by making, using, selling, offering for sale, or importing the Program or
any portion of it.
</para>
<bridgehead id="Patents" renderas="sect1">
11. Patents.
</bridgehead>
<para>
A &ldquo;contributor&rdquo; is a copyright holder who authorizes use under
this License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor&rsquo;s &ldquo;contributor
version&rdquo;.
</para>
<para>
A contributor&rsquo;s &ldquo;essential patent claims&rdquo; are all patent
claims owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted by
this License, of making, using, or selling its contributor version, but do
not include claims that would be infringed only as a consequence of further
modification of the contributor version. For purposes of this definition,
&ldquo;control&rdquo; includes the right to grant patent sublicenses in a
manner consistent with the requirements of this License.
</para>
<para>
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
license under the contributor&rsquo;s essential patent claims, to make, use,
sell, offer for sale, import and otherwise run, modify and propagate the
contents of its contributor version.
</para>
<para>
In the following three paragraphs, a &ldquo;patent license&rdquo; is any
express agreement or commitment, however denominated, not to enforce a
patent (such as an express permission to practice a patent or covenant not
to sue for patent infringement). To &ldquo;grant&rdquo; such a patent
license to a party means to make such an agreement or commitment not to
enforce a patent against the party.
</para>
<para>
If you convey a covered work, knowingly relying on a patent license, and the
Corresponding Source of the work is not available for anyone to copy, free
of charge and under the terms of this License, through a publicly available
network server or other readily accessible means, then you must either (1)
cause the Corresponding Source to be so available, or (2) arrange to deprive
yourself of the benefit of the patent license for this particular work, or
(3) arrange, in a manner consistent with the requirements of this License,
to extend the patent license to downstream recipients. &ldquo;Knowingly
relying&rdquo; means you have actual knowledge that, but for the patent
license, your conveying the covered work in a country, or your
recipient&rsquo;s use of the covered work in a country, would infringe one
or more identifiable patents in that country that you have reason to believe
are valid.
</para>
<para>
If, pursuant to or in connection with a single transaction or arrangement,
you convey, or propagate by procuring conveyance of, a covered work, and
grant a patent license to some of the parties receiving the covered work
authorizing them to use, propagate, modify or convey a specific copy of the
covered work, then the patent license you grant is automatically extended to
all recipients of the covered work and works based on it.
</para>
<para>
A patent license is &ldquo;discriminatory&rdquo; if it does not include
within the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered work
if you are a party to an arrangement with a third party that is in the
business of distributing software, under which you make payment to the third
party based on the extent of your activity of conveying the work, and under
which the third party grants, to any of the parties who would receive the
covered work from you, a discriminatory patent license (a) in connection
with copies of the covered work conveyed by you (or copies made from those
copies), or (b) primarily for and in connection with specific products or
compilations that contain the covered work, unless you entered into that
arrangement, or that patent license was granted, prior to 28 March 2007.
</para>
<para>
Nothing in this License shall be construed as excluding or limiting any
implied license or other defenses to infringement that may otherwise be
available to you under applicable patent law.
</para>
<bridgehead id="NoSurrender" renderas="sect1">
12. No Surrender of Others&rsquo; Freedom.
</bridgehead>
<para>
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey the
Program, the only way you could satisfy both those terms and this License
would be to refrain entirely from conveying the Program.
</para>
<bridgehead id="UsedWithAGPL" renderas="sect1">
13. Use with the <acronym>GNU</acronym> Affero General Public License.
</bridgehead>
<para>
Notwithstanding any other provision of this License, you have permission to
link or combine any covered work with a work licensed under version 3 of the
<acronym>GNU</acronym> Affero General Public License into a single combined
work, and to convey the resulting work. The terms of this License will
continue to apply to the part which is the covered work, but the special
requirements of the <acronym>GNU</acronym> Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
</para>
<bridgehead id="RevisedVersions" renderas="sect1">
14. Revised Versions of this License.
</bridgehead>
<para>
The Free Software Foundation may publish revised and/or new versions of the
<acronym>GNU</acronym> General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may differ in
detail to address new problems or concerns.
</para>
<para>
Each version is given a distinguishing version number. If the Program
specifies that a certain numbered version of the <acronym>GNU</acronym>
General Public License &ldquo;or any later version&rdquo; applies to it, you
have the option of following the terms and conditions either of that
numbered version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
<acronym>GNU</acronym> General Public License, you may choose any version
ever published by the Free Software Foundation.
</para>
<para>
If the Program specifies that a proxy can decide which future versions of
the <acronym>GNU</acronym> General Public License can be used, that
proxy&rsquo;s public statement of acceptance of a version permanently
authorizes you to choose that version for the Program.
</para>
<para>
Later license versions may give you additional or different permissions.
However, no additional obligations are imposed on any author or copyright
holder as a result of your choosing to follow a later version.
</para>
<bridgehead id="WarrantyDisclaimer" renderas="sect1">
15. Disclaimer of Warranty.
</bridgehead>
<para>
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM &ldquo;AS IS&rdquo; WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
</para>
<bridgehead id="LiabilityLimitation" renderas="sect1">
16. Limitation of Liability.
</bridgehead>
<para>
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
</para>
<bridgehead id="InterpretationSecs1516" renderas="sect1">
17. Interpretation of Sections 15 and 16.
</bridgehead>
<para>
If the disclaimer of warranty and limitation of liability provided above
cannot be given local legal effect according to their terms, reviewing
courts shall apply local law that most closely approximates an absolute
waiver of all civil liability in connection with the Program, unless a
warranty or assumption of liability accompanies a copy of the Program in
return for a fee.
</para>
<bridgehead>
END OF TERMS AND CONDITIONS
</bridgehead>
<bridgehead id="HowToApply" renderas="sect1">
How to Apply These Terms to Your New Programs
</bridgehead>
<para>
If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.
</para>
<para>
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively state the
exclusion of warranty; and each file should have at least the
&ldquo;copyright&rdquo; line and a pointer to where the full notice is
found.
</para>
<screen>
<replaceable>one line to give the program&rsquo;s name and a brief idea of what it does.</replaceable>
Copyright (C) <replaceable>year</replaceable> <replaceable>name of author</replaceable>
This program is free software: you can redistribute it and/or modify
it under the terms of the <acronym>GNU</acronym> General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
<acronym>GNU</acronym> General Public License for more details.
You should have received a copy of the <acronym>GNU</acronym> General Public License
along with this program. If not, see <ulink url="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</ulink>.
</screen>
<para>
Also add information on how to contact you by electronic and paper mail.
</para>
<para>
If the program does terminal interaction, make it output a short notice like
this when it starts in an interactive mode:
</para>
<screen>
<replaceable>program</replaceable> Copyright (C) <replaceable>year</replaceable> <replaceable>name of author</replaceable>
This program comes with ABSOLUTELY NO WARRANTY; for details type &lsquo;<literal>show w</literal>&rsquo;.
This is free software, and you are welcome to redistribute it
under certain conditions; type &lsquo;<literal>show c</literal>&rsquo; for details.
</screen>
<para>
The hypothetical commands &lsquo;<literal>show w</literal>&rsquo; and
&lsquo;<literal>show c</literal>&rsquo; should show the appropriate parts of
the General Public License. Of course, your program&rsquo;s commands might be
different; for a GUI interface, you would use an &ldquo;about box&rdquo;.
</para>
<para>
You should also get your employer (if you work as a programmer) or school,
if any, to sign a &ldquo;copyright disclaimer&rdquo; for the program, if
necessary. For more information on this, and how to apply and follow the
<acronym>GNU</acronym> <acronym>GPL</acronym>, see
<ulink url="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</ulink>.
</para>
<para>
The <acronym>GNU</acronym> General Public License does not permit
incorporating your program into proprietary programs. If your program is a
subroutine library, you may consider it more useful to permit linking
proprietary applications with the library. If this is what you want to do,
use the <acronym>GNU</acronym> Lesser General Public License instead of this
License. But first, please read <ulink
url="http://www.gnu.org/philosophy/why-not-lgpl.html">http://www.gnu.org/philosophy/why-not-lgpl.html</ulink>.
</para>
</appendix>

View file

@ -0,0 +1,14 @@
# Blatantly ripped out of the graphviz examples and modified. -pme
digraph v3conf {
size="6,6";
node [color=lightblue2, style=filled];
"aclocal.m4" -> "acinclude.m4";
"configure" -> "aclocal.m4";
"configure" -> "configure.ac";
"configure" -> "crossconfig.m4";
"configure" -> "linkage.m4";
"[*/]Makefile.in" -> "Makefile.am";
"[*/]Makefile.in" -> "configure.ac";
"config.h.in" -> "acconfig.h";
"config.h.in" -> "configure.ac";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,104 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.algorithms" xreflabel="Algorithms">
<?dbhtml filename="algorithms.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
<keyword>
algorithm
</keyword>
</keywordset>
</partinfo>
<title>Algorithms</title>
<preface>
<title></title>
<para>
The neatest accomplishment of the algorithms chapter is that all the
work is done via iterators, not containers directly. This means two
important things:
</para>
<orderedlist>
<listitem>
<para>
Anything that behaves like an iterator can be used in one of
these algorithms. Raw pointers make great candidates, thus
built-in arrays are fine containers, as well as your own iterators.
</para>
</listitem>
<listitem>
<para>
The algorithms do not (and cannot) affect the container as a
whole; only the things between the two iterator endpoints. If
you pass a range of iterators only enclosing the middle third of
a container, then anything outside that range is inviolate.
</para>
</listitem>
</orderedlist>
<para>
Even strings can be fed through the algorithms here, although the
string class has specialized versions of many of these functions
(for example, <code>string::find()</code>). Most of the examples
on this page will use simple arrays of integers as a playground
for algorithms, just to keep things simple. The use of
<emphasis>N</emphasis> as a size in the examples is to keep
things easy to read but probably won't be valid code. You can
use wrappers such as those described in the <ulink
url="../23_containers/howto.html">containers chapter</ulink> to
keep real code readable.
</para>
<para>
The single thing that trips people up the most is the definition
of <emphasis>range</emphasis> used with iterators; the famous
&quot;past-the-end&quot; rule that everybody loves to hate. The
<ulink url="../24_iterators/howto.html#2">iterators
chapter</ulink> of this document has a complete explanation of
this simple rule that seems to cause so much confusion. Once you
get <emphasis>range</emphasis> into your head (it's not that
hard, honest!), then the algorithms are a cakewalk.
</para>
</preface>
<!-- Chapter 01 : Non Modifying -->
<!-- Chapter 02 : Mutating -->
<chapter id="manual.algorithms.mutating" xreflabel="Mutating">
<title>Mutating</title>
<sect1 id="algorithms.mutating.swap" xreflabel="swap">
<title><function>swap</function></title>
<sect2 id="algorithms.swap.specializations" xreflabel="Specializations">
<title>Specializations</title>
<para>If you call <code> std::swap(x,y); </code> where x and y are standard
containers, then the call will automatically be replaced by a call to
<code> x.swap(y); </code> instead.
</para>
<para>This allows member functions of each container class to take over, and
containers' swap functions should have O(1) complexity according to
the standard. (And while &quot;should&quot; allows implementations to
behave otherwise and remain compliant, this implementation does in
fact use constant-time swaps.) This should not be surprising, since
for two containers of the same type to swap contents, only some
internal pointers to storage need to be exchanged.
</para>
</sect2>
</sect1>
</chapter>
<!-- Chapter 03 : Sorting -->
</part>

View file

@ -0,0 +1,659 @@
<sect1 id="manual.util.memory.allocator" xreflabel="Allocator">
<?dbhtml filename="allocator.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
allocator
</keyword>
</keywordset>
</sect1info>
<title>Allocators</title>
<para>
Memory management for Standard Library entities is encapsulated in a
class template called <classname>allocator</classname>. The
<classname>allocator</classname> abstraction is used throughout the
library in <classname>string</classname>, container classes,
algorithnms, and parts of iostreams. This class, and base classes of
it, are the superset of available free store (<quote>heap</quote>)
management classes.
</para>
<sect2 id="allocator.req" xreflabel="allocator.req">
<title>Requirements</title>
<para>
The C++ standard only gives a few directives in this area:
</para>
<itemizedlist>
<listitem>
<para>
When you add elements to a container, and the container must
allocate more memory to hold them, the container makes the
request via its <type>Allocator</type> template
parameter, which is usually aliased to
<type>allocator_type</type>. This includes adding chars
to the string class, which acts as a regular STL container in
this respect.
</para>
</listitem>
<listitem>
<para>
The default <type>Allocator</type> argument of every
container-of-T is <classname>allocator&lt;T&gt;</classname>.
</para>
</listitem>
<listitem>
<para>
The interface of the <classname>allocator&lt;T&gt;</classname> class is
extremely simple. It has about 20 public declarations (nested
typedefs, member functions, etc), but the two which concern us most
are:
</para>
<programlisting>
T* allocate (size_type n, const void* hint = 0);
void deallocate (T* p, size_type n);
</programlisting>
<para>
The <varname>n</varname> arguments in both those
functions is a <emphasis>count</emphasis> of the number of
<type>T</type>'s to allocate space for, <emphasis>not their
total size</emphasis>.
(This is a simplification; the real signatures use nested typedefs.)
</para>
</listitem>
<listitem>
<para>
The storage is obtained by calling <function>::operator
new</function>, but it is unspecified when or how
often this function is called. The use of the
<varname>hint</varname> is unspecified, but intended as an
aid to locality if an implementation so
desires. <constant>[20.4.1.1]/6</constant>
</para>
</listitem>
</itemizedlist>
<para>
Complete details cam be found in the C++ standard, look in
<constant>[20.4 Memory]</constant>.
</para>
</sect2>
<sect2 id="allocator.design_issues" xreflabel="allocator.design_issues">
<title>Design Issues</title>
<para>
The easiest way of fulfilling the requirements is to call
<function>operator new</function> each time a container needs
memory, and to call <function>operator delete</function> each time
the container releases memory. This method may be <ulink
url="http://gcc.gnu.org/ml/libstdc++/2001-05/msg00105.html">slower</ulink>
than caching the allocations and re-using previously-allocated
memory, but has the advantage of working correctly across a wide
variety of hardware and operating systems, including large
clusters. The <classname>__gnu_cxx::new_allocator</classname>
implements the simple operator new and operator delete semantics,
while <classname>__gnu_cxx::malloc_allocator</classname>
implements much the same thing, only with the C language functions
<function>std::malloc</function> and <function>free</function>.
</para>
<para>
Another approach is to use intelligence within the allocator
class to cache allocations. This extra machinery can take a variety
of forms: a bitmap index, an index into an exponentially increasing
power-of-two-sized buckets, or simpler fixed-size pooling cache.
The cache is shared among all the containers in the program: when
your program's <classname>std::vector&lt;int&gt;</classname> gets
cut in half and frees a bunch of its storage, that memory can be
reused by the private
<classname>std::list&lt;WonkyWidget&gt;</classname> brought in from
a KDE library that you linked against. And operators
<function>new</function> and <function>delete</function> are not
always called to pass the memory on, either, which is a speed
bonus. Examples of allocators that use these techniques are
<classname>__gnu_cxx::bitmap_allocator</classname>,
<classname>__gnu_cxx::pool_allocator</classname>, and
<classname>__gnu_cxx::__mt_alloc</classname>.
</para>
<para>
Depending on the implementation techniques used, the underlying
operating system, and compilation environment, scaling caching
allocators can be tricky. In particular, order-of-destruction and
order-of-creation for memory pools may be difficult to pin down
with certainty, which may create problems when used with plugins
or loading and unloading shared objects in memory. As such, using
caching allocators on systems that do not support
<function>abi::__cxa_atexit</function> is not recommended.
</para>
</sect2>
<sect2 id="allocator.impl" xreflabel="allocator.impl">
<title>Implementation</title>
<sect3>
<title>Interface Design</title>
<para>
The only allocator interface that
is support is the standard C++ interface. As such, all STL
containers have been adjusted, and all external allocators have
been modified to support this change.
</para>
<para>
The class <classname>allocator</classname> just has typedef,
constructor, and rebind members. It inherits from one of the
high-speed extension allocators, covered below. Thus, all
allocation and deallocation depends on the base class.
</para>
<para>
The base class that <classname>allocator</classname> is derived from
may not be user-configurable.
</para>
</sect3>
<sect3>
<title>Selecting Default Allocation Policy</title>
<para>
It's difficult to pick an allocation strategy that will provide
maximum utility, without excessively penalizing some behavior. In
fact, it's difficult just deciding which typical actions to measure
for speed.
</para>
<para>
Three synthetic benchmarks have been created that provide data
that is used to compare different C++ allocators. These tests are:
</para>
<orderedlist>
<listitem>
<para>
Insertion.
</para>
<para>
Over multiple iterations, various STL container
objects have elements inserted to some maximum amount. A variety
of allocators are tested.
Test source for <ulink url="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/sequence.cc?view=markup">sequence</ulink>
and <ulink url="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/associative.cc?view=markup">associative</ulink>
containers.
</para>
</listitem>
<listitem>
<para>
Insertion and erasure in a multi-threaded environment.
</para>
<para>
This test shows the ability of the allocator to reclaim memory
on a pre-thread basis, as well as measuring thread contention
for memory resources.
Test source
<ulink url="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert_erase/associative.cc?view=markup">here</ulink>.
</para>
</listitem>
<listitem>
<para>
A threaded producer/consumer model.
</para>
<para>
Test source for
<ulink url="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/producer_consumer/sequence.cc?view=markup">sequence</ulink>
and
<ulink url="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/producer_consumer/associative.cc?view=markup">associative</ulink>
containers.
</para>
</listitem>
</orderedlist>
<para>
The current default choice for
<classname>allocator</classname> is
<classname>__gnu_cxx::new_allocator</classname>.
</para>
</sect3>
<sect3>
<title>Disabling Memory Caching</title>
<para>
In use, <classname>allocator</classname> may allocate and
deallocate using implementation-specified strategies and
heuristics. Because of this, every call to an allocator object's
<function>allocate</function> member function may not actually
call the global operator new. This situation is also duplicated
for calls to the <function>deallocate</function> member
function.
</para>
<para>
This can be confusing.
</para>
<para>
In particular, this can make debugging memory errors more
difficult, especially when using third party tools like valgrind or
debug versions of <function>new</function>.
</para>
<para>
There are various ways to solve this problem. One would be to use
a custom allocator that just called operators
<function>new</function> and <function>delete</function>
directly, for every allocation. (See
<filename>include/ext/new_allocator.h</filename>, for instance.)
However, that option would involve changing source code to use
the a non-default allocator. Another option is to force the
default allocator to remove caching and pools, and to directly
allocate with every call of <function>allocate</function> and
directly deallocate with every call of
<function>deallocate</function>, regardless of efficiency. As it
turns out, this last option is also available.
</para>
<para>
To globally disable memory caching within the library for the
default allocator, merely set
<constant>GLIBCXX_FORCE_NEW</constant> (with any value) in the
system's environment before running the program. If your program
crashes with <constant>GLIBCXX_FORCE_NEW</constant> in the
environment, it likely means that you linked against objects
built against the older library (objects which might still using the
cached allocations...).
</para>
</sect3>
</sect2>
<sect2 id="allocator.using" xreflabel="allocator.using">
<title>Using a Specific Allocator</title>
<para>
You can specify different memory management schemes on a
per-container basis, by overriding the default
<type>Allocator</type> template parameter. For example, an easy
(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>
std::list &lt;int, __gnu_cxx::malloc_allocator&lt;int&gt; &gt; malloc_list;</programlisting>
<para>
Likewise, a debugging form of whichever allocator is currently in use:
</para>
<programlisting>
std::deque &lt;int, __gnu_cxx::debug_allocator&lt;std::allocator&lt;int&gt; &gt; &gt; debug_deque;
</programlisting>
</sect2>
<sect2 id="allocator.custom" xreflabel="allocator.custom">
<title>Custom Allocators</title>
<para>
Writing a portable C++ allocator would dictate that the interface
would look much like the one specified for
<classname>allocator</classname>. Additional member functions, but
not subtractions, would be permissible.
</para>
<para>
Probably the best place to start would be to copy one of the
extension allocators: say a simple one like
<classname>new_allocator</classname>.
</para>
</sect2>
<sect2 id="allocator.ext" xreflabel="allocator.ext">
<title>Extension Allocators</title>
<para>
Several other allocators are provided as part of this
implementation. The location of the extension allocators and their
names have changed, but in all cases, functionality is
equivalent. Starting with gcc-3.4, all extension allocators are
standard style. Before this point, SGI style was the norm. Because of
this, the number of template arguments also changed. Here's a simple
chart to track the changes.
</para>
<para>
More details on each of these extension allocators follows.
</para>
<orderedlist>
<listitem>
<para>
<classname>new_allocator</classname>
</para>
<para>
Simply wraps <function>::operator new</function>
and <function>::operator delete</function>.
</para>
</listitem>
<listitem>
<para>
<classname>malloc_allocator</classname>
</para>
<para>
Simply wraps <function>malloc</function> and
<function>free</function>. There is also a hook for an
out-of-memory handler (for
<function>new</function>/<function>delete</function> this is
taken care of elsewhere).
</para>
</listitem>
<listitem>
<para>
<classname>array_allocator</classname>
</para>
<para>
Allows allocations of known and fixed sizes using existing
global or external storage allocated via construction of
<classname>std::tr1::array</classname> objects. By using this
allocator, fixed size containers (including
<classname>std::string</classname>) can be used without
instances calling <function>::operator new</function> and
<function>::operator delete</function>. This capability
allows the use of STL abstractions without runtime
complications or overhead, even in situations such as program
startup. For usage examples, please consult the testsuite.
</para>
</listitem>
<listitem>
<para>
<classname>debug_allocator</classname>
</para>
<para>
A wrapper around an arbitrary allocator A. It passes on
slightly increased size requests to A, and uses the extra
memory to store size information. When a pointer is passed
to <function>deallocate()</function>, the stored size is
checked, and <function>assert()</function> is used to
guarantee they match.
</para>
</listitem>
<listitem>
<para>
<classname>throw_allocator</classname>
</para>
<para>
Includes memory tracking and marking abilities as well as hooks for
throwing exceptinos at configurable intervals (including random,
all, none).
</para>
</listitem>
<listitem>
<para>
<classname>__pool_alloc</classname>
</para>
<para>
A high-performance, single pool allocator. The reusable
memory is shared among identical instantiations of this type.
It calls through <function>::operator new</function> to
obtain new memory when its lists run out. If a client
container requests a block larger than a certain threshold
size, then the pool is bypassed, and the allocate/deallocate
request is passed to <function>::operator new</function>
directly.
</para>
<para>
Older versions of this class take a boolean template
parameter, called <varname>thr</varname>, and an integer template
parameter, called <varname>inst</varname>.
</para>
<para>
The <varname>inst</varname> number is used to track additional memory
pools. The point of the number is to allow multiple
instantiations of the classes without changing the semantics at
all. All three of
</para>
<programlisting>
typedef __pool_alloc&lt;true,0&gt; normal;
typedef __pool_alloc&lt;true,1&gt; private;
typedef __pool_alloc&lt;true,42&gt; also_private;
</programlisting>
<para>
behave exactly the same way. However, the memory pool for each type
(and remember that different instantiations result in different types)
remains separate.
</para>
<para>
The library uses <emphasis>0</emphasis> in all its instantiations. If you
wish to keep separate free lists for a particular purpose, use a
different number.
</para>
<para>The <varname>thr</varname> boolean determines whether the
pool should be manipulated atomically or not. When
<varname>thr</varname> = <constant>true</constant>, the allocator
is is threadsafe, while <varname>thr</varname> =
<constant>false</constant>, and is slightly faster but unsafe for
multiple threads.
</para>
<para>
For thread-enabled configurations, the pool is locked with a
single big lock. In some situations, this implementation detail
may result in severe performance degredation.
</para>
<para>
(Note that the GCC thread abstraction layer allows us to provide
safe zero-overhead stubs for the threading routines, if threads
were disabled at configuration time.)
</para>
</listitem>
<listitem>
<para>
<classname>__mt_alloc</classname>
</para>
<para>
A high-performance fixed-size allocator with
exponentially-increasing allocations. It has its own
documentation, found <ulink
url="../ext/mt_allocator.html">here</ulink>.
</para>
</listitem>
<listitem>
<para>
<classname>bitmap_allocator</classname>
</para>
<para>
A high-performance allocator that uses a bit-map to keep track
of the used and unused memory locations. It has its own
documentation, found <ulink
url="../ext/ballocator_doc.html">here</ulink>.
</para>
</listitem>
</orderedlist>
</sect2>
<bibliography id="allocator.biblio" xreflabel="allocator.biblio">
<title>Bibliography</title>
<biblioentry>
<title>
ISO/IEC 14882:1998 Programming languages - C++
</title>
<abbrev>
isoc++_1998
</abbrev>
<pagenums>20.4 Memory</pagenums>
</biblioentry>
<biblioentry>
<title>The Standard Librarian: What Are Allocators Good
</title>
<abbrev>
austernm
</abbrev>
<author>
<firstname>Matt</firstname>
<surname>Austern</surname>
</author>
<publisher>
<publishername>
C/C++ Users Journal
</publishername>
</publisher>
<biblioid>
<ulink url="http://www.cuj.com/documents/s=8000/cujcexp1812austern/">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>The Hoard Memory Allocator</title>
<abbrev>
emeryb
</abbrev>
<author>
<firstname>Emery</firstname>
<surname>Berger</surname>
</author>
<biblioid>
<ulink url="http://www.cs.umass.edu/~emery/hoard/">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>Reconsidering Custom Memory Allocation</title>
<abbrev>
bergerzorn
</abbrev>
<author>
<firstname>Emery</firstname>
<surname>Berger</surname>
</author>
<author>
<firstname>Ben</firstname>
<surname>Zorn</surname>
</author>
<author>
<firstname>Kathryn</firstname>
<surname>McKinley</surname>
</author>
<copyright>
<year>2002</year>
<holder>OOPSLA</holder>
</copyright>
<biblioid>
<ulink url="http://www.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>Allocator Types</title>
<abbrev>
kreftlanger
</abbrev>
<author>
<firstname>Klaus</firstname>
<surname>Kreft</surname>
</author>
<author>
<firstname>Angelika</firstname>
<surname>Langer</surname>
</author>
<publisher>
<publishername>
C/C++ Users Journal
</publishername>
</publisher>
<biblioid>
<ulink url="http://www.langer.camelot.de/Articles/C++Report/Allocators/Allocators.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>The C++ Programming Language</title>
<abbrev>
tcpl
</abbrev>
<author>
<firstname>Bjarne</firstname>
<surname>Stroustrup</surname>
</author>
<copyright>
<year>2000</year>
<holder></holder>
</copyright>
<pagenums>19.4 Allocators</pagenums>
<publisher>
<publishername>
Addison Wesley
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>Yalloc: A Recycling C++ Allocator</title>
<abbrev>
yenf
</abbrev>
<author>
<firstname>Felix</firstname>
<surname>Yen</surname>
</author>
<copyright>
<year></year>
<holder></holder>
</copyright>
<biblioid>
<ulink url="http://home.earthlink.net/~brimar/yalloc/">
</ulink>
</biblioid>
</biblioentry>
</bibliography>
</sect1>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,176 @@
<?xml version='1.0'?>
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<appendix id="appendix.free" xreflabel="Free">
<?dbhtml filename="appendix_free.html"?>
<appendixinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</appendixinfo>
<title>Free Software Needs Free Documentation</title>
<para>
The biggest deficiency in free operating systems is not in the
software--it is the lack of good free manuals that we can include in
these systems. Many of our most important programs do not come with
full manuals. Documentation is an essential part of any software
package; when an important free software package does not come with a
free manual, that is a major gap. We have many such gaps today.
</para>
<para>
Once upon a time, many years ago, I thought I would learn Perl. I got
a copy of a free manual, but I found it hard to read. When I asked
Perl users about alternatives, they told me that there were better
introductory manuals--but those were not free.
</para>
<para>
Why was this? The authors of the good manuals had written them for
O'Reilly Associates, which published them with restrictive terms--no
copying, no modification, source files not available--which exclude
them from the free software community.
</para>
<para>
That wasn't the first time this sort of thing has happened, and (to
our community's great loss) it was far from the last. Proprietary
manual publishers have enticed a great many authors to restrict their
manuals since then. Many times I have heard a GNU user eagerly tell
me about a manual that he is writing, with which he expects to help
the GNU project--and then had my hopes dashed, as he proceeded to
explain that he had signed a contract with a publisher that would
restrict it so that we cannot use it.
</para>
<para>
Given that writing good English is a rare skill among programmers, we
can ill afford to lose manuals this way.
</para>
<para>
Free documentation, like free software, is a matter of freedom,
not price. The problem with these manuals was not that O'Reilly
Associates charged a price for printed copies--that in itself is fine.
(The Free Software Foundation <ulink url="http://www.gnu.org/doc/doc.html">sells printed copies</ulink> of
free GNU manuals, too.) But GNU manuals are available in source code
form, while these manuals are available only on paper. GNU manuals
come with permission to copy and modify; the Perl manuals do not.
These restrictions are the problems.
</para>
<para>
The criterion for a free manual is pretty much the same as for free
software: it is a matter of giving all users certain freedoms.
Redistribution (including commercial redistribution) must be
permitted, so that the manual can accompany every copy of the program,
on-line or on paper. Permission for modification is crucial too.
</para>
<para>
As a general rule, I don't believe that it is essential for people to
have permission to modify all sorts of articles and books. The issues
for writings are not necessarily the same as those for software. For
example, I don't think you or I are obliged to give permission to
modify articles like this one, which describe our actions and our
views.
</para>
<para>
But there is a particular reason why the freedom to modify is crucial
for documentation for free software. When people exercise their right
to modify the software, and add or change its features, if they are
conscientious they will change the manual too--so they can provide
accurate and usable documentation with the modified program. A manual
which forbids programmers to be conscientious and finish the job, or
more precisely requires them to write a new manual from scratch if
they change the program, does not fill our community's needs.
</para>
<para>
While a blanket prohibition on modification is unacceptable, some
kinds of limits on the method of modification pose no problem. For
example, requirements to preserve the original author's copyright
notice, the distribution terms, or the list of authors, are ok. It is
also no problem to require modified versions to include notice that
they were modified, even to have entire sections that may not be
deleted or changed, as long as these sections deal with nontechnical
topics. (Some GNU manuals have them.)
</para>
<para>
These kinds of restrictions are not a problem because, as a practical
matter, they don't stop the conscientious programmer from adapting the
manual to fit the modified program. In other words, they don't block
the free software community from making full use of the manual.
</para>
<para>
However, it must be possible to modify all the <emphasis>technical</emphasis>
content of the manual, and then distribute the result in all the usual
media, through all the usual channels; otherwise, the restrictions do
block the community, the manual is not free, and so we need another
manual.
</para>
<para>
Unfortunately, it is often hard to find someone to write another
manual when a proprietary manual exists. The obstacle is that many
users think that a proprietary manual is good enough--so they don't
see the need to write a free manual. They do not see that the free
operating system has a gap that needs filling.
</para>
<para>
Why do users think that proprietary manuals are good enough? Some
have not considered the issue. I hope this article will do something
to change that.
</para>
<para>
Other users consider proprietary manuals acceptable for the same
reason so many people consider proprietary software acceptable: they
judge in purely practical terms, not using freedom as a criterion.
These people are entitled to their opinions, but since those opinions
spring from values which do not include freedom, they are no guide for
those of us who do value freedom.
</para>
<para>
Please spread the word about this issue. We continue to lose manuals
to proprietary publishing. If we spread the word that proprietary
manuals are not sufficient, perhaps the next person who wants to help
GNU by writing documentation will realize, before it is too late, that
he must above all make it free.
</para>
<para>
We can also encourage commercial publishers to sell free, copylefted
manuals instead of proprietary ones. One way you can help this is to
check the distribution terms of a manual before you buy it, and
prefer copylefted manuals to non-copylefted ones.
</para>
<para>
[Note: We now maintain a <ulink url="http://www.fsf.org/licensing/doc/other-free-books.html">web page
that lists free books available from other publishers</ulink>].
</para>
<para>Copyright © 2004, 2005, 2006, 2007 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA</para>
<para>Verbatim copying and distribution of this entire article are
permitted worldwide, without royalty, in any medium, provided this
notice is preserved.</para>
<para>Report any problems or suggestions to <email>webmaster@fsf.org</email>.</para>
</appendix>

View file

@ -0,0 +1,47 @@
<?xml version='1.0'?>
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<appendix id="appendix.porting" xreflabel="Porting">
<?dbhtml filename="appendix_porting.html"?>
<appendixinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</appendixinfo>
<title>Porting and Maintenance</title>
<!-- Hacking the Build System -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="build_hacking.xml">
</xi:include>
<!-- Internals: Porting to New Hardware or Operating Systems -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="internals.xml">
</xi:include>
<!-- ABI Policy and Guidelines -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="abi.xml">
</xi:include>
<!-- API Evolution and Deprecation History -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="evolution.xml">
</xi:include>
<!-- Backwards Compatibility -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="backwards_compatibility.xml">
</xi:include>
</appendix>

View file

@ -0,0 +1,133 @@
<sect1 id="manual.util.memory.auto_ptr" xreflabel="auto_ptr">
<?dbhtml filename="auto_ptr.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
auto_ptr
</keyword>
</keywordset>
</sect1info>
<title>auto_ptr</title>
<sect2 id="auto_ptr.limitations" xreflabel="auto_ptr.limitations">
<title>Limitations</title>
<para>Explaining all of the fun and delicious things that can
happen with misuse of the <classname>auto_ptr</classname> class
template (called <acronym>AP</acronym> here) would take some
time. Suffice it to say that the use of <acronym>AP</acronym>
safely in the presence of copying has some subtleties.
</para>
<para>
The AP class is a really
nifty idea for a smart pointer, but it is one of the dumbest of
all the smart pointers -- and that's fine.
</para>
<para>
AP is not meant to be a supersmart solution to all resource
leaks everywhere. Neither is it meant to be an effective form
of garbage collection (although it can help, a little bit).
And it can <emphasis>not</emphasis>be used for arrays!
</para>
<para>
<acronym>AP</acronym> is meant to prevent nasty leaks in the
presence of exceptions. That's <emphasis>all</emphasis>. This
code is AP-friendly:
</para>
<programlisting>
// Not a recommend naming scheme, but good for web-based FAQs.
typedef std::auto_ptr&lt;MyClass&gt; APMC;
extern function_taking_MyClass_pointer (MyClass*);
extern some_throwable_function ();
void func (int data)
{
APMC ap (new MyClass(data));
some_throwable_function(); // this will throw an exception
function_taking_MyClass_pointer (ap.get());
}
</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>
APMC ap (new MyClass[22]);
</programlisting>
<para>You will get the same problems as you would without the use
of <acronym>AP</acronym>:
</para>
<programlisting>
char* array = new char[10]; // array new...
...
delete array; // ...but single-object delete
</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
to die. AP is trivial to write, however, so you could write your
own <code>auto_array_ptr</code> for that situation (in fact, this has
been done many times; check the mailing lists, Usenet, Boost, etc).
</para>
</sect2>
<sect2 id="auto_ptr.using" xreflabel="auto_ptr.using">
<title>Use in Containers</title>
<para>
</para>
<para>All of the <ulink url="../23_containers/howto.html">containers</ulink>
described in the standard library require their contained types
to have, among other things, a copy constructor like this:
</para>
<programlisting>
struct My_Type
{
My_Type (My_Type const&amp;);
};
</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
meet this requirement. Creating a new AP by copying an existing
one transfers ownership of the pointed-to object, which means that
the AP being copied must change, which in turn means that the
copy ctors of AP do not take const objects.
</para>
<para>
The resulting rule is simple: <emphasis>Never ever use a
container of auto_ptr objects</emphasis>. The standard says that
<quote>undefined</quote> behavior is the result, but it is
guaranteed to be messy.
</para>
<para>
To prevent you from doing this to yourself, the
<ulink url="../19_diagnostics/howto.html#3">concept checks</ulink> built
in to this implementation will issue an error if you try to
compile code like this:
</para>
<programlisting>
#include &lt;vector&gt;
#include &lt;memory&gt;
void f()
{
std::vector&lt; std::auto_ptr&lt;int&gt; &gt; vec_ap_int;
}
</programlisting>
<para>
Should you try this with the checks enabled, you will see an error.
</para>
</sect2>
</sect1>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,559 @@
<sect1 id="manual.ext.allocator.bitmap" xreflabel="mt allocator">
<?dbhtml filename="bitmap_allocator.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
allocator
</keyword>
</keywordset>
</sect1info>
<title>bitmap_allocator</title>
<para>
</para>
<sect2 id="allocator.bitmap.design" xreflabel="allocator.bitmap.design">
<title>Design</title>
<para>
As this name suggests, this allocator uses a bit-map to keep track
of the used and unused memory locations for it's book-keeping
purposes.
</para>
<para>
This allocator will make use of 1 single bit to keep track of
whether it has been allocated or not. A bit 1 indicates free,
while 0 indicates allocated. This has been done so that you can
easily check a collection of bits for a free block. This kind of
Bitmapped strategy works best for single object allocations, and
with the STL type parameterized allocators, we do not need to
choose any size for the block which will be represented by a
single bit. This will be the size of the parameter around which
the allocator has been parameterized. Thus, close to optimal
performance will result. Hence, this should be used for node based
containers which call the allocate function with an argument of 1.
</para>
<para>
The bitmapped allocator's internal pool is exponentially growing.
Meaning that internally, the blocks acquired from the Free List
Store will double every time the bitmapped allocator runs out of
memory.
</para>
<para>
The macro <literal>__GTHREADS</literal> decides whether to use
Mutex Protection around every allocation/deallocation. The state
of the macro is picked up automatically from the gthr abstraction
layer.
</para>
</sect2>
<sect2 id="allocator.bitmap.impl" xreflabel="allocator.bitmap.impl">
<title>Implementation</title>
<sect3 id="bitmap.impl.free_list_store" xreflabel="Free List Store">
<title>Free List Store</title>
<para>
The Free List Store (referred to as FLS for the remaining part of this
document) is the Global memory pool that is shared by all instances of
the bitmapped allocator instantiated for any type. This maintains a
sorted order of all free memory blocks given back to it by the
bitmapped allocator, and is also responsible for giving memory to the
bitmapped allocator when it asks for more.
</para>
<para>
Internally, there is a Free List threshold which indicates the
Maximum number of free lists that the FLS can hold internally
(cache). Currently, this value is set at 64. So, if there are
more than 64 free lists coming in, then some of them will be given
back to the OS using operator delete so that at any given time the
Free List's size does not exceed 64 entries. This is done because
a Binary Search is used to locate an entry in a free list when a
request for memory comes along. Thus, the run-time complexity of
the search would go up given an increasing size, for 64 entries
however, lg(64) == 6 comparisons are enough to locate the correct
free list if it exists.
</para>
<para>
Suppose the free list size has reached it's threshold, then the
largest block from among those in the list and the new block will
be selected and given back to the OS. This is done because it
reduces external fragmentation, and allows the OS to use the
larger blocks later in an orderly fashion, possibly merging them
later. Also, on some systems, large blocks are obtained via calls
to mmap, so giving them back to free system resources becomes most
important.
</para>
<para>
The function _S_should_i_give decides the policy that determines
whether the current block of memory should be given to the
allocator for the request that it has made. That's because we may
not always have exact fits for the memory size that the allocator
requests. We do this mainly to prevent external fragmentation at
the cost of a little internal fragmentation. Now, the value of
this internal fragmentation has to be decided by this function. I
can see 3 possibilities right now. Please add more as and when you
find better strategies.
</para>
<orderedlist>
<listitem><para>Equal size check. Return true only when the 2 blocks are of equal
size.</para></listitem>
<listitem><para>Difference Threshold: Return true only when the _block_size is
greater than or equal to the _required_size, and if the _BS is &gt; _RS
by a difference of less than some THRESHOLD value, then return true,
else return false. </para></listitem>
<listitem><para>Percentage Threshold. Return true only when the _block_size is
greater than or equal to the _required_size, and if the _BS is &gt; _RS
by a percentage of less than some THRESHOLD value, then return true,
else return false.</para></listitem>
</orderedlist>
<para>
Currently, (3) is being used with a value of 36% Maximum wastage per
Super Block.
</para>
</sect3>
<sect3 id="bitmap.impl.super_block" xreflabel="Super Block">
<title>Super Block</title>
<para>
A super block is the block of memory acquired from the FLS from
which the bitmap allocator carves out memory for single objects
and satisfies the user's requests. These super blocks come in
sizes that are powers of 2 and multiples of 32
(_Bits_Per_Block). Yes both at the same time! That's because the
next super block acquired will be 2 times the previous one, and
also all super blocks have to be multiples of the _Bits_Per_Block
value.
</para>
<para>
How does it interact with the free list store?
</para>
<para>
The super block is contained in the FLS, and the FLS is responsible for
getting / returning Super Bocks to and from the OS using operator new
as defined by the C++ standard.
</para>
</sect3>
<sect3 id="bitmap.impl.super_block_data" xreflabel="Super Block Data">
<title>Super Block Data Layout</title>
<para>
Each Super Block will be of some size that is a multiple of the
number of Bits Per Block. Typically, this value is chosen as
Bits_Per_Byte x sizeof(size_t). On an x86 system, this gives the
figure 8 x 4 = 32. Thus, each Super Block will be of size 32
x Some_Value. This Some_Value is sizeof(value_type). For now, let
it be called 'K'. Thus, finally, Super Block size is 32 x K bytes.
</para>
<para>
This value of 32 has been chosen because each size_t has 32-bits
and Maximum use of these can be made with such a figure.
</para>
<para>
Consider a block of size 64 ints. In memory, it would look like this:
(assume a 32-bit system where, size_t is a 32-bit entity).
</para>
<table frame='all'>
<title>Bitmap Allocator Memory Map</title>
<tgroup cols='5' align='left' colsep='1' rowsep='1'>
<colspec colname='c1'></colspec>
<colspec colname='c2'></colspec>
<colspec colname='c3'></colspec>
<colspec colname='c4'></colspec>
<colspec colname='c5'></colspec>
<tbody>
<row>
<entry>268</entry>
<entry>0</entry>
<entry>4294967295</entry>
<entry>4294967295</entry>
<entry>Data -&gt; Space for 64 ints</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
The first Column(268) represents the size of the Block in bytes as
seen by the Bitmap Allocator. Internally, a global free list is
used to keep track of the free blocks used and given back by the
bitmap allocator. It is this Free List Store that is responsible
for writing and managing this information. Actually the number of
bytes allocated in this case would be: 4 + 4 + (4x2) + (64x4) =
272 bytes, but the first 4 bytes are an addition by the Free List
Store, so the Bitmap Allocator sees only 268 bytes. These first 4
bytes about which the bitmapped allocator is not aware hold the
value 268.
</para>
<para>
What do the remaining values represent?</para>
<para>
The 2nd 4 in the expression is the sizeof(size_t) because the
Bitmapped Allocator maintains a used count for each Super Block,
which is initially set to 0 (as indicated in the diagram). This is
incremented every time a block is removed from this super block
(allocated), and decremented whenever it is given back. So, when
the used count falls to 0, the whole super block will be given
back to the Free List Store.
</para>
<para>
The value 4294967295 represents the integer corresponding to the bit
representation of all bits set: 11111111111111111111111111111111.
</para>
<para>
The 3rd 4x2 is size of the bitmap itself, which is the size of 32-bits
x 2,
which is 8-bytes, or 2 x sizeof(size_t).
</para>
</sect3>
<sect3 id="bitmap.impl.max_wasted" xreflabel="Max Wasted Percentage">
<title>Maximum Wasted Percentage</title>
<para>
This has nothing to do with the algorithm per-se,
only with some vales that must be chosen correctly to ensure that the
allocator performs well in a real word scenario, and maintains a good
balance between the memory consumption and the allocation/deallocation
speed.
</para>
<para>
The formula for calculating the maximum wastage as a percentage:
</para>
<para>
(32 x k + 1) / (2 x (32 x k + 1 + 32 x c)) x 100.
</para>
<para>
Where, k =&gt; The constant overhead per node. eg. for list, it is
8 bytes, and for map it is 12 bytes. c =&gt; The size of the
base type on which the map/list is instantiated. Thus, suppose the
type1 is int and type2 is double, they are related by the relation
sizeof(double) == 2*sizeof(int). Thus, all types must have this
double size relation for this formula to work properly.
</para>
<para>
Plugging-in: For List: k = 8 and c = 4 (int and double), we get:
33.376%
</para>
<para>
For map/multimap: k = 12, and c = 4 (int and double), we get: 37.524%
</para>
<para>
Thus, knowing these values, and based on the sizeof(value_type), we may
create a function that returns the Max_Wastage_Percentage for us to use.
</para>
</sect3>
<sect3 id="bitmap.impl.allocate" xreflabel="Allocate">
<title><function>allocate</function></title>
<para>
The allocate function is specialized for single object allocation
ONLY. Thus, ONLY if n == 1, will the bitmap_allocator's
specialized algorithm be used. Otherwise, the request is satisfied
directly by calling operator new.
</para>
<para>
Suppose n == 1, then the allocator does the following:
</para>
<orderedlist>
<listitem>
<para>
Checks to see whether a free block exists somewhere in a region
of memory close to the last satisfied request. If so, then that
block is marked as allocated in the bit map and given to the
user. If not, then (2) is executed.
</para>
</listitem>
<listitem>
<para>
Is there a free block anywhere after the current block right
up to the end of the memory that we have? If so, that block is
found, and the same procedure is applied as above, and
returned to the user. If not, then (3) is executed.
</para>
</listitem>
<listitem>
<para>
Is there any block in whatever region of memory that we own
free? This is done by checking
</para>
<itemizedlist>
<listitem>
<para>
The use count for each super block, and if that fails then
</para>
</listitem>
<listitem>
<para>
The individual bit-maps for each super block.
</para>
</listitem>
</itemizedlist>
<para>
Note: Here we are never touching any of the memory that the
user will be given, and we are confining all memory accesses
to a small region of memory! This helps reduce cache
misses. If this succeeds then we apply the same procedure on
that bit-map as (1), and return that block of memory to the
user. However, if this process fails, then we resort to (4).
</para>
</listitem>
<listitem>
<para>
This process involves Refilling the internal exponentially
growing memory pool. The said effect is achieved by calling
_S_refill_pool which does the following:
</para>
<itemizedlist>
<listitem>
<para>
Gets more memory from the Global Free List of the Required
size.
</para>
</listitem>
<listitem>
<para>
Adjusts the size for the next call to itself.
</para>
</listitem>
<listitem>
<para>
Writes the appropriate headers in the bit-maps.
</para>
</listitem>
<listitem>
<para>
Sets the use count for that super-block just allocated to 0
(zero).
</para>
</listitem>
<listitem>
<para>
All of the above accounts to maintaining the basic invariant
for the allocator. If the invariant is maintained, we are
sure that all is well. Now, the same process is applied on
the newly acquired free blocks, which are dispatched
accordingly.
</para>
</listitem>
</itemizedlist>
</listitem>
</orderedlist>
<para>
Thus, you can clearly see that the allocate function is nothing but a
combination of the next-fit and first-fit algorithm optimized ONLY for
single object allocations.
</para>
</sect3>
<sect3 id="bitmap.impl.deallocate" xreflabel="Deallocate">
<title><function>deallocate</function></title>
<para>
The deallocate function again is specialized for single objects ONLY.
For all n belonging to &gt; 1, the operator delete is called without
further ado, and the deallocate function returns.
</para>
<para>
However for n == 1, a series of steps are performed:
</para>
<orderedlist>
<listitem><para>
We first need to locate that super-block which holds the memory
location given to us by the user. For that purpose, we maintain
a static variable _S_last_dealloc_index, which holds the index
into the vector of block pairs which indicates the index of the
last super-block from which memory was freed. We use this
strategy in the hope that the user will deallocate memory in a
region close to what he/she deallocated the last time around. If
the check for belongs_to succeeds, then we determine the bit-map
for the given pointer, and locate the index into that bit-map,
and mark that bit as free by setting it.
</para></listitem>
<listitem><para>
If the _S_last_dealloc_index does not point to the memory block
that we're looking for, then we do a linear search on the block
stored in the vector of Block Pairs. This vector in code is
called _S_mem_blocks. When the corresponding super-block is
found, we apply the same procedure as we did for (1) to mark the
block as free in the bit-map.
</para></listitem>
</orderedlist>
<para>
Now, whenever a block is freed, the use count of that particular
super block goes down by 1. When this use count hits 0, we remove
that super block from the list of all valid super blocks stored in
the vector. While doing this, we also make sure that the basic
invariant is maintained by making sure that _S_last_request and
_S_last_dealloc_index point to valid locations within the vector.
</para>
</sect3>
<sect3 id="bitmap.impl.questions" xreflabel="Questions">
<title>Questions</title>
<sect4 id="bitmap.impl.question.1" xreflabel="Question 1">
<title>1</title>
<para>
Q1) The "Data Layout" section is
cryptic. I have no idea of what you are trying to say. Layout of what?
The free-list? Each bitmap? The Super Block?
</para>
<para>
The layout of a Super Block of a given
size. In the example, a super block of size 32 x 1 is taken. The
general formula for calculating the size of a super block is
32 x sizeof(value_type) x 2^n, where n ranges from 0 to 32 for 32-bit
systems.
</para>
</sect4>
<sect4 id="bitmap.impl.question.2" xreflabel="Question 2">
<title>2</title>
<para>
And since I just mentioned the
term `each bitmap', what in the world is meant by it? What does each
bitmap manage? How does it relate to the super block? Is the Super
Block a bitmap as well?
</para>
<para>
Each bitmap is part of a Super Block which is made up of 3 parts
as I have mentioned earlier. Re-iterating, 1. The use count,
2. The bit-map for that Super Block. 3. The actual memory that
will be eventually given to the user. Each bitmap is a multiple
of 32 in size. If there are 32 x (2^3) blocks of single objects
to be given, there will be '32 x (2^3)' bits present. Each 32
bits managing the allocated / free status for 32 blocks. Since
each size_t contains 32-bits, one size_t can manage up to 32
blocks' status. Each bit-map is made up of a number of size_t,
whose exact number for a super-block of a given size I have just
mentioned.
</para>
</sect4>
<sect4 id="bitmap.impl.question.3" xreflabel="Question 3">
<title>3</title>
<para>
How do the allocate and deallocate functions work in regard to
bitmaps?
</para>
<para>
The allocate and deallocate functions manipulate the bitmaps and
have nothing to do with the memory that is given to the user. As
I have earlier mentioned, a 1 in the bitmap's bit field
indicates free, while a 0 indicates allocated. This lets us
check 32 bits at a time to check whether there is at lease one
free block in those 32 blocks by testing for equality with
(0). Now, the allocate function will given a memory block find
the corresponding bit in the bitmap, and will reset it (i.e.,
make it re-set (0)). And when the deallocate function is called,
it will again set that bit after locating it to indicate that
that particular block corresponding to this bit in the bit-map
is not being used by anyone, and may be used to satisfy future
requests.
</para>
<para>
e.g.: Consider a bit-map of 64-bits as represented below:
1111111111111111111111111111111111111111111111111111111111111111
</para>
<para>
Now, when the first request for allocation of a single object
comes along, the first block in address order is returned. And
since the bit-maps in the reverse order to that of the address
order, the last bit (LSB if the bit-map is considered as a
binary word of 64-bits) is re-set to 0.
</para>
<para>
The bit-map now looks like this:
1111111111111111111111111111111111111111111111111111111111111110
</para>
</sect4>
</sect3>
<sect3 id="bitmap.impl.locality" xreflabel="Locality">
<title>Locality</title>
<para>
Another issue would be whether to keep the all bitmaps in a
separate area in memory, or to keep them near the actual blocks
that will be given out or allocated for the client. After some
testing, I've decided to keep these bitmaps close to the actual
blocks. This will help in 2 ways.
</para>
<orderedlist>
<listitem><para>Constant time access for the bitmap themselves, since no kind of
look up will be needed to find the correct bitmap list or it's
equivalent.</para></listitem>
<listitem><para>And also this would preserve the cache as far as possible.</para></listitem>
</orderedlist>
<para>
So in effect, this kind of an allocator might prove beneficial from a
purely cache point of view. But this allocator has been made to try and
roll out the defects of the node_allocator, wherein the nodes get
skewed about in memory, if they are not returned in the exact reverse
order or in the same order in which they were allocated. Also, the
new_allocator's book keeping overhead is too much for small objects and
single object allocations, though it preserves the locality of blocks
very well when they are returned back to the allocator.
</para>
</sect3>
<sect3 id="bitmap.impl.grow_policy" xreflabel="Grow Policy">
<title>Overhead and Grow Policy</title>
<para>
Expected overhead per block would be 1 bit in memory. Also, once
the address of the free list has been found, the cost for
allocation/deallocation would be negligible, and is supposed to be
constant time. For these very reasons, it is very important to
minimize the linear time costs, which include finding a free list
with a free block while allocating, and finding the corresponding
free list for a block while deallocating. Therefore, I have
decided that the growth of the internal pool for this allocator
will be exponential as compared to linear for
node_allocator. There, linear time works well, because we are
mainly concerned with speed of allocation/deallocation and memory
consumption, whereas here, the allocation/deallocation part does
have some linear/logarithmic complexity components in it. Thus, to
try and minimize them would be a good thing to do at the cost of a
little bit of memory.
</para>
<para>
Another thing to be noted is the pool size will double every time
the internal pool gets exhausted, and all the free blocks have
been given away. The initial size of the pool would be
sizeof(size_t) x 8 which is the number of bits in an integer,
which can fit exactly in a CPU register. Hence, the term given is
exponential growth of the internal pool.
</para>
</sect3>
</sect2>
</sect1>

View file

@ -0,0 +1,182 @@
<sect1 id="manual.intro.setup.build" xreflabel="Building">
<?dbhtml filename="build.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
build
</keyword>
</keywordset>
</sect1info>
<title>Build</title>
<para>
Because libstdc++ is part of GCC, the primary source for
installation instructions is
<ulink url="http://gcc.gnu.org/install/">the GCC install page</ulink>.
Additional data is given here only where it applies to libstdc++.
</para>
<sect2 id="build.prereq" xreflabel="build.prereq">
<title>Prerequisites</title>
<para>
The list of software needed to build the library is kept with the
rest of the compiler, at
<ulink url="http://gcc.gnu.org/install/prerequisites.html">
http://gcc.gnu.org/install/prerequisites.html</ulink>. The same page
also lists the tools you will need if you wish to modify the source.
</para>
<para>As of GCC 4.0.1 the minimum version of binutils required to build
libstdc++ is <code>2.15.90.0.1.1</code>. You can get snapshots
(as well as releases) of binutils from
<ulink url="ftp://sources.redhat.com/pub/binutils">
ftp://sources.redhat.com/pub/binutils</ulink>.
Older releases of libstdc++ do not require such a recent version,
but to take full advantage of useful space-saving features and
bug-fixes you should use a recent binutils if possible.
The configure process will automatically detect and use these
features if the underlying support is present.
</para>
<para>
Finally, a few system-specific requirements:
</para>
<variablelist>
<varlistentry>
<term>linux</term>
<listitem>
<para>
If gcc 3.1.0 or later on is being used on linux, an attempt
will be made to use "C" library functionality necessary for
C++ named locale support. For gcc 3.2.1 and later, this
means that glibc 2.2.5 or later is required and the "C"
library de_DE locale information must be installed.
</para>
<para>
Note however that the sanity checks involving the de_DE
locale are skipped when an explicit --enable-clocale=gnu
configure option is used: only the basic checks are carried
out, defending against misconfigurations.
</para>
<para>
If the 'gnu' locale model is being used, the following
locales are used and tested in the libstdc++ testsuites.
The first column is the name of the locale, the second is
the character set it is expected to use.
</para>
<programlisting>
de_DE ISO-8859-1
de_DE@euro ISO-8859-15
en_HK ISO-8859-1
en_PH ISO-8859-1
en_US ISO-8859-1
en_US.ISO-8859-1 ISO-8859-1
en_US.ISO-8859-15 ISO-8859-15
en_US.UTF-8 UTF-8
es_ES ISO-8859-1
es_MX ISO-8859-1
fr_FR ISO-8859-1
fr_FR@euro ISO-8859-15
is_IS UTF-8
it_IT ISO-8859-1
ja_JP.eucjp EUC-JP
se_NO.UTF-8 UTF-8
ta_IN UTF-8
zh_TW BIG5
</programlisting>
<para>Failure to have the underlying "C" library locale
information installed will mean that C++ named locales for the
above regions will not work: because of this, the libstdc++
testsuite will skip the named locale tests. If this isn't an
issue, don't worry about it. If named locales are needed, the
underlying locale information must be installed. Note that
rebuilding libstdc++ after the "C" locales are installed is not
necessary.
</para>
<para>
To install support for locales, do only one of the following:
</para>
<itemizedlist>
<listitem>
<para>install all locales</para>
<itemizedlist>
<listitem>
<para>with RedHat Linux:
</para>
<para> <code> export LC_ALL=C </code>
</para>
<para> <code> rpm -e glibc-common --nodeps </code>
</para>
<para>
<code> rpm -i --define "_install_langs all"
glibc-common-2.2.5-34.i386.rpm
</code>
</para>
</listitem>
<listitem>
<para>
Instructions for other operating systems solicited.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>install just the necessary locales</para>
<itemizedlist>
<listitem>
<para>with Debian Linux:</para>
<para> Add the above list, as shown, to the file
<code>/etc/locale.gen</code> </para>
<para> run <code>/usr/sbin/locale-gen</code> </para>
</listitem>
<listitem>
<para>on most Unix-like operating systems:</para>
<para><code> localedef -i de_DE -f ISO-8859-1 de_DE </code></para>
<para>(repeat for each entry in the above list) </para>
</listitem>
<listitem>
<para>
Instructions for other operating systems solicited.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2 id="build.configure" xreflabel="build.make">
<title>Make</title>
<para>If you have never done this before, you should read the basic
<ulink url="http://gcc.gnu.org/install/">GCC Installation
Instructions</ulink> first. Read <emphasis>all of them</emphasis>.
<emphasis>Twice.</emphasis>
</para>
<para>When building libstdc++ you'll have to configure
the entire <emphasis>gccsrcdir</emphasis> directory. The full list of libstdc++
specific configuration options, not dependent on the specific compiler
release being used, can be found <ulink url="configopts.html">here</ulink>.
</para>
<para>Consider possibly using --enable-languages=c++ to save time by only
building the C++ language parts.
</para>
<programlisting>
cd <emphasis>gccbuilddir</emphasis>
<emphasis>gccsrcdir</emphasis>/configure --prefix=<emphasis>destdir</emphasis> --other-opts...</programlisting>
</sect2>
</sect1>

View file

@ -0,0 +1,354 @@
<sect1 id="appendix.porting.build_hacking" xreflabel="build_hacking">
<?dbhtml filename="build_hacking.html"?>
<sect1info>
<keywordset>
<keyword>
C++
</keyword>
<keyword>
BUILD_HACKING
</keyword>
<keyword>
version
</keyword>
<keyword>
dynamic
</keyword>
<keyword>
shared
</keyword>
</keywordset>
</sect1info>
<title>Configure and Build Hacking</title>
<sect2 id="build_hacking.prereq" xreflabel="build_hacking.prereq">
<title>Prerequisites</title>
<para>
As noted <ulink
url="http://gcc.gnu.org/install/prerequisites.html">previously</ulink>,
certain other tools are necessary for hacking on files that
control configure (<code>configure.ac</code>,
<code>acinclude.m4</code>) and make
(<code>Makefile.am</code>). These additional tools
(<code>automake</code>, and <code>autoconf</code>) are further
described in detail in their respective manuals. All the libraries
in GCC try to stay in sync with each other in terms of versions of
the auto-tools used, so please try to play nicely with the
neighbors.
</para>
</sect2>
<sect2 id="build_hacking.map" xreflabel="build_hacking.map">
<title>Overview: What Comes from Where</title>
<screen>
<inlinemediaobject>
<imageobject>
<imagedata fileref="../images/confdeps.png"/>
</imageobject>
<textobject>
<phrase>Dependency Graph Configure to Build Files</phrase>
</textobject>
</inlinemediaobject>
</screen>
<para>
Regenerate all generated files by using the command sequence
<code>"autoreconf"</code> at the top level of the libstdc++ source
directory. The following will also work, but is much more complex:
<code>"aclocal-1.7 &amp;&amp; autoconf-2.59 &amp;&amp;
autoheader-2.59 &amp;&amp; automake-1.7"</code> The version
numbers may be absent entirely or otherwise vary depending on
<ulink url="http://gcc.gnu.org/install/prerequisites.html">the
current requirements</ulink> and your vendor's choice of
installation names.
</para>
</sect2>
<sect2 id="build_hacking.scripts" xreflabel="build_hacking.scripts">
<title>Storing Information in non-AC files (like configure.host)</title>
<para>
Until that glorious day when we can use AC_TRY_LINK with a
cross-compiler, we have to hardcode the results of what the tests
would have shown if they could be run. So we have an inflexible
mess like crossconfig.m4.
</para>
<para>
Wouldn't it be nice if we could store that information in files
like configure.host, which can be modified without needing to
regenerate anything, and can even be tweaked without really
knowing how the configury all works? Perhaps break the pieces of
crossconfig.m4 out and place them in their appropriate
config/{cpu,os} directory.
</para>
<para>
Alas, writing macros like
"<code>AC_DEFINE(HAVE_A_NICE_DAY)</code>" can only be done inside
files which are passed through autoconf. Files which are pure
shell script can be source'd at configure time. Files which
contain autoconf macros must be processed with autoconf. We could
still try breaking the pieces out into "config/*/cross.m4" bits,
for instance, but then we would need arguments to aclocal/autoconf
to properly find them all when generating configure. I would
discourage that.
</para>
</sect2>
<sect2 id="build_hacking.conventions" xreflabel="build_hacking.conventions">
<title>Coding and Commenting Conventions</title>
<para>
Most comments should use {octothorpes, shibboleths, hash marks,
pound signs, whatevers} rather than "dnl". Nearly all comments in
configure.ac should. Comments inside macros written in ancilliary
.m4 files should. About the only comments which should
<emphasis>not</emphasis> use #, but use dnl instead, are comments
<emphasis>outside</emphasis> our own macros in the ancilliary
files. The difference is that # comments show up in
<code>configure</code> (which is most helpful for debugging),
while dnl'd lines just vanish. Since the macros in ancilliary
files generate code which appears in odd places, their "outside"
comments tend to not be useful while reading
<code>configure</code>.
</para>
<para>
Do not use any <code>$target*</code> variables, such as
<code>$target_alias</code>. The single exception is in
configure.ac, for automake+dejagnu's sake.
</para>
</sect2>
<sect2 id="build_hacking.acinclude" xreflabel="build_hacking.acinclude">
<title>The acinclude.m4 layout</title>
<para>
The nice thing about acinclude.m4/aclocal.m4 is that macros aren't
actually performed/called/expanded/whatever here, just loaded. So
we can arrange the contents however we like. As of this writing,
acinclude.m4 is arranged as follows:
</para>
<programlisting>
GLIBCXX_CHECK_HOST
GLIBCXX_TOPREL_CONFIGURE
GLIBCXX_CONFIGURE
</programlisting>
<para>
All the major variable "discovery" is done here. CXX, multilibs,
etc.
</para>
<programlisting>
fragments included from elsewhere
</programlisting>
<para>
Right now, "fragments" == "the math/linkage bits".
</para>
<programlisting>
GLIBCXX_CHECK_COMPILER_FEATURES
GLIBCXX_CHECK_LINKER_FEATURES
GLIBCXX_CHECK_WCHAR_T_SUPPORT
</programlisting>
<para>
Next come extra compiler/linker feature tests. Wide character
support was placed here because I couldn't think of another place
for it. It will probably get broken apart like the math tests,
because we're still disabling wchars on systems which could actually
support them.
</para>
<programlisting>
GLIBCXX_CHECK_SETRLIMIT_ancilliary
GLIBCXX_CHECK_SETRLIMIT
GLIBCXX_CHECK_S_ISREG_OR_S_IFREG
GLIBCXX_CHECK_POLL
GLIBCXX_CHECK_WRITEV
GLIBCXX_CONFIGURE_TESTSUITE
</programlisting>
<para>
Feature tests which only get used in one place. Here, things used
only in the testsuite, plus a couple bits used in the guts of I/O.
</para>
<programlisting>
GLIBCXX_EXPORT_INCLUDES
GLIBCXX_EXPORT_FLAGS
GLIBCXX_EXPORT_INSTALL_INFO
</programlisting>
<para>
Installation variables, multilibs, working with the rest of the
compiler. Many of the critical variables used in the makefiles are
set here.
</para>
<programlisting>
GLIBGCC_ENABLE
GLIBCXX_ENABLE_C99
GLIBCXX_ENABLE_CHEADERS
GLIBCXX_ENABLE_CLOCALE
GLIBCXX_ENABLE_CONCEPT_CHECKS
GLIBCXX_ENABLE_CSTDIO
GLIBCXX_ENABLE_CXX_FLAGS
GLIBCXX_ENABLE_C_MBCHAR
GLIBCXX_ENABLE_DEBUG
GLIBCXX_ENABLE_DEBUG_FLAGS
GLIBCXX_ENABLE_LONG_LONG
GLIBCXX_ENABLE_PCH
GLIBCXX_ENABLE_SJLJ_EXCEPTIONS
GLIBCXX_ENABLE_SYMVERS
GLIBCXX_ENABLE_THREADS
</programlisting>
<para>
All the features which can be controlled with enable/disable
configure options. Note how they're alphabetized now? Keep them
like that. :-)
</para>
<programlisting>
AC_LC_MESSAGES
libtool bits
</programlisting>
<para>
Things which we don't seem to use directly, but just has to be
present otherwise stuff magically goes wonky.
</para>
</sect2>
<sect2 id="build_hacking.enable" xreflabel="build_hacking.enable">
<title><constant>GLIBCXX_ENABLE</constant>, the <literal>--enable</literal> maker</title>
<para>
All the GLIBCXX_ENABLE_FOO macros use a common helper,
GLIBCXX_ENABLE. (You don't have to use it, but it's easy.) The
helper does two things for us:
</para>
<orderedlist>
<listitem>
<para>
Builds the call to the AC_ARG_ENABLE macro, with --help text
properly quoted and aligned. (Death to changequote!)
</para>
</listitem>
<listitem>
<para>
Checks the result against a list of allowed possibilities, and
signals a fatal error if there's no match. This means that the
rest of the GLIBCXX_ENABLE_FOO macro doesn't need to test for
strange arguments, nor do we need to protect against
empty/whitespace strings with the <code>"x$foo" = "xbar"</code>
idiom.
</para>
</listitem>
</orderedlist>
<para>Doing these things correctly takes some extra autoconf/autom4te code,
which made our macros nearly illegible. So all the ugliness is factored
out into this one helper macro.
</para>
<para>Many of the macros take an argument, passed from when they are expanded
in configure.ac. The argument controls the default value of the
enable/disable switch. Previously, the arguments themselves had defaults.
Now they don't, because that's extra complexity with zero gain for us.
</para>
<para>There are three "overloaded signatures". When reading the descriptions
below, keep in mind that the brackets are autoconf's quotation characters,
and that they will be stripped. Examples of just about everything occur
in acinclude.m4, if you want to look.
</para>
<programlisting>
GLIBCXX_ENABLE (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
GLIBCXX_ENABLE (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
GLIBCXX_ENABLE (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
</programlisting>
<itemizedlist>
<listitem>
<para>
FEATURE is the string that follows --enable. The results of the
test (such as it is) will be in the variable $enable_FEATURE,
where FEATURE has been squashed. Example:
<code>[extra-foo]</code>, controlled by the --enable-extra-foo
option and stored in $enable_extra_foo.
</para>
</listitem>
<listitem>
<para>
DEFAULT is the value to store in $enable_FEATURE if the user does
not pass --enable/--disable. It should be one of the permitted
values passed later. Examples: <code>[yes]</code>, or
<code>[bar]</code>, or <code>[$1]</code> (which passes the
argument given to the GLIBCXX_ENABLE_FOO macro as the
default).
</para>
<para>
For cases where we need to probe for particular models of things,
it is useful to have an undocumented "auto" value here (see
GLIBCXX_ENABLE_CLOCALE for an example).
</para>
</listitem>
<listitem>
<para>
HELP-ARG is any text to append to the option string itself in the
--help output. Examples: <code>[]</code> (i.e., an empty string,
which appends nothing), <code>[=BAR]</code>, which produces
<code>--enable-extra-foo=BAR</code>, and
<code>[@&lt;:@=BAR@:&gt;@]</code>, which produces
<code>--enable-extra-foo[=BAR]</code>. See the difference? See
what it implies to the user?
</para>
<para>
If you're wondering what that line noise in the last example was,
that's how you embed autoconf special characters in output text.
They're called <ulink
url="http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_95.html#SEC95"><emphasis>quadrigraphs</emphasis></ulink>
and you should use them whenever necessary.
</para>
</listitem>
<listitem>
<para>HELP-STRING is what you think it is. Do not include the
"default" text like we used to do; it will be done for you by
GLIBCXX_ENABLE. By convention, these are not full English
sentences. Example: [turn on extra foo]
</para>
</listitem>
</itemizedlist>
<para>
With no other arguments, only the standard autoconf patterns are
allowed: "<code>--{enable,disable}-foo[={yes,no}]</code>" The
$enable_FEATURE variable is guaranteed to equal either "yes" or "no"
after the macro. If the user tries to pass something else, an
explanatory error message will be given, and configure will halt.
</para>
<para>
The second signature takes a fifth argument, "<code>[permit
a | b | c | ...]</code>"
This allows <emphasis>a</emphasis> or <emphasis>b</emphasis> or
... after the equals sign in the option, and $enable_FEATURE is
guaranteed to equal one of them after the macro. Note that if you
want to allow plain --enable/--disable with no "=whatever", you must
include "yes" and "no" in the list of permitted values. Also note
that whatever you passed as DEFAULT must be in the list. If the
user tries to pass something not on the list, a semi-explanatory
error message will be given, and configure will halt. Example:
<code>[permit generic|gnu|ieee_1003.1-2001|yes|no|auto]</code>
</para>
<para>
The third signature takes a fifth argument. It is arbitrary shell
code to execute if the user actually passes the enable/disable
option. (If the user does not, the default is used. Duh.) No
argument checking at all is done in this signature. See
GLIBCXX_ENABLE_CXX_FLAGS for an example of handling, and an error
message.
</para>
</sect2>
</sect1>

View file

@ -0,0 +1,730 @@
<sect1 id="manual.localization.facet.codecvt" xreflabel="codecvt">
<?dbhtml filename="codecvt.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
codecvt
</keyword>
</keywordset>
</sect1info>
<title>codecvt</title>
<para>
The standard class codecvt attempts to address conversions between
different character encoding schemes. In particular, the standard
attempts to detail conversions between the implementation-defined wide
characters (hereafter referred to as wchar_t) and the standard type
char that is so beloved in classic <quote>C</quote> (which can now be
referred to as narrow characters.) This document attempts to describe
how the GNU libstdc++ implementation deals with the conversion between
wide and narrow characters, and also presents a framework for dealing
with the huge number of other encodings that iconv can convert,
including Unicode and UTF8. Design issues and requirements are
addressed, and examples of correct usage for both the required
specializations for wide and narrow characters and the
implementation-provided extended functionality are given.
</para>
<sect2 id="facet.codecvt.req" xreflabel="facet.codecvt.req">
<title>Requirements</title>
<para>
Around page 425 of the C++ Standard, this charming heading comes into view:
</para>
<blockquote>
<para>
22.2.1.5 - Template class codecvt
</para>
</blockquote>
<para>
The text around the codecvt definition gives some clues:
</para>
<blockquote>
<para>
<emphasis>
-1- The class codecvt&lt;internT,externT,stateT&gt; is for use when
converting from one codeset to another, such as from wide characters
to multibyte characters, between wide character encodings such as
Unicode and EUC.
</emphasis>
</para>
</blockquote>
<para>
Hmm. So, in some unspecified way, Unicode encodings and
translations between other character sets should be handled by this
class.
</para>
<blockquote>
<para>
<emphasis>
-2- The stateT argument selects the pair of codesets being mapped between.
</emphasis>
</para>
</blockquote>
<para>
Ah ha! Another clue...
</para>
<blockquote>
<para>
<emphasis>
-3- The instantiations required in the Table ??
(lib.locale.category), namely codecvt&lt;wchar_t,char,mbstate_t&gt; and
codecvt&lt;char,char,mbstate_t&gt;, convert the implementation-defined
native character set. codecvt&lt;char,char,mbstate_t&gt; implements a
degenerate conversion; it does not convert at
all. codecvt&lt;wchar_t,char,mbstate_t&gt; converts between the native
character sets for tiny and wide characters. Instantiations on
mbstate_t perform conversion between encodings known to the library
implementor. Other encodings can be converted by specializing on a
user-defined stateT type. The stateT object can contain any state that
is useful to communicate to or from the specialized do_convert member.
</emphasis>
</para>
</blockquote>
<para>
At this point, a couple points become clear:
</para>
<para>
One: The standard clearly implies that attempts to add non-required
(yet useful and widely used) conversions need to do so through the
third template parameter, stateT.</para>
<para>
Two: The required conversions, by specifying mbstate_t as the third
template parameter, imply an implementation strategy that is mostly
(or wholly) based on the underlying C library, and the functions
mcsrtombs and wcsrtombs in particular.</para>
</sect2>
<sect2 id="facet.codecvt.design" xreflabel="facet.codecvt.design">
<title>Design</title>
<sect3 id="codecvt.design.wchar_t_size" xreflabel="codecvt.design.wchar_t_size">
<title><type>wchar_t</type> Size</title>
<para>
The simple implementation detail of wchar_t's size seems to
repeatedly confound people. Many systems use a two byte,
unsigned integral type to represent wide characters, and use an
internal encoding of Unicode or UCS2. (See AIX, Microsoft NT,
Java, others.) Other systems, use a four byte, unsigned integral
type to represent wide characters, and use an internal encoding
of UCS4. (GNU/Linux systems using glibc, in particular.) The C
programming language (and thus C++) does not specify a specific
size for the type wchar_t.
</para>
<para>
Thus, portable C++ code cannot assume a byte size (or endianness) either.
</para>
</sect3>
<sect3 id="codecvt.design.unicode" xreflabel="codecvt.design.unicode">
<title>Support for Unicode</title>
<para>
Probably the most frequently asked question about code conversion
is: &quot;So dudes, what's the deal with Unicode strings?&quot;
The dude part is optional, but apparently the usefulness of
Unicode strings is pretty widely appreciated. Sadly, this specific
encoding (And other useful encodings like UTF8, UCS4, ISO 8859-10,
etc etc etc) are not mentioned in the C++ standard.
</para>
<para>
A couple of comments:
</para>
<para>
The thought that all one needs to convert between two arbitrary
codesets is two types and some kind of state argument is
unfortunate. In particular, encodings may be stateless. The naming
of the third parameter as stateT is unfortunate, as what is really
needed is some kind of generalized type that accounts for the
issues that abstract encodings will need. The minimum information
that is required includes:
</para>
<itemizedlist>
<listitem>
<para>
Identifiers for each of the codesets involved in the
conversion. For example, using the iconv family of functions
from the Single Unix Specification (what used to be called
X/Open) hosted on the GNU/Linux operating system allows
bi-directional mapping between far more than the following
tantalizing possibilities:
</para>
<para>
(An edited list taken from <code>`iconv --list`</code> on a
Red Hat 6.2/Intel system:
</para>
<blockquote>
<programlisting>
8859_1, 8859_9, 10646-1:1993, 10646-1:1993/UCS4, ARABIC, ARABIC7,
ASCII, EUC-CN, EUC-JP, EUC-KR, EUC-TW, GREEK-CCIcode, GREEK, GREEK7-OLD,
GREEK7, GREEK8, HEBREW, ISO-8859-1, ISO-8859-2, ISO-8859-3,
ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8,
ISO-8859-9, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14,
ISO-8859-15, ISO-10646, ISO-10646/UCS2, ISO-10646/UCS4,
ISO-10646/UTF-8, ISO-10646/UTF8, SHIFT-JIS, SHIFT_JIS, UCS-2, UCS-4,
UCS2, UCS4, UNICODE, UNICODEBIG, UNICODELIcodeLE, US-ASCII, US, UTF-8,
UTF-16, UTF8, UTF16).
</programlisting>
</blockquote>
<para>
For iconv-based implementations, string literals for each of the
encodings (ie. &quot;UCS-2&quot; and &quot;UTF-8&quot;) are necessary,
although for other,
non-iconv implementations a table of enumerated values or some other
mechanism may be required.
</para>
</listitem>
<listitem><para>
Maximum length of the identifying string literal.
</para></listitem>
<listitem><para>
Some encodings require explicit endian-ness. As such, some kind
of endian marker or other byte-order marker will be necessary. See
&quot;Footnotes for C/C++ developers&quot; in Haible for more information on
UCS-2/Unicode endian issues. (Summary: big endian seems most likely,
however implementations, most notably Microsoft, vary.)
</para></listitem>
<listitem><para>
Types representing the conversion state, for conversions involving
the machinery in the &quot;C&quot; library, or the conversion descriptor, for
conversions using iconv (such as the type iconv_t.) Note that the
conversion descriptor encodes more information than a simple encoding
state type.
</para></listitem>
<listitem><para>
Conversion descriptors for both directions of encoding. (ie, both
UCS-2 to UTF-8 and UTF-8 to UCS-2.)
</para></listitem>
<listitem><para>
Something to indicate if the conversion requested if valid.
</para></listitem>
<listitem><para>
Something to represent if the conversion descriptors are valid.
</para></listitem>
<listitem><para>
Some way to enforce strict type checking on the internal and
external types. As part of this, the size of the internal and
external types will need to be known.
</para></listitem>
</itemizedlist>
</sect3>
<sect3 id="codecvt.design.issues" xreflabel="codecvt.design.issues">
<title>Other Issues</title>
<para>
In addition, multi-threaded and multi-locale environments also impact
the design and requirements for code conversions. In particular, they
affect the required specialization codecvt&lt;wchar_t, char, mbstate_t&gt;
when implemented using standard &quot;C&quot; functions.
</para>
<para>
Three problems arise, one big, one of medium importance, and one small.
</para>
<para>
First, the small: mcsrtombs and wcsrtombs may not be multithread-safe
on all systems required by the GNU tools. For GNU/Linux and glibc,
this is not an issue.
</para>
<para>
Of medium concern, in the grand scope of things, is that the functions
used to implement this specialization work on null-terminated
strings. Buffers, especially file buffers, may not be null-terminated,
thus giving conversions that end prematurely or are otherwise
incorrect. Yikes!
</para>
<para>
The last, and fundamental problem, is the assumption of a global
locale for all the &quot;C&quot; functions referenced above. For something like
C++ iostreams (where codecvt is explicitly used) the notion of
multiple locales is fundamental. In practice, most users may not run
into this limitation. However, as a quality of implementation issue,
the GNU C++ library would like to offer a solution that allows
multiple locales and or simultaneous usage with computationally
correct results. In short, libstdc++ is trying to offer, as an
option, a high-quality implementation, damn the additional complexity!
</para>
<para>
For the required specialization codecvt&lt;wchar_t, char, mbstate_t&gt; ,
conversions are made between the internal character set (always UCS4
on GNU/Linux) and whatever the currently selected locale for the
LC_CTYPE category implements.
</para>
</sect3>
</sect2>
<sect2 id="facet.codecvt.impl" xreflabel="facet.codecvt.impl">
<title>Implementation</title>
<para>
The two required specializations are implemented as follows:
</para>
<para>
<code>
codecvt&lt;char, char, mbstate_t&gt;
</code>
</para>
<para>
This is a degenerate (ie, does nothing) specialization. Implementing
this was a piece of cake.
</para>
<para>
<code>
codecvt&lt;char, wchar_t, mbstate_t&gt;
</code>
</para>
<para>
This specialization, by specifying all the template parameters, pretty
much ties the hands of implementors. As such, the implementation is
straightforward, involving mcsrtombs for the conversions between char
to wchar_t and wcsrtombs for conversions between wchar_t and char.
</para>
<para>
Neither of these two required specializations deals with Unicode
characters. As such, libstdc++ implements a partial specialization
of the codecvt class with and iconv wrapper class, encoding_state as the
third template parameter.
</para>
<para>
This implementation should be standards conformant. First of all, the
standard explicitly points out that instantiations on the third
template parameter, stateT, are the proper way to implement
non-required conversions. Second of all, the standard says (in Chapter
17) that partial specializations of required classes are a-ok. Third
of all, the requirements for the stateT type elsewhere in the standard
(see 21.1.2 traits typedefs) only indicate that this type be copy
constructible.
</para>
<para>
As such, the type encoding_state is defined as a non-templatized, POD
type to be used as the third type of a codecvt instantiation. This
type is just a wrapper class for iconv, and provides an easy interface
to iconv functionality.
</para>
<para>
There are two constructors for encoding_state:
</para>
<para>
<code>
encoding_state() : __in_desc(0), __out_desc(0)
</code>
</para>
<para>
This default constructor sets the internal encoding to some default
(currently UCS4) and the external encoding to whatever is returned by
nl_langinfo(CODESET).
</para>
<para>
<code>
encoding_state(const char* __int, const char* __ext)
</code>
</para>
<para>
This constructor takes as parameters string literals that indicate the
desired internal and external encoding. There are no defaults for
either argument.
</para>
<para>
One of the issues with iconv is that the string literals identifying
conversions are not standardized. Because of this, the thought of
mandating and or enforcing some set of pre-determined valid
identifiers seems iffy: thus, a more practical (and non-migraine
inducing) strategy was implemented: end-users can specify any string
(subject to a pre-determined length qualifier, currently 32 bytes) for
encodings. It is up to the user to make sure that these strings are
valid on the target system.
</para>
<para>
<code>
void
_M_init()
</code>
</para>
<para>
Strangely enough, this member function attempts to open conversion
descriptors for a given encoding_state object. If the conversion
descriptors are not valid, the conversion descriptors returned will
not be valid and the resulting calls to the codecvt conversion
functions will return error.
</para>
<para>
<code>
bool
_M_good()
</code>
</para>
<para>
Provides a way to see if the given encoding_state object has been
properly initialized. If the string literals describing the desired
internal and external encoding are not valid, initialization will
fail, and this will return false. If the internal and external
encodings are valid, but iconv_open could not allocate conversion
descriptors, this will also return false. Otherwise, the object is
ready to convert and will return true.
</para>
<para>
<code>
encoding_state(const encoding_state&amp;)
</code>
</para>
<para>
As iconv allocates memory and sets up conversion descriptors, the copy
constructor can only copy the member data pertaining to the internal
and external code conversions, and not the conversion descriptors
themselves.
</para>
<para>
Definitions for all the required codecvt member functions are provided
for this specialization, and usage of codecvt&lt;internal character type,
external character type, encoding_state&gt; is consistent with other
codecvt usage.
</para>
</sect2>
<sect2 id="facet.codecvt.use" xreflabel="facet.codecvt.use">
<title>Use</title>
<para>A conversions involving string literal.</para>
<programlisting>
typedef codecvt_base::result result;
typedef unsigned short unicode_t;
typedef unicode_t int_type;
typedef char ext_type;
typedef encoding_state state_type;
typedef codecvt&lt;int_type, ext_type, state_type&gt; unicode_codecvt;
const ext_type* e_lit = "black pearl jasmine tea";
int size = strlen(e_lit);
int_type i_lit_base[24] =
{ 25088, 27648, 24832, 25344, 27392, 8192, 28672, 25856, 24832, 29184,
27648, 8192, 27136, 24832, 29440, 27904, 26880, 28160, 25856, 8192, 29696,
25856, 24832, 2560
};
const int_type* i_lit = i_lit_base;
const ext_type* efrom_next;
const int_type* ifrom_next;
ext_type* e_arr = new ext_type[size + 1];
ext_type* eto_next;
int_type* i_arr = new int_type[size + 1];
int_type* ito_next;
// construct a locale object with the specialized facet.
locale loc(locale::classic(), new unicode_codecvt);
// sanity check the constructed locale has the specialized facet.
VERIFY( has_facet&lt;unicode_codecvt&gt;(loc) );
const unicode_codecvt&amp; cvt = use_facet&lt;unicode_codecvt&gt;(loc);
// convert between const char* and unicode strings
unicode_codecvt::state_type state01("UNICODE", "ISO_8859-1");
initialize_state(state01);
result r1 = cvt.in(state01, e_lit, e_lit + size, efrom_next,
i_arr, i_arr + size, ito_next);
VERIFY( r1 == codecvt_base::ok );
VERIFY( !int_traits::compare(i_arr, i_lit, size) );
VERIFY( efrom_next == e_lit + size );
VERIFY( ito_next == i_arr + size );
</programlisting>
</sect2>
<sect2 id="facet.codecvt.future" xreflabel="facet.codecvt.future">
<title>Future</title>
<itemizedlist>
<listitem>
<para>
a. things that are sketchy, or remain unimplemented:
do_encoding, max_length and length member functions
are only weakly implemented. I have no idea how to do
this correctly, and in a generic manner. Nathan?
</para>
</listitem>
<listitem>
<para>
b. conversions involving std::string
</para>
<itemizedlist>
<listitem><para>
how should operators != and == work for string of
different/same encoding?
</para></listitem>
<listitem><para>
what is equal? A byte by byte comparison or an
encoding then byte comparison?
</para></listitem>
<listitem><para>
conversions between narrow, wide, and unicode strings
</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>
c. conversions involving std::filebuf and std::ostream
</para>
<itemizedlist>
<listitem><para>
how to initialize the state object in a
standards-conformant manner?
</para></listitem>
<listitem><para>
how to synchronize the &quot;C&quot; and &quot;C++&quot;
conversion information?
</para></listitem>
<listitem><para>
wchar_t/char internal buffers and conversions between
internal/external buffers?
</para></listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</sect2>
<bibliography id="facet.codecvt.biblio" xreflabel="facet.codecvt.biblio">
<title>Bibliography</title>
<biblioentry>
<title>
The GNU C Library
</title>
<author>
<surname>McGrath</surname>
<firstname>Roland</firstname>
</author>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2007</year>
<holder>FSF</holder>
</copyright>
<pagenums>Chapters 6 Character Set Handling and 7 Locales and Internationalization</pagenums>
</biblioentry>
<biblioentry>
<title>
Correspondence
</title>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2002</year>
<holder></holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 14882:1998 Programming languages - C++
</title>
<copyright>
<year>1998</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 9899:1999 Programming languages - C
</title>
<copyright>
<year>1999</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</title>
<copyright>
<year>1999</year>
<holder>
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.</holder>
</copyright>
<biblioid>
<ulink url="http://www.opennc.org/austin/docreg.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
The C++ Programming Language, Special Edition
</title>
<author>
<surname>Stroustrup</surname>
<firstname>Bjarne</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley, Inc.</holder>
</copyright>
<pagenums>Appendix D</pagenums>
<publisher>
<publishername>
Addison Wesley
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
Standard C++ IOStreams and Locales
</title>
<subtitle>
Advanced Programmer's Guide and Reference
</subtitle>
<author>
<surname>Langer</surname>
<firstname>Angelika</firstname>
</author>
<author>
<surname>Kreft</surname>
<firstname>Klaus</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley Longman, Inc.</holder>
</copyright>
<publisher>
<publishername>
Addison Wesley Longman
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
A brief description of Normative Addendum 1
</title>
<author>
<surname>Feather</surname>
<firstname>Clive</firstname>
</author>
<pagenums>Extended Character Sets</pagenums>
<biblioid>
<ulink url="http://www.lysator.liu.se/c/na1.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
The Unicode HOWTO
</title>
<author>
<surname>Haible</surname>
<firstname>Bruno</firstname>
</author>
<biblioid>
<ulink url="ftp://ftp.ilog.fr/pub/Users/haible/utf8/Unicode-HOWTO.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
UTF-8 and Unicode FAQ for Unix/Linux
</title>
<author>
<surname>Khun</surname>
<firstname>Markus</firstname>
</author>
<biblioid>
<ulink url="http://www.cl.cam.ac.uk/~mgk25/unicode.html">
</ulink>
</biblioid>
</biblioentry>
</bibliography>
</sect1>

View file

@ -0,0 +1,334 @@
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<chapter id="manual.ext.concurrency" xreflabel="Concurrency Extensions">
<?dbhtml filename="concurrency.html"?>
<chapterinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</chapterinfo>
<title>Concurrency</title>
<sect1 id="manual.ext.concurrency.design" xreflabel="Design">
<title>Design</title>
<sect2 id="manual.ext.concurrency.design.threads" xreflabel="Threads API">
<title>Interface to Locks and Mutexes</title>
<para>The file &lt;ext/concurrence.h&gt; contains all the higher-level
constructs for playing with threads. In contrast to the atomics layer,
the concurrence layer consists largely of types. All types are defined within <code>namespace __gnu_cxx</code>.
</para>
<para>
These types can be used in a portable manner, regardless of the
specific environment. They are carefully designed to provide optimum
efficiency and speed, abstracting out underlying thread calls and
accesses when compiling for single-threaded situations (even on hosts
that support multiple threads.)
</para>
<para>The enumerated type <code>_Lock_policy</code> details the set of
available locking
policies: <code>_S_single</code>, <code>_S_mutex</code>,
and <code>_S_atomic</code>.
</para>
<itemizedlist>
<listitem><para><code>_S_single</code></para>
<para>Indicates single-threaded code that does not need locking.
</para>
</listitem>
<listitem><para><code>_S_mutex</code></para>
<para>Indicates multi-threaded code using thread-layer abstractions.
</para>
</listitem>
<listitem><para><code>_S_atomic</code></para>
<para>Indicates multi-threaded code using atomic operations.
</para>
</listitem>
</itemizedlist>
<para>The compile-time constant <code>__default_lock_policy</code> is set
to one of the three values above, depending on characteristics of the
host environment and the current compilation flags.
</para>
<para>Two more datatypes make up the rest of the
interface: <code>__mutex</code>, and <code>__scoped_lock</code>.
</para>
<para>
</para>
<para>The scoped lock idiom is well-discussed within the C++
community. This version takes a <code>__mutex</code> reference, and
locks it during construction of <code>__scoped_locke</code> and
unlocks it during destruction. This is an efficient way of locking
critical sections, while retaining exception-safety.
</para>
</sect2>
<sect2 id="manual.ext.concurrency.design.atomics" xreflabel="Atomic API">
<title>Interface to Atomic Functions</title>
<para>
Two functions and one type form the base of atomic support.
</para>
<para>The type <code>_Atomic_word</code> is a signed integral type
supporting atomic operations.
</para>
<para>
The two functions functions are:
</para>
<programlisting>
_Atomic_word
__exchange_and_add_dispatch(volatile _Atomic_word*, int);
void
__atomic_add_dispatch(volatile _Atomic_word*, int);
</programlisting>
<para>Both of these functions are declared in the header file
&lt;ext/atomicity.h&gt;, and are in <code>namespace __gnu_cxx</code>.
</para>
<itemizedlist>
<listitem><para>
<code>
__exchange_and_add_dispatch
</code>
</para>
<para>Adds the second argument's value to the first argument. Returns the old value.
</para>
</listitem>
<listitem><para>
<code>
__atomic_add_dispatch
</code>
</para>
<para>Adds the second argument's value to the first argument. Has no return value.
</para>
</listitem>
</itemizedlist>
<para>
These functions forward to one of several specialized helper
functions, depending on the circumstances. For instance,
</para>
<para>
<code>
__exchange_and_add_dispatch
</code>
</para>
<para>
Calls through to either of:
</para>
<itemizedlist>
<listitem><para><code>__exchange_and_add</code>
</para>
<para>Multi-thread version. Inlined if compiler-generated builtin atomics
can be used, otherwise resolved at link time to a non-builtin code
sequence.
</para>
</listitem>
<listitem><para><code>__exchange_and_add_single</code>
</para>
<para>Single threaded version. Inlined.</para>
</listitem>
</itemizedlist>
<para>However, only <code>__exchange_and_add_dispatch</code>
and <code>__atomic_add_dispatch</code> should be used. These functions
can be used in a portable manner, regardless of the specific
environment. They are carefully designed to provide optimum efficiency
and speed, abstracting out atomic accesses when they are not required
(even on hosts that support compiler intrinsics for atomic
operations.)
</para>
<para>
In addition, there are two macros
</para>
<para>
<code>
_GLIBCXX_READ_MEM_BARRIER
</code>
</para>
<para>
<code>
_GLIBCXX_WRITE_MEM_BARRIER
</code>
</para>
<para>
Which expand to the appropriate write and read barrier required by the
host hardware and operating system.
</para>
</sect2>
</sect1>
<sect1 id="manual.ext.concurrency.impl" xreflabel="Implementation">
<title>Implementation</title>
<sect2 id="manual.ext.concurrency.impl.atomic_fallbacks" xreflabel="Atomic F">
<title>Using Builitin Atomic Functions</title>
<para>The functions for atomic operations described above are either
implemented via compiler intrinsics (if the underlying host is
capable) or by library fallbacks.</para>
<para>Compiler intrinsics (builtins) are always preferred. However, as
the compiler builtins for atomics are not universally implemented,
using them directly is problematic, and can result in undefined
function calls. (An example of an undefined symbol from the use
of <code>__sync_fetch_and_add</code> on an unsupported host is a
missing reference to <code>__sync_fetch_and_add_4</code>.)
</para>
<para>In addition, on some hosts the compiler intrinsics are enabled
conditionally, via the <code>-march</code> command line flag. This makes
usage vary depending on the target hardware and the flags used during
compile.
</para>
<para> If builtins are possible, <code>_GLIBCXX_ATOMIC_BUILTINS</code>
will be defined.
</para>
<para>For the following hosts, intrinsics are enabled by default.
</para>
<itemizedlist>
<listitem><para>alpha</para></listitem>
<listitem><para>ia64</para></listitem>
<listitem><para>powerpc</para></listitem>
<listitem><para>s390</para></listitem>
</itemizedlist>
<para>For others, some form of <code>-march</code> may work. On
non-ancient x86 hardware, <code>-march=native</code> usually does the
trick.</para>
<para> For hosts without compiler intrinsics, but with capable
hardware, hand-crafted assembly is selected. This is the case for the following hosts:
</para>
<itemizedlist>
<listitem><para>cris</para></listitem>
<listitem><para>hppa</para></listitem>
<listitem><para>i386</para></listitem>
<listitem><para>i486</para></listitem>
<listitem><para>m48k</para></listitem>
<listitem><para>mips</para></listitem>
<listitem><para>sparc</para></listitem>
</itemizedlist>
<para>And for the rest, a simulated atomic lock via pthreads.
</para>
<para> Detailed information about compiler intrinsics for atomic operations can be found in the GCC <ulink url="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html"> documentation</ulink>.
</para>
<para> More details on the library fallbacks from the porting <ulink url="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting.html#Thread%20safety">section</ulink>.
</para>
</sect2>
<sect2 id="manual.ext.concurrency.impl.thread" xreflabel="Pthread">
<title>Thread Abstraction</title>
<para>A thin layer above IEEE 1003.1 (ie pthreads) is used to abstract
the thread interface for GCC. This layer is called "gthread," and is
comprised of one header file that wraps the host's default thread layer with
a POSIX-like interface.
</para>
<para> The file &lt;gthr-default.h&gt; points to the deduced wrapper for
the current host. In libstdc++ implementation files,
&lt;bits/gthr.h&gt; is used to select the proper gthreads file.
</para>
<para>Within libstdc++ sources, all calls to underlying thread functionality
use this layer. More detail as to the specific interface can be found in the source <ulink url="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/gthr_8h-source.html">documentation</ulink>.
</para>
<para>By design, the gthread layer is interoperable with the types,
functions, and usage found in the usual &lt;pthread.h&gt; file,
including <code>pthread_t</code>, <code>pthread_once_t</code>, <code>pthread_create</code>,
etc.
</para>
</sect2>
</sect1>
<sect1 id="manual.ext.concurrency.use" xreflabel="Use">
<title>Use</title>
<para>Typical usage of the last two constructs is demonstrated as follows:
</para>
<programlisting>
#include &lt;ext/concurrence.h&gt;
namespace
{
__gnu_cxx::__mutex safe_base_mutex;
} // anonymous namespace
namespace other
{
void
foo()
{
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
for (int i = 0; i &lt; max; ++i)
{
_Safe_iterator_base* __old = __iter;
__iter = __iter-&lt;_M_next;
__old-&lt;_M_detach_single();
}
}
</programlisting>
<para>In this sample code, an anonymous namespace is used to keep
the <code>__mutex</code> private to the compilation unit,
and <code>__scoped_lock</code> is used to guard access to the critical
section within the for loop, locking the mutex on creation and freeing
the mutex as control moves out of this block.
</para>
<para>Several exception classes are used to keep track of
concurrence-related errors. These classes
are: <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__concurrence_wait_error</code>,
and <code>__concurrence_broadcast_error</code>.
</para>
</sect1>
</chapter>

View file

@ -0,0 +1,318 @@
<sect1 id="manual.intro.setup.configure" xreflabel="Configuring">
<?dbhtml filename="configure.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
configure
</keyword>
<keyword>
options
</keyword>
</keywordset>
</sect1info>
<title>Configure</title>
<para>
Here are some of the non-obvious options to libstdc++'s configure.
Keep in mind that
<!-- This SECnn should be the "Choosing Package Options" section. -->
<ulink url="http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_131.html#SEC131">they
all have opposite forms as well</ulink>
(enable/disable and with/without). The defaults are for <emphasis>current
development sources</emphasis>, which may be different than those for
released versions.
</para>
<para>The canonical way to find out the configure options that are
available for a given set of libstdc++ sources is to go to the
source directory and then type:<code> ./configure --help</code>
</para>
<variablelist>
<varlistentry><term><code>--enable-multilib</code>[default]</term>
<listitem><para>This is part of the generic multilib support for building cross
compilers. As such, targets like &quot;powerpc-elf&quot; will have
libstdc++ built many different ways: &quot;-msoft-float&quot;
and not, etc. A different libstdc++ will be built for each of
the different multilib versions. This option is on by default.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-sjlj-exceptions</code></term>
<listitem><para>Forces old, set-jump/long-jump exception handling model. If
at all possible, the new, frame unwinding exception handling routines
should be used instead, as they significantly reduce both
runtime memory usage and executable size. This option can
change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-version-specific-runtime-libs</code></term>
<listitem><para>Specify that run-time libraries should be installed in the
compiler-specific subdirectory (i.e.,
<code>${libdir}/gcc-lib/${target_alias}/${gcc_version}</code>)
instead of <code>${libdir}</code>. This option is useful if you
intend to use several versions of gcc in parallel. In addition,
libstdc++'s include files will be installed in
<code>${libdir}/gcc-lib/${target_alias}/${gcc_version}/include/g++</code>,
unless you also specify
<literal>--with-gxx-include-dir=<filename class="directory">dirname</filename></literal> during configuration.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--with-gxx-include-dir=&lt;include-files dir&gt;</code></term>
<listitem><para>Adds support for named libstdc++ include directory. For instance,
the following puts all the libstdc++ headers into a directory
called &quot;2.97-20001008&quot; instead of the usual
&quot;c++/(version)&quot;.
</para>
<programlisting>
--with-gxx-include-dir=/foo/H-x86-gcc-3-c-gxx-inc/include/2.97-20001008</programlisting> </listitem></varlistentry>
<varlistentry><term><code>--enable-cstdio</code></term>
<listitem><para>This is an abbreviated form of <code>'--enable-cstdio=stdio'</code>
(described next). This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-cstdio=OPTION</code></term>
<listitem><para>Select a target-specific I/O package. At the moment, the only
choice is to use 'stdio', a generic &quot;C&quot; abstraction.
The default is 'stdio'.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-clocale</code></term>
<listitem><para>This is an abbreviated form of <code>'--enable-clocale=generic'</code>
(described next). This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-clocale=OPTION</code></term>
<listitem><para>Select a target-specific underlying locale package. The
choices are 'ieee_1003.1-2001' to specify an X/Open, Standard Unix
(IEEE Std. 1003.1-2001) model based on langinfo/iconv/catgets,
'gnu' to specify a model based on functionality from the GNU C
library (langinfo/iconv/gettext) (from <ulink url="http://sources.redhat.com/glibc/">glibc</ulink>, the GNU C
library), or 'generic' to use a generic &quot;C&quot;
abstraction which consists of &quot;C&quot; locale info.
</para>
<para>As part of the configuration process, the "C" library is
probed both for sufficient vintage, and installed locale
data. If either of these elements are not present, the C++
locale model default to 'generic.' On glibc-based systems of
version 2.2.5 and above with installed locale files, 'gnu' is
automatically selected.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-libstdcxx-allocator</code></term>
<listitem><para>This is an abbreviated form of
<code>'--enable-libstdcxx-allocator=auto'</code> (described
next). This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-libstdcxx-allocator=OPTION </code></term>
<listitem><para>Select a target-specific underlying std::allocator. The
choices are 'new' to specify a wrapper for new, 'malloc' to
specify a wrapper for malloc, 'mt' for a fixed power of two allocator
(<ulink url="ext/mt_allocator.html">documented</ulink> under extensions),
'pool' for the SGI pooled allocator or 'bitmap' for a bitmap allocator.
This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-cheaders=OPTION</code></term>
<listitem><para>This allows the user to define the approach taken for C header
compatibility with C++. Options are c, c_std, and c_global.
These correspond to the source directory's include/c,
include/c_std, and include/c_global, and may also include
include/c_compatibility. The default is c_global.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-threads</code></term>
<listitem><para>This is an abbreviated form of <code>'--enable-threads=yes'</code>
(described next). This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-threads=OPTION</code></term>
<listitem><para>Select a threading library. A full description is given in the
general <ulink url="http://gcc.gnu.org/install/configure.html">compiler
configuration instructions</ulink>.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-libstdcxx-debug</code></term>
<listitem><para>Build separate debug libraries in addition to what is normally built.
By default, the debug libraries are compiled with
<code> CXXFLAGS='-g3 -O0'</code>
, are installed in <code>${libdir}/debug</code>, and have the
same names and versioning information as the non-debug
libraries. This option is off by default.
</para>
<para>Note this make command, executed in
the build directory, will do much the same thing, without the
configuration difference and without building everything twice:
<code>make CXXFLAGS='-g3 -O0' all</code>
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-libstdcxx-debug-flags=FLAGS</code></term>
<listitem><para>This option is only valid when <code> --enable-debug </code>
is also specified, and applies to the debug builds only. With
this option, you can pass a specific string of flags to the
compiler to use when building the debug versions of libstdc++.
FLAGS is a quoted string of options, like
</para>
<programlisting>
--enable-libstdcxx-debug-flags='-g3 -O1 -gdwarf-2'</programlisting>
</listitem></varlistentry>
<varlistentry><term><code>--enable-cxx-flags=FLAGS</code></term>
<listitem><para>With this option, you can pass a string of -f (functionality)
flags to the compiler to use when building libstdc++. This
option can change the library ABI. FLAGS is a quoted string of
options, like
</para>
<programlisting>
--enable-cxx-flags='-fvtable-gc -fomit-frame-pointer -ansi'</programlisting>
<para>
Note that the flags don't necessarily have to all be -f flags,
as shown, but usually those are the ones that will make sense
for experimentation and configure-time overriding.
</para>
<para>The advantage of --enable-cxx-flags over setting CXXFLAGS in
the 'make' environment is that, if files are automatically
rebuilt, the same flags will be used when compiling those files
as well, so that everything matches.
</para>
<para>Fun flags to try might include combinations of
</para>
<programlisting>
-fstrict-aliasing
-fno-exceptions
-ffunction-sections
-fvtable-gc</programlisting>
<para>and opposite forms (-fno-) of the same. Tell us (the libstdc++
mailing list) if you discover more!
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-c99</code></term>
<listitem><para>The &quot;long long&quot; type was introduced in C99, along
with many other functions for wide characters, and math
classification macros, etc. If enabled, all C99 functions not
specified by the C++ standard will be put into <code>namespace
__gnu_cxx</code>, and then all these names will
be injected into namespace std, so that C99 functions can be
used &quot;as if&quot; they were in the C++ standard (as they
will eventually be in some future revision of the standard,
without a doubt). By default, C99 support is on, assuming the
configure probes find all the necessary functions and bits
necessary. This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-wchar_t</code>[default]</term>
<listitem><para>Template specializations for the &quot;wchar_t&quot; type are
required for wide character conversion support. Disabling
wide character specializations may be expedient for initial
porting efforts, but builds only a subset of what is required by
ISO, and is not recommended. By default, this option is on.
This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-long-long </code></term>
<listitem><para>The &quot;long long&quot; type was introduced in C99. It is
provided as a GNU extension to C++98 in g++. This flag builds
support for &quot;long long&quot; into the library (specialized
templates and the like for iostreams). This option is on by default:
if enabled, users will have to either use the new-style &quot;C&quot;
headers by default (i.e., &lt;cmath&gt; not &lt;math.h&gt;)
or add appropriate compile-time flags to all compile lines to
allow &quot;C&quot; visibility of this feature (on GNU/Linux,
the flag is -D_ISOC99_SOURCE, which is added automatically via
CPLUSPLUS_CPP_SPEC's addition of _GNU_SOURCE).
This option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-fully-dynamic-string</code></term>
<listitem><para>This option enables a special version of basic_string avoiding
the optimization that allocates empty objects in static memory.
Mostly useful together with shared memory allocators, see PR
libstdc++/16612 for details.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-concept-checks</code></term>
<listitem><para>This turns on additional compile-time checks for instantiated
library templates, in the form of specialized templates,
<ulink url="19_diagnostics/howto.html#3">described here</ulink>. They
can help users discover when they break the rules of the STL, before
their programs run.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-symvers[=style]</code></term>
<listitem><para>In 3.1 and later, tries to turn on symbol versioning in the
shared library (if a shared library has been
requested). Values for 'style' that are currently supported
are 'gnu', 'gnu-versioned-namespace', 'darwin', and
'darwin-export'. Both gnu- options require that a recent
version of the GNU linker be in use. Both darwin options are
equivalent. With no style given, the configure script will try
to guess correct defaults for the host system, probe to see if
additional requirements are necessary and present for
activation, and if so, will turn symbol versioning on. This
option can change the library ABI.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-visibility</code></term>
<listitem><para> In 4.2 and later, enables or disables visibility attributes.
If enabled (as by default), and the compiler seems capable of
passing the simple sanity checks thrown at it, adjusts items
in namespace std, namespace std::tr1, and namespace __gnu_cxx
so that -fvisibility options work.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--enable-libstdcxx-pch</code></term>
<listitem><para>In 3.4 and later, tries to turn on the generation of
stdc++.h.gch, a pre-compiled file including all the standard
C++ includes. If enabled (as by default), and the compiler
seems capable of passing the simple sanity checks thrown at
it, try to build stdc++.h.gch as part of the make process.
In addition, this generated file is used later on (by appending <code>
--include bits/stdc++.h </code> to CXXFLAGS) when running the
testsuite.
</para>
</listitem></varlistentry>
<varlistentry><term><code>--disable-hosted-libstdcxx</code></term>
<listitem>
<para>
By default, a complete <emphasis>hosted</emphasis> C++ library is
built. The C++ Standard also describes a
<emphasis>freestanding</emphasis> environment, in which only a
minimal set of headers are provided. This option builds such an
environment.
</para>
</listitem></varlistentry>
</variablelist>
</sect1>

View file

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

View file

@ -0,0 +1,259 @@
<sect1 id="manual.localization.facet.ctype" xreflabel="ctype">
<?dbhtml filename="ctype.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
ctype
</keyword>
</keywordset>
</sect1info>
<title>ctype</title>
<sect2 id="facet.ctype.impl" xreflabel="facet.ctype.impl">
<title>Implementation</title>
<sect3>
<title>Specializations</title>
<para>
For the required specialization codecvt&lt;wchar_t, char, mbstate_t&gt; ,
conversions are made between the internal character set (always UCS4
on GNU/Linux) and whatever the currently selected locale for the
LC_CTYPE category implements.
</para>
<para>
The two required specializations are implemented as follows:
</para>
<para>
<code>
ctype&lt;char&gt;
</code>
</para>
<para>
This is simple specialization. Implementing this was a piece of cake.
</para>
<para>
<code>
ctype&lt;wchar_t&gt;
</code>
</para>
<para>
This specialization, by specifying all the template parameters, pretty
much ties the hands of implementors. As such, the implementation is
straightforward, involving mcsrtombs for the conversions between char
to wchar_t and wcsrtombs for conversions between wchar_t and char.
</para>
<para>
Neither of these two required specializations deals with Unicode
characters.
</para>
</sect3>
</sect2>
<sect2 id="facet.ctype.future" xreflabel="facet.ctype.future">
<title>Future</title>
<itemizedlist>
<listitem>
<para>
How to deal with the global locale issue?
</para></listitem>
<listitem>
<para>
How to deal with different types than char, wchar_t? </para></listitem>
<listitem><para>
Overlap between codecvt/ctype: narrow/widen
</para></listitem>
<listitem>
<para>
Mask typedef in codecvt_base, argument types in codecvt. what
is know about this type?
</para></listitem>
<listitem>
<para>
Why mask* argument in codecvt?
</para></listitem>
<listitem>
<para>
Can this be made (more) generic? is there a simple way to
straighten out the configure-time mess that is a by-product of
this class?
</para></listitem>
<listitem>
<para>
Get the ctype&lt;wchar_t&gt;::mask stuff under control. Need to
make some kind of static table, and not do lookup evertime
somebody hits the do_is... functions. Too bad we can't just
redefine mask for ctype&lt;wchar_t&gt;
</para></listitem>
<listitem>
<para>
Rename abstract base class. See if just smash-overriding is a
better approach. Clarify, add sanity to naming.
</para>
</listitem>
</itemizedlist>
</sect2>
<bibliography id="facet.ctype.biblio" xreflabel="facet.ctype.biblio">
<title>Bibliography</title>
<biblioentry>
<title>
The GNU C Library
</title>
<author>
<surname>McGrath</surname>
<firstname>Roland</firstname>
</author>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2007</year>
<holder>FSF</holder>
</copyright>
<pagenums>Chapters 6 Character Set Handling and 7 Locales and Internationalization</pagenums>
</biblioentry>
<biblioentry>
<title>
Correspondence
</title>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2002</year>
<holder></holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 14882:1998 Programming languages - C++
</title>
<copyright>
<year>1998</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 9899:1999 Programming languages - C
</title>
<copyright>
<year>1999</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</title>
<copyright>
<year>1999</year>
<holder>
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.</holder>
</copyright>
<biblioid>
<ulink url="http://www.opennc.org/austin/docreg.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
The C++ Programming Language, Special Edition
</title>
<author>
<surname>Stroustrup</surname>
<firstname>Bjarne</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley, Inc.</holder>
</copyright>
<pagenums>Appendix D</pagenums>
<publisher>
<publishername>
Addison Wesley
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
Standard C++ IOStreams and Locales
</title>
<subtitle>
Advanced Programmer's Guide and Reference
</subtitle>
<author>
<surname>Langer</surname>
<firstname>Angelika</firstname>
</author>
<author>
<surname>Kreft</surname>
<firstname>Klaus</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley Longman, Inc.</holder>
</copyright>
<publisher>
<publishername>
Addison Wesley Longman
</publishername>
</publisher>
</biblioentry>
</bibliography>
</sect1>

View file

@ -0,0 +1,245 @@
<sect1 id="manual.intro.using.debug" xreflabel="Debugging Support">
<?dbhtml filename="debug.html"?>
<sect1info>
<keywordset>
<keyword>
C++
</keyword>
<keyword>
debug
</keyword>
</keywordset>
</sect1info>
<title>Debugging Support</title>
<para>
There are numerous things that can be done to improve the ease with
which C++ binaries are debugged when using the GNU tool chain. Here
are some of them.
</para>
<sect2 id="debug.compiler" xreflabel="debug.compiler">
<title>Using <command>g++</command></title>
<para>
Compiler flags determine how debug information is transmitted
between compilation and debug or analysis tools.
</para>
<para>
The default optimizations and debug flags for a libstdc++ build
are <code>-g -O2</code>. However, both debug and optimization
flags can be varied to change debugging characteristics. For
instance, turning off all optimization via the <code>-g -O0</code>
flag will disable inlining, so that stepping through all
functions, including inlined constructors and destructors, is
possible. In addition,
<code>-fno-eliminate-unused-debug-types</code> can be used when
additional debug information, such as nested class info, is
desired.
</para>
<para>
Or, the debug format that the compiler and debugger use to
communicate information about source constructs can be changed via
<code> -gdwarf-2 </code> or <code> -gstabs </code> flags: some
debugging formats permit more expressive type and scope information
to be shown in gdb. The default debug information for a particular
platform can be identified via the value set by the
PREFERRED_DEBUGGING_TYPE macro in the gcc sources.
</para>
<para>
Many other options are available: please see <ulink
url="http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging%20Options">"Options
for Debugging Your Program"</ulink> in Using the GNU Compiler
Collection (GCC) for a complete list.
</para>
</sect2>
<sect2 id="debug.req" xreflabel="debug.req">
<title>Debug Versions of Library Binary Files</title>
<para>
If you would like debug symbols in libstdc++, there are two ways to
build libstdc++ with debug flags. The first is to run make from the
toplevel in a freshly-configured tree with
</para>
<programlisting>
--enable-libstdcxx-debug
</programlisting>
<para>and perhaps</para>
<programlisting>
--enable-libstdcxx-debug-flags='...'
</programlisting>
<para>
to create a separate debug build. Both the normal build and the
debug build will persist, without having to specify
<code>CXXFLAGS</code>, and the debug library will be installed in a
separate directory tree, in <code>(prefix)/lib/debug</code>. For
more information, look at the <ulink
url="configopts.html">configuration options</ulink> document.
</para>
<para>
A second approach is to use the configuration flags
</para>
<programlisting>
make CXXFLAGS='-g3 -O0' all
</programlisting>
<para>
This quick and dirty approach is often sufficient for quick
debugging tasks, when you cannot or don't want to recompile your
application to use the <ulink url="#safe">debug mode</ulink>.</para>
</sect2>
<sect2 id="debug.memory" xreflabel="debug.memory">
<title>Memory Leak Hunting</title>
<para>
There are various third party memory tracing and debug utilities
that can be used to provide detailed memory allocation information
about C++ code. An exhaustive list of tools is not going to be
attempted, but includes <code>mtrace</code>, <code>valgrind</code>,
<code>mudflap</code>, and the non-free commercial product
<code>purify</code>. In addition, <code>libcwd</code> has a
replacement for the global new and delete operators that can track
memory allocation and deallocation and provide useful memory
statistics.
</para>
<para>
Regardless of the memory debugging tool being used, there is one
thing of great importance to keep in mind when debugging C++ code
that uses <code>new</code> and <code>delete</code>: there are
different kinds of allocation schemes that can be used by <code>
std::allocator </code>. For implementation details, see the <ulink
url="ext/mt_allocator.html">mt allocator</ulink> documentation and
look specifically for <code>GLIBCXX_FORCE_NEW</code>.
</para>
<para>
In a nutshell, the default allocator used by <code>
std::allocator</code> is a high-performance pool allocator, and can
give the mistaken impression that in a suspect executable, memory is
being leaked, when in reality the memory "leak" is a pool being used
by the library's allocator and is reclaimed after program
termination.
</para>
<para>
For valgrind, there are some specific items to keep in mind. First
of all, use a version of valgrind that will work with current GNU
C++ tools: the first that can do this is valgrind 1.0.4, but later
versions should work at least as well. Second of all, use a
completely unoptimized build to avoid confusing valgrind. Third, use
GLIBCXX_FORCE_NEW to keep extraneous pool allocation noise from
cluttering debug information.
</para>
<para>
Fourth, it may be necessary to force deallocation in other libraries
as well, namely the "C" library. On linux, this can be accomplished
with the appropriate use of the <code>__cxa_atexit</code> or
<code>atexit</code> functions.
</para>
<programlisting>
#include &lt;cstdlib&gt;
extern "C" void __libc_freeres(void);
void do_something() { }
int main()
{
atexit(__libc_freeres);
do_something();
return 0;
}
</programlisting>
<para>or, using <code>__cxa_atexit</code>:</para>
<programlisting>
extern "C" void __libc_freeres(void);
extern "C" int __cxa_atexit(void (*func) (void *), void *arg, void *d);
void do_something() { }
int main()
{
extern void* __dso_handle __attribute__ ((__weak__));
__cxa_atexit((void (*) (void *)) __libc_freeres, NULL,
&amp;__dso_handle ? __dso_handle : NULL);
do_test();
return 0;
}
</programlisting>
<para>
Suggested valgrind flags, given the suggestions above about setting
up the runtime environment, library, and test file, might be:
</para>
<programlisting>
valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out
</programlisting>
</sect2>
<sect2 id="debug.gdb" xreflabel="debug.gdb">
<title>Using <command>gdb</command></title>
<para>
</para>
<para>
Many options are available for gdb itself: please see <ulink
url="http://sources.redhat.com/gdb/current/onlinedocs/gdb_13.html#SEC109">
"GDB features for C++" </ulink> in the gdb documentation. Also
recommended: the other parts of this manual.
</para>
<para>
These settings can either be switched on in at the gdb command line,
or put into a .gdbint file to establish default debugging
characteristics, like so:
</para>
<programlisting>
set print pretty on
set print object on
set print static-members on
set print vtbl on
set print demangle on
set demangle-style gnu-v3
</programlisting>
</sect2>
<sect2 id="debug.exceptions" xreflabel="debug.exceptions">
<title>Tracking uncaught exceptions</title>
<para>
The <link linkend="support.termination.verbose">verbose
termination handler</link> gives information about uncaught
exceptions which are killing the program. It is described in the
linked-to page.
</para>
</sect2>
<sect2 id="debug.debug_mode" xreflabel="debug.debug_mode">
<title>Debug Mode</title>
<para> The <link linkend="manual.ext.debug_mode">Debug Mode</link>
has compile and run-time checks for many containers.
</para>
</sect2>
<sect2 id="debug.compile_time_checks" xreflabel="debug.compile_time_checks">
<title>Compile Time Checking</title>
<para> The <link linkend="manual.ext.compile_checks">Compile-Time
Checks</link> Extension has compile-time checks for many algorithms.
</para>
</sect2>
</sect1>

View file

@ -0,0 +1,888 @@
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<chapter id="manual.ext.debug_mode" xreflabel="Debug Mode">
<?dbhtml filename="debug_mode.html"?>
<chapterinfo>
<keywordset>
<keyword>
C++
</keyword>
<keyword>
library
</keyword>
<keyword>
debug
</keyword>
</keywordset>
</chapterinfo>
<title>Debug Mode</title>
<sect1 id="manual.ext.debug_mode.intro" xreflabel="Intro">
<title>Intro</title>
<para>
By default, libstdc++ is built with efficiency in mind, and
therefore performs little or no error checking that is not
required by the C++ standard. This means that programs that
incorrectly use the C++ standard library will exhibit behavior
that is not portable and may not even be predictable, because they
tread into implementation-specific or undefined behavior. To
detect some of these errors before they can become problematic,
libstdc++ offers a debug mode that provides additional checking of
library facilities, and will report errors in the use of libstdc++
as soon as they can be detected by emitting a description of the
problem to standard error and aborting the program. This debug
mode is available with GCC 3.4.0 and later versions.
</para>
<para>
The libstdc++ debug mode performs checking for many areas of the
C++ standard, but the focus is on checking interactions among
standard iterators, containers, and algorithms, including:
</para>
<itemizedlist>
<listitem><para><emphasis>Safe iterators</emphasis>: Iterators keep track of the
container whose elements they reference, so errors such as
incrementing a past-the-end iterator or dereferencing an iterator
that points to a container that has been destructed are diagnosed
immediately.</para></listitem>
<listitem><para><emphasis>Algorithm preconditions</emphasis>: Algorithms attempt to
validate their input parameters to detect errors as early as
possible. For instance, the <code>set_intersection</code>
algorithm requires that its iterator
parameters <code>first1</code> and <code>last1</code> form a valid
iterator range, and that the sequence
[<code>first1</code>, <code>last1</code>) is sorted according to
the same predicate that was passed
to <code>set_intersection</code>; the libstdc++ debug mode will
detect an error if the sequence is not sorted or was sorted by a
different predicate.</para></listitem>
</itemizedlist>
</sect1>
<sect1 id="manual.ext.debug_mode.semantics" xreflabel="Semantics">
<title>Semantics</title>
<para>
</para>
<para>A program that uses the C++ standard library correctly
will maintain the same semantics under debug mode as it had with
the normal (release) library. All functional and exception-handling
guarantees made by the normal library also hold for the debug mode
library, with one exception: performance guarantees made by the
normal library may not hold in the debug mode library. For
instance, erasing an element in a <code>std::list</code> is a
constant-time operation in normal library, but in debug mode it is
linear in the number of iterators that reference that particular
list. So while your (correct) program won't change its results, it
is likely to execute more slowly.</para>
<para>libstdc++ includes many extensions to the C++ standard library. In
some cases the extensions are obvious, such as the hashed
associative containers, whereas other extensions give predictable
results to behavior that would otherwise be undefined, such as
throwing an exception when a <code>std::basic_string</code> is
constructed from a NULL character pointer. This latter category also
includes implementation-defined and unspecified semantics, such as
the growth rate of a vector. Use of these extensions is not
considered incorrect, so code that relies on them will not be
rejected by debug mode. However, use of these extensions may affect
the portability of code to other implementations of the C++ standard
library, and is therefore somewhat hazardous. For this reason, the
libstdc++ debug mode offers a "pedantic" mode (similar to
GCC's <code>-pedantic</code> compiler flag) that attempts to emulate
the semantics guaranteed by the C++ standard. For
instance, constructing a <code>std::basic_string</code> with a NULL
character pointer would result in an exception under normal mode or
non-pedantic debug mode (this is a libstdc++ extension), whereas
under pedantic debug mode libstdc++ would signal an error. To enable
the pedantic debug mode, compile your program with
both <code>-D_GLIBCXX_DEBUG</code>
and <code>-D_GLIBCXX_DEBUG_PEDANTIC</code> .
(N.B. In GCC 3.4.x and 4.0.0, due to a bug,
<code>-D_GLIBXX_DEBUG_PEDANTIC</code> was also needed. The problem has
been fixed in GCC 4.0.1 and later versions.) </para>
<para>The following library components provide extra debugging
capabilities in debug mode:</para>
<itemizedlist>
<listitem><para><code>std::basic_string</code> (no safe iterators and see note below)</para></listitem>
<listitem><para><code>std::bitset</code></para></listitem>
<listitem><para><code>std::deque</code></para></listitem>
<listitem><para><code>std::list</code></para></listitem>
<listitem><para><code>std::map</code></para></listitem>
<listitem><para><code>std::multimap</code></para></listitem>
<listitem><para><code>std::multiset</code></para></listitem>
<listitem><para><code>std::set</code></para></listitem>
<listitem><para><code>std::vector</code></para></listitem>
<listitem><para><code>std::unordered_map</code></para></listitem>
<listitem><para><code>std::unordered_multimap</code></para></listitem>
<listitem><para><code>std::unordered_set</code></para></listitem>
<listitem><para><code>std::unordered_multiset</code></para></listitem>
</itemizedlist>
<para>N.B. although there are precondition checks for some string operations,
e.g. <code>operator[]</code>,
they will not always be run when using the <code>char</code> and
<code>wchar_t</code> specialisations (<code>std::string</code> and
<code>std::wstring</code>). This is because libstdc++ uses GCC's
<code>extern template</code> extension to provide explicit instantiations
of <code>std::string</code> and <code>std::wstring</code>, and those
explicit instantiations don't include the debug-mode checks. If the
containing functions are inlined then the checks will run, so compiling
with <code>-O1</code> might be enough to enable them. Alternatively
<code>-D_GLIBCXX_EXTERN_TEMPLATE=0</code> will suppress the declarations
of the explicit instantiations and cause the functions to be instantiated
with the debug-mode checks included, but this is unsupported and not
guaranteed to work. For full debug-mode support you can use the
<code>__gnu_debug::basic_string</code> debugging container directly,
which always works correctly.
</para>
</sect1>
<sect1 id="manual.ext.debug_mode.using" xreflabel="Using">
<title>Using</title>
<para>
</para>
<sect2 id="debug_mode.using.mode" xreflabel="Using Mode">
<title>Using the Debug Mode</title>
<para>To use the libstdc++ debug mode, compile your application with the
compiler flag <code>-D_GLIBCXX_DEBUG</code>. Note that this flag
changes the sizes and behavior of standard class templates such
as <code>std::vector</code>, and therefore you can only link code
compiled with debug mode and code compiled without debug mode if no
instantiation of a container is passed between the two translation
units.</para>
<para>By default, error messages are formatted to fit on lines of about
78 characters. The environment variable
<code>GLIBCXX_DEBUG_MESSAGE_LENGTH</code> can be used to request a
different length.</para>
</sect2>
<sect2 id="debug_mode.using.specific" xreflabel="Using Specific">
<title>Using a Specific Debug Container</title>
<para>When it is not feasible to recompile your entire application, or
only specific containers need checking, debugging containers are
available as GNU extensions. These debugging containers are
functionally equivalent to the standard drop-in containers used in
debug mode, but they are available in a separate namespace as GNU
extensions and may be used in programs compiled with either release
mode or with debug mode. The
following table provides the names and headers of the debugging
containers:
</para>
<table frame='all'>
<title>Debugging Containers</title>
<tgroup cols='6' align='left' colsep='1' rowsep='1'>
<colspec colname='c1'></colspec>
<colspec colname='c2'></colspec>
<colspec colname='c3'></colspec>
<colspec colname='c4'></colspec>
<thead>
<row>
<entry>Container</entry>
<entry>Header</entry>
<entry>Debug container</entry>
<entry>Debug header</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>std::bitset</classname></entry>
<entry><filename class="headerfile">bitset</filename></entry>
<entry><classname>__gnu_debug::bitset</classname></entry>
<entry><filename class="headerfile">bitset</filename></entry>
</row>
<row>
<entry><classname>std::deque</classname></entry>
<entry><filename class="headerfile">deque</filename></entry>
<entry><classname>__gnu_debug::deque</classname></entry>
<entry><filename class="headerfile">deque</filename></entry>
</row>
<row>
<entry><classname>std::list</classname></entry>
<entry><filename class="headerfile">list</filename></entry>
<entry><classname>__gnu_debug::list</classname></entry>
<entry><filename class="headerfile">list</filename></entry>
</row>
<row>
<entry><classname>std::map</classname></entry>
<entry><filename class="headerfile">map</filename></entry>
<entry><classname>__gnu_debug::map</classname></entry>
<entry><filename class="headerfile">map</filename></entry>
</row>
<row>
<entry><classname>std::multimap</classname></entry>
<entry><filename class="headerfile">map</filename></entry>
<entry><classname>__gnu_debug::multimap</classname></entry>
<entry><filename class="headerfile">map</filename></entry>
</row>
<row>
<entry><classname>std::multiset</classname></entry>
<entry><filename class="headerfile">set</filename></entry>
<entry><classname>__gnu_debug::multiset</classname></entry>
<entry><filename class="headerfile">set</filename></entry>
</row>
<row>
<entry><classname>std::set</classname></entry>
<entry><filename class="headerfile">set</filename></entry>
<entry><classname>__gnu_debug::set</classname></entry>
<entry><filename class="headerfile">set</filename></entry>
</row>
<row>
<entry><classname>std::string</classname></entry>
<entry><filename class="headerfile">string</filename></entry>
<entry><classname>__gnu_debug::string</classname></entry>
<entry><filename class="headerfile">string</filename></entry>
</row>
<row>
<entry><classname>std::wstring</classname></entry>
<entry><filename class="headerfile">string</filename></entry>
<entry><classname>__gnu_debug::wstring</classname></entry>
<entry><filename class="headerfile">string</filename></entry>
</row>
<row>
<entry><classname>std::basic_string</classname></entry>
<entry><filename class="headerfile">string</filename></entry>
<entry><classname>__gnu_debug::basic_string</classname></entry>
<entry><filename class="headerfile">string</filename></entry>
</row>
<row>
<entry><classname>std::vector</classname></entry>
<entry><filename class="headerfile">vector</filename></entry>
<entry><classname>__gnu_debug::vector</classname></entry>
<entry><filename class="headerfile">vector</filename></entry>
</row>
</tbody>
</tgroup>
</table>
<para>In addition, when compiling in C++0x mode, these additional
containers have additional debug capability.
</para>
<table frame='all'>
<title>Debugging Containers C++0x</title>
<tgroup cols='6' align='left' colsep='1' rowsep='1'>
<colspec colname='c1'></colspec>
<colspec colname='c2'></colspec>
<colspec colname='c3'></colspec>
<colspec colname='c4'></colspec>
<thead>
<row>
<entry>Container</entry>
<entry>Header</entry>
<entry>Debug container</entry>
<entry>Debug header</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>std::unordered_map</classname></entry>
<entry><filename class="headerfile">unordered_map</filename></entry>
<entry><classname>__gnu_debug::unordered_map</classname></entry>
<entry><filename class="headerfile">unordered_map</filename></entry>
</row>
<row>
<entry><classname>std::unordered_multimap</classname></entry>
<entry><filename class="headerfile">unordered_map</filename></entry>
<entry><classname>__gnu_debug::unordered_multimap</classname></entry>
<entry><filename class="headerfile">unordered_map</filename></entry>
</row>
<row>
<entry><classname>std::unordered_set</classname></entry>
<entry><filename class="headerfile">unordered_set</filename></entry>
<entry><classname>__gnu_debug::unordered_set</classname></entry>
<entry><filename class="headerfile">unordered_set</filename></entry>
</row>
<row>
<entry><classname>std::unordered_multiset</classname></entry>
<entry><filename class="headerfile">unordered_set</filename></entry>
<entry><classname>__gnu_debug::unordered_multiset</classname></entry>
<entry><filename class="headerfile">unordered_set</filename></entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
</sect1>
<sect1 id="manual.ext.debug_mode.design" xreflabel="Design">
<title>Design</title>
<para>
</para>
<sect2 id="manual.ext.debug_mode.design.goals" xreflabel="Goals">
<title>Goals</title>
<para>
</para>
<para> The libstdc++ debug mode replaces unsafe (but efficient) standard
containers and iterators with semantically equivalent safe standard
containers and iterators to aid in debugging user programs. The
following goals directed the design of the libstdc++ debug mode:</para>
<itemizedlist>
<listitem><para><emphasis>Correctness</emphasis>: the libstdc++ debug mode must not change
the semantics of the standard library for all cases specified in
the ANSI/ISO C++ standard. The essence of this constraint is that
any valid C++ program should behave in the same manner regardless
of whether it is compiled with debug mode or release mode. In
particular, entities that are defined in namespace std in release
mode should remain defined in namespace std in debug mode, so that
legal specializations of namespace std entities will remain
valid. A program that is not valid C++ (e.g., invokes undefined
behavior) is not required to behave similarly, although the debug
mode will abort with a diagnostic when it detects undefined
behavior.</para></listitem>
<listitem><para><emphasis>Performance</emphasis>: the additional of the libstdc++ debug mode
must not affect the performance of the library when it is compiled
in release mode. Performance of the libstdc++ debug mode is
secondary (and, in fact, will be worse than the release
mode).</para></listitem>
<listitem><para><emphasis>Usability</emphasis>: the libstdc++ debug mode should be easy to
use. It should be easily incorporated into the user's development
environment (e.g., by requiring only a single new compiler switch)
and should produce reasonable diagnostics when it detects a
problem with the user program. Usability also involves detection
of errors when using the debug mode incorrectly, e.g., by linking
a release-compiled object against a debug-compiled object if in
fact the resulting program will not run correctly.</para></listitem>
<listitem><para><emphasis>Minimize recompilation</emphasis>: While it is expected that
users recompile at least part of their program to use debug
mode, the amount of recompilation affects the
detect-compile-debug turnaround time. This indirectly affects the
usefulness of the debug mode, because debugging some applications
may require rebuilding a large amount of code, which may not be
feasible when the suspect code may be very localized. There are
several levels of conformance to this requirement, each with its
own usability and implementation characteristics. In general, the
higher-numbered conformance levels are more usable (i.e., require
less recompilation) but are more complicated to implement than
the lower-numbered conformance levels.
<orderedlist>
<listitem><para><emphasis>Full recompilation</emphasis>: The user must recompile his or
her entire application and all C++ libraries it depends on,
including the C++ standard library that ships with the
compiler. This must be done even if only a small part of the
program can use debugging features.</para></listitem>
<listitem><para><emphasis>Full user recompilation</emphasis>: The user must recompile
his or her entire application and all C++ libraries it depends
on, but not the C++ standard library itself. This must be done
even if only a small part of the program can use debugging
features. This can be achieved given a full recompilation
system by compiling two versions of the standard library when
the compiler is installed and linking against the appropriate
one, e.g., a multilibs approach.</para></listitem>
<listitem><para><emphasis>Partial recompilation</emphasis>: The user must recompile the
parts of his or her application and the C++ libraries it
depends on that will use the debugging facilities
directly. This means that any code that uses the debuggable
standard containers would need to be recompiled, but code
that does not use them (but may, for instance, use IOStreams)
would not have to be recompiled.</para></listitem>
<listitem><para><emphasis>Per-use recompilation</emphasis>: The user must recompile the
parts of his or her application and the C++ libraries it
depends on where debugging should occur, and any other code
that interacts with those containers. This means that a set of
translation units that accesses a particular standard
container instance may either be compiled in release mode (no
checking) or debug mode (full checking), but must all be
compiled in the same way; a translation unit that does not see
that standard container instance need not be recompiled. This
also means that a translation unit <emphasis>A</emphasis> that contains a
particular instantiation
(say, <code>std::vector&lt;int&gt;</code>) compiled in release
mode can be linked against a translation unit <emphasis>B</emphasis> that
contains the same instantiation compiled in debug mode (a
feature not present with partial recompilation). While this
behavior is technically a violation of the One Definition
Rule, this ability tends to be very important in
practice. The libstdc++ debug mode supports this level of
recompilation. </para></listitem>
<listitem><para><emphasis>Per-unit recompilation</emphasis>: The user must only
recompile the translation units where checking should occur,
regardless of where debuggable standard containers are
used. This has also been dubbed "<code>-g</code> mode",
because the <code>-g</code> compiler switch works in this way,
emitting debugging information at a per--translation-unit
granularity. We believe that this level of recompilation is in
fact not possible if we intend to supply safe iterators, leave
the program semantics unchanged, and not regress in
performance under release mode because we cannot associate
extra information with an iterator (to form a safe iterator)
without either reserving that space in release mode
(performance regression) or allocating extra memory associated
with each iterator with <code>new</code> (changes the program
semantics).</para></listitem>
</orderedlist>
</para></listitem>
</itemizedlist>
</sect2>
<sect2 id="manual.ext.debug_mode.design.methods" xreflabel="Methods">
<title>Methods</title>
<para>
</para>
<para>This section provides an overall view of the design of the
libstdc++ debug mode and details the relationship between design
decisions and the stated design goals.</para>
<sect3 id="debug_mode.design.methods.wrappers" xreflabel="Method Wrapper">
<title>The Wrapper Model</title>
<para>The libstdc++ debug mode uses a wrapper model where the debugging
versions of library components (e.g., iterators and containers) form
a layer on top of the release versions of the library
components. The debugging components first verify that the operation
is correct (aborting with a diagnostic if an error is found) and
will then forward to the underlying release-mode container that will
perform the actual work. This design decision ensures that we cannot
regress release-mode performance (because the release-mode
containers are left untouched) and partially enables <ulink url="#mixing">mixing debug and release code</ulink> at link time,
although that will not be discussed at this time.</para>
<para>Two types of wrappers are used in the implementation of the debug
mode: container wrappers and iterator wrappers. The two types of
wrappers interact to maintain relationships between iterators and
their associated containers, which are necessary to detect certain
types of standard library usage errors such as dereferencing
past-the-end iterators or inserting into a container using an
iterator from a different container.</para>
<sect4 id="debug_mode.design.methods.safe_iter" xreflabel="Method Safe Iter">
<title>Safe Iterators</title>
<para>Iterator wrappers provide a debugging layer over any iterator that
is attached to a particular container, and will manage the
information detailing the iterator's state (singular,
dereferenceable, etc.) and tracking the container to which the
iterator is attached. Because iterators have a well-defined, common
interface the iterator wrapper is implemented with the iterator
adaptor class template <code>__gnu_debug::_Safe_iterator</code>,
which takes two template parameters:</para>
<itemizedlist>
<listitem><para><code>Iterator</code>: The underlying iterator type, which must
be either the <code>iterator</code> or <code>const_iterator</code>
typedef from the sequence type this iterator can reference.</para></listitem>
<listitem><para><code>Sequence</code>: The type of sequence that this iterator
references. This sequence must be a safe sequence (discussed below)
whose <code>iterator</code> or <code>const_iterator</code> typedef
is the type of the safe iterator.</para></listitem>
</itemizedlist>
</sect4>
<sect4 id="debug_mode.design.methods.safe_seq" xreflabel="Method Safe Seq">
<title>Safe Sequences (Containers)</title>
<para>Container wrappers provide a debugging layer over a particular
container type. Because containers vary greatly in the member
functions they support and the semantics of those member functions
(especially in the area of iterator invalidation), container
wrappers are tailored to the container they reference, e.g., the
debugging version of <code>std::list</code> duplicates the entire
interface of <code>std::list</code>, adding additional semantic
checks and then forwarding operations to the
real <code>std::list</code> (a public base class of the debugging
version) as appropriate. However, all safe containers inherit from
the class template <code>__gnu_debug::_Safe_sequence</code>,
instantiated with the type of the safe container itself (an instance
of the curiously recurring template pattern).</para>
<para>The iterators of a container wrapper will be
<ulink url="#safe_iterator">safe iterators</ulink> that reference sequences
of this type and wrap the iterators provided by the release-mode
base class. The debugging container will use only the safe
iterators within its own interface (therefore requiring the user to
use safe iterators, although this does not change correct user
code) and will communicate with the release-mode base class with
only the underlying, unsafe, release-mode iterators that the base
class exports.</para>
<para> The debugging version of <code>std::list</code> will have the
following basic structure:</para>
<programlisting>
template&lt;typename _Tp, typename _Allocator = allocator&lt;_Tp&gt;
class debug-list :
public release-list&lt;_Tp, _Allocator&gt;,
public __gnu_debug::_Safe_sequence&lt;debug-list&lt;_Tp, _Allocator&gt; &gt;
{
typedef release-list&lt;_Tp, _Allocator&gt; _Base;
typedef debug-list&lt;_Tp, _Allocator&gt; _Self;
public:
typedef __gnu_debug::_Safe_iterator&lt;typename _Base::iterator, _Self&gt; iterator;
typedef __gnu_debug::_Safe_iterator&lt;typename _Base::const_iterator, _Self&gt; const_iterator;
// duplicate std::list interface with debugging semantics
};
</programlisting>
</sect4>
</sect3>
<sect3 id="debug_mode.design.methods.precond" xreflabel="Precondition check">
<title>Precondition Checking</title>
<para>The debug mode operates primarily by checking the preconditions of
all standard library operations that it supports. Preconditions that
are always checked (regardless of whether or not we are in debug
mode) are checked via the <code>__check_xxx</code> macros defined
and documented in the source
file <code>include/debug/debug.h</code>. Preconditions that may or
may not be checked, depending on the debug-mode
macro <code>_GLIBCXX_DEBUG</code>, are checked via
the <code>__requires_xxx</code> macros defined and documented in the
same source file. Preconditions are validated using any additional
information available at run-time, e.g., the containers that are
associated with a particular iterator, the position of the iterator
within those containers, the distance between two iterators that may
form a valid range, etc. In the absence of suitable information,
e.g., an input iterator that is not a safe iterator, these
precondition checks will silently succeed.</para>
<para>The majority of precondition checks use the aforementioned macros,
which have the secondary benefit of having prewritten debug
messages that use information about the current status of the
objects involved (e.g., whether an iterator is singular or what
sequence it is attached to) along with some static information
(e.g., the names of the function parameters corresponding to the
objects involved). When not using these macros, the debug mode uses
either the debug-mode assertion
macro <code>_GLIBCXX_DEBUG_ASSERT</code> , its pedantic
cousin <code>_GLIBCXX_DEBUG_PEDASSERT</code>, or the assertion
check macro that supports more advance formulation of error
messages, <code>_GLIBCXX_DEBUG_VERIFY</code>. These macros are
documented more thoroughly in the debug mode source code.</para>
</sect3>
<sect3 id="debug_mode.design.methods.coexistence" xreflabel="Coexistence">
<title>Release- and debug-mode coexistence</title>
<para>The libstdc++ debug mode is the first debug mode we know of that
is able to provide the "Per-use recompilation" (4) guarantee, that
allows release-compiled and debug-compiled code to be linked and
executed together without causing unpredictable behavior. This
guarantee minimizes the recompilation that users are required to
perform, shortening the detect-compile-debug bughunting cycle
and making the debug mode easier to incorporate into development
environments by minimizing dependencies.</para>
<para>Achieving link- and run-time coexistence is not a trivial
implementation task. To achieve this goal we required a small
extension to the GNU C++ compiler (described in the GCC Manual for
C++ Extensions, see <ulink url="http://gcc.gnu.org/onlinedocs/gcc/Strong-Using.html">strong
using</ulink>), and a complex organization of debug- and
release-modes. The end result is that we have achieved per-use
recompilation but have had to give up some checking of the
<code>std::basic_string</code> class template (namely, safe
iterators).
</para>
<sect4 id="methods.coexistence.compile" xreflabel="Compile">
<title>Compile-time coexistence of release- and debug-mode components</title>
<para>Both the release-mode components and the debug-mode
components need to exist within a single translation unit so that
the debug versions can wrap the release versions. However, only one
of these components should be user-visible at any particular
time with the standard name, e.g., <code>std::list</code>. </para>
<para>In release mode, we define only the release-mode version of the
component with its standard name and do not include the debugging
component at all. The release mode version is defined within the
namespace <code>std</code>. Minus the namespace associations, this
method leaves the behavior of release mode completely unchanged from
its behavior prior to the introduction of the libstdc++ debug
mode. Here's an example of what this ends up looking like, in
C++.</para>
<programlisting>
namespace std
{
template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;
class list
{
// ...
};
} // namespace std
</programlisting>
<para>In debug mode we include the release-mode container (which is now
defined in in the namespace <code>__norm</code>) and also the
debug-mode container. The debug-mode container is defined within the
namespace <code>__debug</code>, which is associated with namespace
<code>std</code> via the GNU namespace association extension. This
method allows the debug and release versions of the same component to
coexist at compile-time and link-time without causing an unreasonable
maintenance burden, while minimizing confusion. Again, this boils down
to C++ code as follows:</para>
<programlisting>
namespace std
{
namespace __norm
{
template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;
class list
{
// ...
};
} // namespace __gnu_norm
namespace __debug
{
template&lt;typename _Tp, typename _Alloc = allocator&lt;_Tp&gt; &gt;
class list
: public __norm::list&lt;_Tp, _Alloc&gt;,
public __gnu_debug::_Safe_sequence&lt;list&lt;_Tp, _Alloc&gt; &gt;
{
// ...
};
} // namespace __norm
using namespace __debug __attribute__ ((strong));
}
</programlisting>
</sect4>
<sect4 id="methods.coexistence.link" xreflabel="Link">
<title>Link- and run-time coexistence of release- and
debug-mode components</title>
<para>Because each component has a distinct and separate release and
debug implementation, there are are no issues with link-time
coexistence: the separate namespaces result in different mangled
names, and thus unique linkage.</para>
<para>However, components that are defined and used within the C++
standard library itself face additional constraints. For instance,
some of the member functions of <code> std::moneypunct</code> return
<code>std::basic_string</code>. Normally, this is not a problem, but
with a mixed mode standard library that could be using either
debug-mode or release-mode <code> basic_string</code> objects, things
get more complicated. As the return value of a function is not
encoded into the mangled name, there is no way to specify a
release-mode or a debug-mode string. In practice, this results in
runtime errors. A simplified example of this problem is as follows.
</para>
<para> Take this translation unit, compiled in debug-mode: </para>
<programlisting>
// -D_GLIBCXX_DEBUG
#include &lt;string&gt;
std::string test02();
std::string test01()
{
return test02();
}
int main()
{
test01();
return 0;
}
</programlisting>
<para> ... and linked to this translation unit, compiled in release mode:</para>
<programlisting>
#include &lt;string&gt;
std::string
test02()
{
return std::string("toast");
}
</programlisting>
<para> For this reason we cannot easily provide safe iterators for
the <code>std::basic_string</code> class template, as it is present
throughout the C++ standard library. For instance, locale facets
define typedefs that include <code>basic_string</code>: in a mixed
debug/release program, should that typedef be based on the
debug-mode <code>basic_string</code> or the
release-mode <code>basic_string</code>? While the answer could be
"both", and the difference hidden via renaming a la the
debug/release containers, we must note two things about locale
facets:</para>
<orderedlist>
<listitem><para>They exist as shared state: one can create a facet in one
translation unit and access the facet via the same type name in a
different translation unit. This means that we cannot have two
different versions of locale facets, because the types would not be
the same across debug/release-mode translation unit barriers.</para></listitem>
<listitem><para>They have virtual functions returning strings: these functions
mangle in the same way regardless of the mangling of their return
types (see above), and their precise signatures can be relied upon
by users because they may be overridden in derived classes.</para></listitem>
</orderedlist>
<para>With the design of libstdc++ debug mode, we cannot effectively hide
the differences between debug and release-mode strings from the
user. Failure to hide the differences may result in unpredictable
behavior, and for this reason we have opted to only
perform <code>basic_string</code> changes that do not require ABI
changes. The effect on users is expected to be minimal, as there are
simple alternatives (e.g., <code>__gnu_debug::basic_string</code>),
and the usability benefit we gain from the ability to mix debug- and
release-compiled translation units is enormous.</para>
</sect4>
<sect4 id="methods.coexistence.alt" xreflabel="Alternatives">
<title>Alternatives for Coexistence</title>
<para>The coexistence scheme above was chosen over many alternatives,
including language-only solutions and solutions that also required
extensions to the C++ front end. The following is a partial list of
solutions, with justifications for our rejection of each.</para>
<itemizedlist>
<listitem><para><emphasis>Completely separate debug/release libraries</emphasis>: This is by
far the simplest implementation option, where we do not allow any
coexistence of debug- and release-compiled translation units in a
program. This solution has an extreme negative affect on usability,
because it is quite likely that some libraries an application
depends on cannot be recompiled easily. This would not meet
our <emphasis>usability</emphasis> or <emphasis>minimize recompilation</emphasis> criteria
well.</para></listitem>
<listitem><para><emphasis>Add a <code>Debug</code> boolean template parameter</emphasis>:
Partial specialization could be used to select the debug
implementation when <code>Debug == true</code>, and the state
of <code>_GLIBCXX_DEBUG</code> could decide whether the
default <code>Debug</code> argument is <code>true</code>
or <code>false</code>. This option would break conformance with the
C++ standard in both debug <emphasis>and</emphasis> release modes. This would
not meet our <emphasis>correctness</emphasis> criteria. </para></listitem>
<listitem><para><emphasis>Packaging a debug flag in the allocators</emphasis>: We could
reuse the <code>Allocator</code> template parameter of containers
by adding a sentinel wrapper <code>debug&lt;&gt;</code> that
signals the user's intention to use debugging, and pick up
the <code>debug&lt;&gt;</code> allocator wrapper in a partial
specialization. However, this has two drawbacks: first, there is a
conformance issue because the default allocator would not be the
standard-specified <code>std::allocator&lt;T&gt;</code>. Secondly
(and more importantly), users that specify allocators instead of
implicitly using the default allocator would not get debugging
containers. Thus this solution fails the <emphasis>correctness</emphasis>
criteria.</para></listitem>
<listitem><para><emphasis>Define debug containers in another namespace, and employ
a <code>using</code> declaration (or directive)</emphasis>: This is an
enticing option, because it would eliminate the need for
the <code>link_name</code> extension by aliasing the
templates. However, there is no true template aliasing mechanism
is C++, because both <code>using</code> directives and using
declarations disallow specialization. This method fails
the <emphasis>correctness</emphasis> criteria.</para></listitem>
<listitem><para><emphasis> Use implementation-specific properties of anonymous
namespaces. </emphasis>
See <ulink url="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00004.html"> this post
</ulink>
This method fails the <emphasis>correctness</emphasis> criteria.</para></listitem>
<listitem><para><emphasis>Extension: allow reopening on namespaces</emphasis>: This would
allow the debug mode to effectively alias the
namespace <code>std</code> to an internal namespace, such
as <code>__gnu_std_debug</code>, so that it is completely
separate from the release-mode <code>std</code> namespace. While
this will solve some renaming problems and ensure that
debug- and release-compiled code cannot be mixed unsafely, it ensures that
debug- and release-compiled code cannot be mixed at all. For
instance, the program would have two <code>std::cout</code>
objects! This solution would fails the <emphasis>minimize
recompilation</emphasis> requirement, because we would only be able to
support option (1) or (2).</para></listitem>
<listitem><para><emphasis>Extension: use link name</emphasis>: This option involves
complicated re-naming between debug-mode and release-mode
components at compile time, and then a g++ extension called <emphasis>
link name </emphasis> to recover the original names at link time. There
are two drawbacks to this approach. One, it's very verbose,
relying on macro renaming at compile time and several levels of
include ordering. Two, ODR issues remained with container member
functions taking no arguments in mixed-mode settings resulting in
equivalent link names, <code> vector::push_back() </code> being
one example.
See <ulink url="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00177.html">link
name</ulink> </para></listitem>
</itemizedlist>
<para>Other options may exist for implementing the debug mode, many of
which have probably been considered and others that may still be
lurking. This list may be expanded over time to include other
options that we could have implemented, but in all cases the full
ramifications of the approach (as measured against the design goals
for a libstdc++ debug mode) should be considered first. The DejaGNU
testsuite includes some testcases that check for known problems with
some solutions (e.g., the <code>using</code> declaration solution
that breaks user specialization), and additional testcases will be
added as we are able to identify other typical problem cases. These
test cases will serve as a benchmark by which we can compare debug
mode implementations.</para>
</sect4>
</sect3>
</sect2>
<sect2 id="manual.ext.debug_mode.design.other" xreflabel="Other">
<title>Other Implementations</title>
<para>
</para>
<para> There are several existing implementations of debug modes for C++
standard library implementations, although none of them directly
supports debugging for programs using libstdc++. The existing
implementations include:</para>
<itemizedlist>
<listitem><para><ulink url="http://www.mathcs.sjsu.edu/faculty/horstman/safestl.html">SafeSTL</ulink>:
SafeSTL was the original debugging version of the Standard Template
Library (STL), implemented by Cay S. Horstmann on top of the
Hewlett-Packard STL. Though it inspired much work in this area, it
has not been kept up-to-date for use with modern compilers or C++
standard library implementations.</para></listitem>
<listitem><para><ulink url="http://www.stlport.org/">STLport</ulink>: STLport is a free
implementation of the C++ standard library derived from the <ulink url="http://www.sgi.com/tech/stl/">SGI implementation</ulink>, and
ported to many other platforms. It includes a debug mode that uses a
wrapper model (that in some way inspired the libstdc++ debug mode
design), although at the time of this writing the debug mode is
somewhat incomplete and meets only the "Full user recompilation" (2)
recompilation guarantee by requiring the user to link against a
different library in debug mode vs. release mode.</para></listitem>
<listitem><para><ulink url="http://www.metrowerks.com/mw/default.htm">Metrowerks
CodeWarrior</ulink>: The C++ standard library that ships with Metrowerks
CodeWarrior includes a debug mode. It is a full debug-mode
implementation (including debugging for CodeWarrior extensions) and
is easy to use, although it meets only the "Full recompilation" (1)
recompilation guarantee.</para></listitem>
</itemizedlist>
</sect2>
</sect1>
</chapter>

View file

@ -0,0 +1,126 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.diagnostics" xreflabel="Diagnostics">
<?dbhtml filename="diagnostics.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Diagnostics</title>
<chapter id="manual.diagnostics.exceptions" xreflabel="Exceptions">
<title>Exceptions</title>
<sect1 id="manual.diagnostics.exceptions.hierarchy" xreflabel="Exception Classes">
<title>Exception Classes</title>
<para>
All exception objects are defined in one of the standard header
files: <filename>exception</filename>,
<filename>stdexcept</filename>, <filename>new</filename>, and
<filename>typeinfo</filename>.
</para>
<para>
The base exception object is <classname>exception</classname>,
located in <filename>exception</filename>. This object has no
<classname>string</classname> member.
</para>
<para>
Derived from this are several classes that may have a
<classname>string</classname> member: a full heirarchy can be
found in the <ulink url="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00233.html">source documentation</ulink>.
</para>
</sect1>
<sect1 id="manual.diagnostics.exceptions.data" xreflabel="Adding Data to Exceptions">
<title>Adding Data to Exceptions</title>
<para>
The standard exception classes carry with them a single string as
data (usually describing what went wrong or where the 'throw' took
place). It's good to remember that you can add your own data to
these exceptions when extending the hierarchy:
</para>
<programlisting>
struct My_Exception : public std::runtime_error
{
public:
My_Exception (const string&amp; whatarg)
: std::runtime_error(whatarg), e(errno), id(GetDataBaseID()) { }
int errno_at_time_of_throw() const { return e; }
DBID id_of_thing_that_threw() const { return id; }
protected:
int e;
DBID id; // some user-defined type
};
</programlisting>
</sect1>
<sect1 id="manual.diagnostics.exceptions.cancellation" xreflabel="Cancellation">
<title>Cancellation</title>
<para>
</para>
</sect1>
</chapter>
<chapter id="manual.diagnostics.concept_checking" xreflabel="Concept Checking">
<title>Concept Checking</title>
<para>
In 1999, SGI added <quote>concept checkers</quote> to their
implementation of the STL: code which checked the template
parameters of instantiated pieces of the STL, in order to insure
that the parameters being used met the requirements of the
standard. For example, the Standard requires that types passed as
template parameters to <classname>vector</classname> be
&quot;Assignable&quot; (which means what you think it means). The
checking was done during compilation, and none of the code was
executed at runtime.
</para>
<para>
Unfortunately, the size of the compiler files grew significantly
as a result. The checking code itself was cumbersome. And bugs
were found in it on more than one occasion.
</para>
<para>
The primary author of the checking code, Jeremy Siek, had already
started work on a replacement implementation. The new code has been
formally reviewed and accepted into
<ulink url="http://www.boost.org/libs/concept_check/concept_check.htm">the
Boost libraries</ulink>, and we are pleased to incorporate it into the
GNU C++ library.
</para>
<para>
The new version imposes a much smaller space overhead on the generated
object file. The checks are also cleaner and easier to read and
understand.
</para>
<para>
They are off by default for all versions of GCC.
They can be enabled at configure time with
<ulink url="../configopts.html"><literal>--enable-concept-checks</literal></ulink>.
You can enable them on a per-translation-unit basis with
<literal>-D_GLIBCXX_CONCEPT_CHECKS</literal>.
</para>
<para>
Please note that the upcoming C++ standard has first-class
support for template parameter constraints based on concepts in the core
language. This will obviate the need for the library-simulated concept
checking described above.
</para>
</chapter>
</part>

View file

@ -0,0 +1,452 @@
<sect1 id="appendix.porting.api" xreflabel="api">
<?dbhtml filename="api.html"?>
<sect1info>
<keywordset>
<keyword>ISO C++</keyword>
<keyword>api</keyword>
<keyword>evolution</keyword>
<keyword>deprecation</keyword>
<keyword>history</keyword>
</keywordset>
</sect1info>
<title>API Evolution and Deprecation History</title>
<para>
A list of user-visible changes, in cronological order
</para>
<sect2 id="api.rel_300" xreflabel="api.rel_300">
<title><constant>3.0</constant></title>
<para>
Extensions moved to <filename class="directory">include/ext</filename>.
</para>
<para>
Include files from the SGI/HP sources that pre-date the ISO standard
are added. These files are placed into
the <filename class="directory">include/backward</filename> directory and a deprecated warning
is added that notifies on inclusion (<literal>-Wno-deprecated</literal>
deactivates the warning.)
</para>
<para>Deprecated include <filename class="headerfile">backward/strstream</filename> added.</para>
<para>Removal of include <filename class="headerfile">builtinbuf.h</filename>, <filename class="headerfile">indstream.h</filename>, <filename class="headerfile">parsestream.h</filename>, <filename class="headerfile">PlotFile.h</filename>, <filename class="headerfile">SFile.h</filename>, <filename class="headerfile">stdiostream.h</filename>, and <filename class="headerfile">stream.h</filename>.
</para>
</sect2>
<sect2 id="api.rel_310" xreflabel="api.rel_310">
<title><constant>3.1</constant></title>
<para>
</para>
<para>
Extensions from SGI/HP moved from <code>namespace std</code>
to <code>namespace __gnu_cxx</code>. As part of this, the following
new includes are
added: <filename class="headerfile">ext/algorithm</filename>, <filename class="headerfile">ext/functional</filename>, <filename class="headerfile">ext/iterator</filename>, <filename class="headerfile">ext/memory</filename>, and <filename class="headerfile">ext/numeric</filename>.
</para>
<para>
Extensions to <code>basic_filebuf</code> introduced: <code>__gnu_cxx::enc_filebuf</code>, and <code>__gnu_cxx::stdio_filebuf</code>.
</para>
<para>
Extensions to tree data structures added in <filename class="headerfile">ext/rb_tree</filename>.
</para>
<para>
Removal of <filename class="headerfile">ext/tree</filename>, moved to <filename class="headerfile">backward/tree.h</filename>.
</para>
</sect2>
<sect2 id="api.rel_320" xreflabel="api.rel_320">
<title><constant>3.2</constant></title>
<para>
</para>
<para>Symbol versioning introduced for shared library.</para>
<para>Removal of include <filename class="headerfile">backward/strstream.h</filename>.</para>
<para>Allocator changes. Change <code>__malloc_alloc</code> to <code>malloc_allocator</code> and <code>__new_alloc</code> to <code>new_allocator</code>. </para>
<para> For GCC releases from 2.95 through the 3.1 series, defining
<literal>__USE_MALLOC</literal> on the gcc command line would change the
default allocation strategy to instead use <code> malloc</code> and
<function>free</function>. See
<ulink url="../23_containers/howto.html#3">this note</ulink>
for details as to why this was something needing improvement.
</para>
<para>Error handling in iostreams cleaned up, made consistent. </para>
</sect2>
<sect2 id="api.rel_330" xreflabel="api.rel_330">
<title><constant>3.3</constant></title>
<para>
</para>
</sect2>
<sect2 id="api.rel_340" xreflabel="api.rel_340">
<title><constant>3.4</constant></title>
<para>
</para>
<para>
Large file support.
</para>
<para> Extensions for generic characters and <code>char_traits</code> added in <filename class="headerfile">ext/pod_char_traits.h</filename>.
</para>
<para>
Support for <code>wchar_t</code> specializations of <code>basic_filebuf</code> enhanced to support <code>UTF-8</code> and <code>Unicode</code>, depending on host. More hosts support basic <code>wchar_t</code> functionality.
</para>
<para>
Support for <code>char_traits</code> beyond builtin types.
</para>
<para>
Conformant <code>allocator</code> class and usage in containers. As
part of this, the following extensions are
added: <filename class="headerfile">ext/bitmap_allocator.h</filename>, <filename class="headerfile">ext/debug_allocator.h</filename>, <filename class="headerfile">ext/mt_allocator.h</filename>, <filename class="headerfile">ext/malloc_allocator.h</filename>,<filename class="headerfile">ext/new_allocator.h</filename>, <filename class="headerfile">ext/pool_allocator.h</filename>.
</para>
<para>
This is a change from all previous versions, and may require
source-level changes due to allocator-related changes to structures
names and template parameters, filenames, and file locations. Some,
like <code>__simple_alloc, __allocator, __alloc, </code> and <code>
_Alloc_traits</code> have been removed.
</para>
<para>Default behavior of <code>std::allocator</code> has changed.</para>
<para>
Previous versions prior to 3.4 cache allocations in a memory
pool, instead of passing through to call the global allocation
operators (ie, <classname>__gnu_cxx::pool_allocator</classname>). More
recent versions default to the
simpler <classname>__gnu_cxx::new_allocator</classname>.
</para>
<para> Previously, all allocators were written to the SGI
style, and all STL containers expected this interface. This
interface had a traits class called <code>_Alloc_traits</code> that
attempted to provide more information for compile-time allocation
selection and optimization. This traits class had another allocator
wrapper, <code>__simple_alloc&lt;T,A&gt;</code>, which was a
wrapper around another allocator, A, which itself is an allocator
for instances of T. But wait, there's more:
<code>__allocator&lt;T,A&gt;</code> is another adapter. Many of
the provided allocator classes were SGI style: such classes can be
changed to a conforming interface with this wrapper:
<code>__allocator&lt;T, __alloc&gt;</code> is thus the same as
<code>allocator&lt;T&gt;</code>.
</para>
<para> The class <classname>allocator</classname> used the typedef
<type>__alloc</type> to select an underlying allocator that
satisfied memory allocation requests. The selection of this
underlying allocator was not user-configurable.
</para>
<table frame='all'>
<title>Extension Allocators</title>
<tgroup cols='4' align='left' colsep='1' rowsep='1'>
<colspec colname='c1'></colspec>
<colspec colname='c2'></colspec>
<colspec colname='c3'></colspec>
<colspec colname='c4'></colspec>
<thead>
<row>
<entry>Allocator (3.4)</entry>
<entry>Header (3.4)</entry>
<entry>Allocator (3.[0-3])</entry>
<entry>Header (3.[0-3])</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>__gnu_cxx::new_allocator&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/new_allocator.h</filename></entry>
<entry><classname>std::__new_alloc</classname></entry>
<entry><filename class="headerfile">memory</filename></entry>
</row>
<row>
<entry><classname>__gnu_cxx::malloc_allocator&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/malloc_allocator.h</filename></entry>
<entry><classname>std::__malloc_alloc_template&lt;int&gt;</classname></entry>
<entry><filename class="headerfile">memory</filename></entry>
</row>
<row>
<entry><classname>__gnu_cxx::debug_allocator&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/debug_allocator.h</filename></entry>
<entry><classname>std::debug_alloc&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">memory</filename></entry>
</row>
<row>
<entry><classname>__gnu_cxx::__pool_alloc&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/pool_allocator.h</filename></entry>
<entry><classname>std::__default_alloc_template&lt;bool,int&gt;</classname></entry>
<entry><filename class="headerfile">memory</filename></entry>
</row>
<row>
<entry><classname>__gnu_cxx::__mt_alloc&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/mt_allocator.h</filename></entry>
<entry> </entry>
<entry> </entry>
</row>
<row>
<entry><classname>__gnu_cxx::bitmap_allocator&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/bitmap_allocator.h</filename></entry>
<entry> </entry>
<entry> </entry>
</row>
</tbody>
</tgroup>
</table>
<para> Releases after gcc-3.4 have continued to add to the collection
of available allocators. All of these new allocators are
standard-style. The following table includes details, along with
the first released version of GCC that included the extension allocator.
</para>
<table frame='all'>
<title>Extension Allocators Continued</title>
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
<colspec colname='c1'></colspec>
<colspec colname='c2'></colspec>
<colspec colname='c3'></colspec>
<thead>
<row>
<entry>Allocator</entry>
<entry>Include</entry>
<entry>Version</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>__gnu_cxx::array_allocator&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/array_allocator.h</filename></entry>
<entry>4.0.0</entry>
</row>
<row>
<entry><classname>__gnu_cxx::throw_allocator&lt;T&gt;</classname></entry>
<entry><filename class="headerfile">ext/throw_allocator.h</filename></entry>
<entry>4.2.0</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Debug mode first appears.
</para>
<para>
Precompiled header support <acronym>PCH</acronym> support.
</para>
<para>
Macro guard for changed, from <literal>_GLIBCPP_</literal> to <literal>_GLIBCXX_</literal>.
</para>
<para>
Extension <filename class="headerfile">ext/stdio_sync_filebuf.h</filename> added.
</para>
<para>
Extension <filename class="headerfile">ext/demangle.h</filename> added.
</para>
</sect2>
<sect2 id="api.rel_400" xreflabel="api.rel_400">
<title><constant>4.0</constant></title>
<para>
</para>
<para>
TR1 features first appear.
</para>
<para>
Extension allocator <filename class="headerfile">ext/array_allocator.h</filename> added.
</para>
<para>
Extension <code>codecvt</code> specializations moved to <filename class="headerfile">ext/codecvt_specializations.h</filename>.
</para>
<para>
Removal of <filename class="headerfile">ext/demangle.h</filename>.
</para>
</sect2>
<sect2 id="api.rel_410" xreflabel="api.rel_410">
<title><constant>4.1</constant></title>
<para>
</para>
<para>
Removal of <filename class="headerfile">cassert</filename> from all standard headers: now has to be explicitly included for <code>std::assert</code> calls.
</para>
<para> Extensions for policy-based data structures first added. New includes,
types, namespace <code>pb_assoc</code>.
</para>
<para> Extensions for typelists added in <filename class="headerfile">ext/typelist.h</filename>.
</para>
<para> Extension for policy-based <code>basic_string</code> first added: <code>__gnu_cxx::__versa_string</code> in <filename class="headerfile">ext/vstring.h</filename>.
</para>
</sect2>
<sect2 id="api.rel_420" xreflabel="api.rel_420">
<title><constant>4.2</constant></title>
<para>
</para>
<para> Default visibility attributes applied to <code>namespace std</code>. Support for <code>-fvisibility</code>.
</para>
<para>TR1 <filename class="headerfile">random</filename>, <filename class="headerfile">complex</filename>, and C compatibility headers added.</para>
<para> Extensions for concurrent programming consolidated
into <filename class="headerfile">ext/concurrence.h</filename> and <filename class="headerfile">ext/atomicity.h</filename>,
including change of namespace to <code>__gnu_cxx</code> in some
cases. Added types
include <code>_Lock_policy</code>, <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__mutex</code>, <code>__scoped_lock</code>.</para>
<para> Extensions for type traits consolidated
into <filename class="headerfile">ext/type_traits.h</filename>. Additional traits are added
(<code>__conditional_type</code>, <code>__enable_if</code>, others.)
</para>
<para> Extensions for policy-based data structures revised. New includes,
types, namespace moved to <code>__pb_ds</code>.
</para>
<para> Extensions for debug mode modified: now nested in <code>namespace
std::__debug</code> and extensions in <code>namespace
__gnu_cxx::__debug</code>.</para>
<para> Extensions added: <filename class="headerfile">ext/typelist.h</filename>
and <filename class="headerfile">ext/throw_allocator.h</filename>.
</para>
</sect2>
<sect2 id="api.rel_430" xreflabel="api.rel_430">
<title><constant>4.3</constant></title>
<para>
</para>
<para>
C++0X features first appear.
</para>
<para>TR1 <filename class="headerfile">regex</filename> and <filename class="headerfile">cmath</filename>'s mathematical special function added.</para>
<para>
Backward include edit.
</para>
<itemizedlist>
<listitem>
<para>Removed</para>
<para>
<filename class="headerfile">algobase.h</filename> <filename class="headerfile">algo.h</filename> <filename class="headerfile">alloc.h</filename> <filename class="headerfile">bvector.h</filename> <filename class="headerfile">complex.h</filename>
<filename class="headerfile">defalloc.h</filename> <filename class="headerfile">deque.h</filename> <filename class="headerfile">fstream.h</filename> <filename class="headerfile">function.h</filename> <filename class="headerfile">hash_map.h</filename> <filename class="headerfile">hash_set.h</filename>
<filename class="headerfile">hashtable.h</filename> <filename class="headerfile">heap.h</filename> <filename class="headerfile">iomanip.h</filename> <filename class="headerfile">iostream.h</filename> <filename class="headerfile">istream.h</filename> <filename class="headerfile">iterator.h</filename>
<filename class="headerfile">list.h</filename> <filename class="headerfile">map.h</filename> <filename class="headerfile">multimap.h</filename> <filename class="headerfile">multiset.h</filename> <filename class="headerfile">new.h</filename> <filename class="headerfile">ostream.h</filename> <filename class="headerfile">pair.h</filename> <filename class="headerfile">queue.h</filename> <filename class="headerfile">rope.h</filename> <filename class="headerfile">set.h</filename> <filename class="headerfile">slist.h</filename> <filename class="headerfile">stack.h</filename> <filename class="headerfile">streambuf.h</filename> <filename class="headerfile">stream.h</filename> <filename class="headerfile">tempbuf.h</filename>
<filename class="headerfile">tree.h</filename> <filename class="headerfile">vector.h</filename>
</para>
</listitem>
<listitem>
<para>Added</para>
<para>
<filename class="headerfile">hash_map</filename> and <filename class="headerfile">hash_set</filename>
</para>
</listitem>
<listitem>
<para>Added in C++0x</para>
<para>
<filename class="headerfile">auto_ptr.h</filename> and <filename class="headerfile">binders.h</filename>
</para>
</listitem>
</itemizedlist>
<para>
Header dependency streamlining.
</para>
<itemizedlist>
<listitem><para><filename class="headerfile">algorithm</filename> no longer includes <filename class="headerfile">climits</filename>, <filename class="headerfile">cstring</filename>, or <filename class="headerfile">iosfwd</filename> </para></listitem>
<listitem><para><filename class="headerfile">bitset</filename> no longer includes <filename class="headerfile">istream</filename> or <filename class="headerfile">ostream</filename>, adds <filename class="headerfile">iosfwd</filename> </para></listitem>
<listitem><para><filename class="headerfile">functional</filename> no longer includes <filename class="headerfile">cstddef</filename></para></listitem>
<listitem><para><filename class="headerfile">iomanip</filename> no longer includes <filename class="headerfile">istream</filename>, <filename class="headerfile">istream</filename>, or <filename class="headerfile">functional</filename>, adds <filename class="headerfile">ioswd</filename> </para></listitem>
<listitem><para><filename class="headerfile">numeric</filename> no longer includes <filename class="headerfile">iterator</filename></para></listitem>
<listitem><para><filename class="headerfile">string</filename> no longer includes <filename class="headerfile">algorithm</filename> or <filename class="headerfile">memory</filename></para></listitem>
<listitem><para><filename class="headerfile">valarray</filename> no longer includes <filename class="headerfile">numeric</filename> or <filename class="headerfile">cstdlib</filename></para></listitem>
<listitem><para><filename class="headerfile">tr1/hashtable</filename> no longer includes <filename class="headerfile">memory</filename> or <filename class="headerfile">functional</filename></para></listitem>
<listitem><para><filename class="headerfile">tr1/memory</filename> no longer includes <filename class="headerfile">algorithm</filename></para></listitem>
<listitem><para><filename class="headerfile">tr1/random</filename> no longer includes <filename class="headerfile">algorithm</filename> or <filename class="headerfile">fstream</filename></para></listitem>
</itemizedlist>
<para>
Debug mode for <filename class="headerfile">unordered_map</filename> and <filename class="headerfile">unordered_set</filename>.
</para>
<para>
Parallel mode first appears.
</para>
<para>Variadic template implementations of items in <filename class="headerfile">tuple</filename> and
<filename class="headerfile">functional</filename>.
</para>
<para>Default <code>what</code> implementations give more elaborate
exception strings for <code>bad_cast</code>,
<code>bad_typeid</code>, <code>bad_exception</code>, and
<code>bad_alloc</code>.
</para>
<para>
PCH binary files no longer installed. Instead, the source files are installed.
</para>
<para>
Namespace pb_ds moved to __gnu_pb_ds.
</para>
</sect2>
</sect1>

View file

@ -0,0 +1,577 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.ext" xreflabel="Extensions">
<?dbhtml filename="extensions.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Extensions</title>
<preface>
<title></title>
<para>
Here we will make an attempt at describing the non-Standard extensions to
the library. Some of these are from SGI's STL, some of these are GNU's,
and some just seemed to appear on the doorstep.
</para>
<para><emphasis>Before</emphasis> you leap in and use any of these
extensions, be aware of two things:
</para>
<orderedlist>
<listitem>
<para>
Non-Standard means exactly that.
</para>
<para>
The behavior, and the very
existence, of these extensions may change with little or no
warning. (Ideally, the really good ones will appear in the next
revision of C++.) Also, other platforms, other compilers, other
versions of g++ or libstdc++ may not recognize these names, or
treat them differently, or...
</para>
</listitem>
<listitem>
<para>
You should know how to <ulink url="XXX">access
these headers properly</ulink>.
</para>
</listitem>
</orderedlist>
</preface>
<!-- Chapter 01 : Compile Time Checks -->
<chapter id="manual.ext.compile_checks" xreflabel="Compile Time Checks">
<title>Compile Time Checks</title>
<para>
Also known as concept checking.
</para>
<para>In 1999, SGI added <emphasis>concept checkers</emphasis> to their implementation
of the STL: code which checked the template parameters of
instantiated pieces of the STL, in order to insure that the parameters
being used met the requirements of the standard. For example,
the Standard requires that types passed as template parameters to
<code>vector</code> be <quote>Assignable</quote> (which means what you think
it means). The checking was done during compilation, and none of
the code was executed at runtime.
</para>
<para>Unfortunately, the size of the compiler files grew significantly
as a result. The checking code itself was cumbersome. And bugs
were found in it on more than one occasion.
</para>
<para>The primary author of the checking code, Jeremy Siek, had already
started work on a replacement implementation. The new code has been
formally reviewed and accepted into
<ulink url="http://www.boost.org/libs/concept_check/concept_check.htm">the
Boost libraries</ulink>, and we are pleased to incorporate it into the
GNU C++ library.
</para>
<para>The new version imposes a much smaller space overhead on the generated
object file. The checks are also cleaner and easier to read and
understand.
</para>
<para>They are off by default for all versions of GCC from 3.0 to 3.4 (the
latest release at the time of writing).
They can be enabled at configure time with
<ulink url="../configopts.html"><literal>--enable-concept-checks</literal></ulink>.
You can enable them on a per-translation-unit basis with
<code>#define _GLIBCXX_CONCEPT_CHECKS</code> for GCC 3.4 and higher
(or with <code>#define _GLIBCPP_CONCEPT_CHECKS</code> for versions
3.1, 3.2 and 3.3).
</para>
<para>Please note that the upcoming C++ standard has first-class
support for template parameter constraints based on concepts in the core
language. This will obviate the need for the library-simulated concept
checking described above.
</para>
</chapter>
<!-- Chapter 02 : Debug Mode -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="debug_mode.xml">
</xi:include>
<!-- Chapter 03 : Parallel Mode -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="parallel_mode.xml">
</xi:include>
<!-- Chapter 04 : Allocators -->
<chapter id="manual.ext.allocator" xreflabel="Allocators">
<title>Allocators</title>
<!-- Section 01 : __mt_alloc -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="mt_allocator.xml">
</xi:include>
<!-- Section 02 : bitmap_allocator -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="bitmap_allocator.xml">
</xi:include>
</chapter>
<!-- Chapter 05 : Containers -->
<chapter id="manual.ext.containers" xreflabel="Containers">
<title>Containers</title>
<para>
</para>
<sect1 id="manual.ext.containers.pbds" xreflabel="Policy Based Data Structures">
<title>Policy Based Data Structures</title>
<para>
<ulink
url="http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/index.html">More details here</ulink>.
</para>
</sect1>
<sect1 id="manual.ext.containers.sgi" xreflabel="SGI ext">
<title>HP/SGI</title>
<para>
</para>
<para>A few extensions and nods to backwards-compatibility have been made with
containers. Those dealing with older SGI-style allocators are dealt with
elsewhere. The remaining ones all deal with bits:
</para>
<para>The old pre-standard <code>bit_vector</code> class is present for
backwards compatibility. It is simply a typedef for the
<code>vector&lt;bool&gt;</code> specialization.
</para>
<para>The <code>bitset</code> class has a number of extensions, described in the
rest of this item. First, we'll mention that this implementation of
<code>bitset&lt;N&gt;</code> is specialized for cases where N number of
bits will fit into a single word of storage. If your choice of N is
within that range (&lt;=32 on i686-pc-linux-gnu, for example), then all
of the operations will be faster.
</para>
<para>There are
versions of single-bit test, set, reset, and flip member functions which
do no range-checking. If we call them member functions of an instantiation
of &quot;bitset&lt;N&gt;,&quot; then their names and signatures are:
</para>
<programlisting>
bitset&lt;N&gt;&amp; _Unchecked_set (size_t pos);
bitset&lt;N&gt;&amp; _Unchecked_set (size_t pos, int val);
bitset&lt;N&gt;&amp; _Unchecked_reset (size_t pos);
bitset&lt;N&gt;&amp; _Unchecked_flip (size_t pos);
bool _Unchecked_test (size_t pos);
</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).
</para>
<para>The semantics of member function <code>operator[]</code> are not specified
in the C++ standard. A long-standing defect report calls for sensible
obvious semantics, which are already implemented here: <code>op[]</code>
on a const bitset returns a bool, and for a non-const bitset returns a
<code>reference</code> (a nested type). However, this implementation does
no range-checking on the index argument, which is in keeping with other
containers' <code>op[]</code> requirements. The defect report's proposed
resolution calls for range-checking to be done. We'll just wait and see...
</para>
<para>Finally, two additional searching functions have been added. They return
the index of the first &quot;on&quot; bit, and the index of the first
&quot;on&quot; bit that is after <code>prev</code>, respectively:
</para>
<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>
</sect1>
<sect1 id="manual.ext.containers.deprecated_sgi" xreflabel="SGI ext dep">
<title>Deprecated HP/SGI</title>
<para>
The SGI hashing classes <classname>hash_set</classname> and
<classname>hash_set</classname> have been deprecated by the
unordered_set, unordered_multiset, unordered_map,
unordered_multimap containers in TR1 and the upcoming C++0x, and
may be removed in future releases.
</para>
<para>The SGI headers</para>
<programlisting>
&lt;hash_map&gt;
&lt;hash_set&gt;
&lt;rope&gt;
&lt;slist&gt;
&lt;rb_tree&gt;
</programlisting>
<para>are all here;
<code>&lt;hash_map&gt;</code> and <code>&lt;hash_set&gt;</code>
are deprecated but available as backwards-compatible extensions,
as discussed further below. <code>&lt;rope&gt;</code> is the
SGI specialization for large strings (&quot;rope,&quot;
&quot;large strings,&quot; get it? Love that geeky humor.)
<code>&lt;slist&gt;</code> is a singly-linked list, for when the
doubly-linked <code>list&lt;&gt;</code> is too much space
overhead, and <code>&lt;rb_tree&gt;</code> exposes the red-black
tree classes used in the implementation of the standard maps and
sets.
</para>
<para>Each of the associative containers map, multimap, set, and multiset
have a counterpart which uses a
<ulink url="http://www.sgi.com/tech/stl/HashFunction.html">hashing
function</ulink> to do the arranging, instead of a strict weak ordering
function. The classes take as one of their template parameters a
function object that will return the hash value; by default, an
instantiation of
<ulink url="http://www.sgi.com/tech/stl/hash.html">hash</ulink>.
You should specialize this functor for your class, or define your own,
before trying to use one of the hashing classes.
</para>
<para>The hashing classes support all the usual associative container
functions, as well as some extra constructors specifying the number
of buckets, etc.
</para>
<para>Why would you want to use a hashing class instead of the
<quote>normal</quote>implementations? Matt Austern writes:
</para>
<blockquote>
<para>
<emphasis>[W]ith a well chosen hash function, hash tables
generally provide much better average-case performance than
binary search trees, and much worse worst-case performance. So
if your implementation has hash_map, if you don't mind using
nonstandard components, and if you aren't scared about the
possibility of pathological cases, you'll probably get better
performance from hash_map.
</emphasis>
</para>
</blockquote>
</sect1>
</chapter>
<!-- Chapter 06 : Utilities -->
<chapter id="manual.ext.util" xreflabel="Utilities">
<title>Utilities</title>
<para>
The &lt;functional&gt; header contains many additional functors
and helper functions, extending section 20.3. They are
implemented in the file stl_function.h:
</para>
<itemizedlist>
<listitem>
<para><code>identity_element</code> for addition and multiplication. *
</para>
</listitem>
<listitem>
<para>The functor <code>identity</code>, whose <code>operator()</code>
returns the argument unchanged. *
</para>
</listitem>
<listitem>
<para>Composition functors <code>unary_function</code> and
<code>binary_function</code>, and their helpers <code>compose1</code>
and <code>compose2</code>. *
</para>
</listitem>
<listitem>
<para><code>select1st</code> and <code>select2nd</code>, to strip pairs. *
</para>
</listitem>
<listitem><para><code>project1st</code> and <code>project2nd</code>. * </para></listitem>
<listitem><para>A set of functors/functions which always return the same result. They
are <code>constant_void_fun</code>, <code>constant_binary_fun</code>,
<code>constant_unary_fun</code>, <code>constant0</code>,
<code>constant1</code>, and <code>constant2</code>. * </para></listitem>
<listitem><para>The class <code>subtractive_rng</code>. * </para></listitem>
<listitem><para>mem_fun adaptor helpers <code>mem_fun1</code> and
<code>mem_fun1_ref</code> are provided for backwards compatibility. </para></listitem>
</itemizedlist>
<para>
20.4.1 can use several different allocators; they are described on the
main extensions page.
</para>
<para>
20.4.3 is extended with a special version of
<code>get_temporary_buffer</code> taking a second argument. The
argument is a pointer, which is ignored, but can be used to specify
the template type (instead of using explicit function template
arguments like the standard version does). That is, in addition to
</para>
<programlisting>
get_temporary_buffer&lt;int&gt;(5);
</programlisting>
<para>
you can also use
</para>
<programlisting>
get_temporary_buffer(5, (int*)0);
</programlisting>
<para>
A class <code>temporary_buffer</code> is given in stl_tempbuf.h. *
</para>
<para>
The specialized algorithms of section 20.4.4 are extended with
<code>uninitialized_copy_n</code>. *
</para>
</chapter>
<!-- Chapter 07 : Algorithms -->
<chapter id="manual.ext.algorithms" xreflabel="Algorithms">
<title>Algorithms</title>
<para>25.1.6 (count, count_if) is extended with two more versions of count
and count_if. The standard versions return their results. The
additional signatures return void, but take a final parameter by
reference to which they assign their results, e.g.,
</para>
<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>
copy_n (_InputIter first, _Size count, _OutputIter result);</programlisting>
<para>which copies the first 'count' elements at 'first' into 'result'.
</para>
<para>25.3 (sorting 'n' heaps 'n' stuff) is extended with some helper
predicates. Look in the doxygen-generated pages for notes on these.
</para>
<itemizedlist>
<listitem><para><code>is_heap</code> tests whether or not a range is a heap.</para></listitem>
<listitem><para><code>is_sorted</code> tests whether or not a range is sorted in
nondescending order.</para></listitem>
</itemizedlist>
<para>25.3.8 (lexigraphical_compare) is extended with
</para>
<programlisting>
lexicographical_compare_3way(_InputIter1 first1, _InputIter1 last1,
_InputIter2 first2, _InputIter2 last2)</programlisting>
<para>which does... what?
</para>
</chapter>
<!-- Chapter 08 : Numerics -->
<chapter id="manual.ext.numerics" xreflabel="Numerics">
<title>Numerics</title>
<para>26.4, the generalized numeric operations such as accumulate, are extended
with the following functions:
</para>
<programlisting>
power (x, n);
power (x, n, moniod_operation);</programlisting>
<para>Returns, in FORTRAN syntax, &quot;x ** n&quot; where n&gt;=0. In the
case of n == 0, returns the <ulink url="#ch20">identity element</ulink> for the
monoid operation. The two-argument signature uses multiplication (for
a true &quot;power&quot; implementation), but addition is supported as well.
The operation functor must be associative.
</para>
<para>The <code>iota</code> function wins the award for Extension With the
Coolest Name. It &quot;assigns sequentially increasing values to a range.
That is, it assigns value to *first, value + 1 to *(first + 1) and so
on.&quot; Quoted from SGI documentation.
</para>
<programlisting>
void iota(_ForwardIter first, _ForwardIter last, _Tp value);</programlisting>
</chapter>
<!-- Chapter 09 : Iterators -->
<chapter id="manual.ext.iterators" xreflabel="Iterators">
<title>Iterators</title>
<para>24.3.2 describes <code>struct iterator</code>, which didn't exist in the
original HP STL implementation (the language wasn't rich enough at the
time). For backwards compatibility, base classes are provided which
declare the same nested typedefs:
</para>
<itemizedlist>
<listitem><para>input_iterator</para></listitem>
<listitem><para>output_iterator</para></listitem>
<listitem><para>forward_iterator</para></listitem>
<listitem><para>bidirectional_iterator</para></listitem>
<listitem><para>random_access_iterator</para></listitem>
</itemizedlist>
<para>24.3.4 describes iterator operation <code>distance</code>, which takes
two iterators and returns a result. It is extended by another signature
which takes two iterators and a reference to a result. The result is
modified, and the function returns nothing.
</para>
</chapter>
<!-- Chapter 08 : IO -->
<chapter id="manual.ext.io" xreflabel="IO">
<title>Input and Output</title>
<para>
Extensions allowing <code>filebuf</code>s to be constructed from
"C" types like FILE*s and file descriptors.
</para>
<sect1 id="manual.ext.io.filebuf_derived" xreflabel="Derived filebufs">
<title>Derived filebufs</title>
<para>The v2 library included non-standard extensions to construct
<code>std::filebuf</code>s from C stdio types such as
<code>FILE*</code>s and POSIX file descriptors.
Today the recommended way to use stdio types with libstdc++
IOStreams is via the <code>stdio_filebuf</code> class (see below),
but earlier releases provided slightly different mechanisms.
</para>
<itemizedlist>
<listitem><para>3.0.x <code>filebuf</code>s have another ctor with this signature:
<code>basic_filebuf(__c_file_type*, ios_base::openmode, int_type);
</code>
This comes in very handy in a number of places, such as
attaching Unix sockets, pipes, and anything else which uses file
descriptors, into the IOStream buffering classes. The three
arguments are as follows:
<itemizedlist>
<listitem><para><code>__c_file_type* F </code>
// the __c_file_type typedef usually boils down to stdio's FILE
</para></listitem>
<listitem><para><code>ios_base::openmode M </code>
// same as all the other uses of openmode
</para></listitem>
<listitem><para><code>int_type B </code>
// buffer size, defaults to BUFSIZ if not specified
</para></listitem>
</itemizedlist>
For those wanting to use file descriptors instead of FILE*'s, I
invite you to contemplate the mysteries of C's <code>fdopen()</code>.
</para></listitem>
<listitem><para>In library snapshot 3.0.95 and later, <code>filebuf</code>s bring
back an old extension: the <code>fd()</code> member function. The
integer returned from this function can be used for whatever file
descriptors can be used for on your platform. Naturally, the
library cannot track what you do on your own with a file descriptor,
so if you perform any I/O directly, don't expect the library to be
aware of it.
</para></listitem>
<listitem><para>Beginning with 3.1, the extra <code>filebuf</code> constructor and
the <code>fd()</code> function were removed from the standard
filebuf. Instead, <code>&lt;ext/stdio_filebuf.h&gt;</code> contains
a derived class called
<ulink url="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/class____gnu__cxx_1_1stdio__filebuf.html"><code>__gnu_cxx::stdio_filebuf</code></ulink>.
This class can be constructed from a C <code>FILE*</code> or a file
descriptor, and provides the <code>fd()</code> function.
</para></listitem>
</itemizedlist>
<para>If you want to access a <code>filebuf</code>'s file descriptor to
implement file locking (e.g. using the <code>fcntl()</code> system
call) then you might be interested in Henry Suter's
<ulink url="http://suter.home.cern.ch/suter/RWLock.html">RWLock</ulink>
class.
</para>
<para>
</para>
</sect1>
</chapter>
<!-- Chapter 11 : Demangling -->
<chapter id="manual.ext.demangle" xreflabel="Demangling">
<title>Demangling</title>
<para>
Transforming C++ ABI itentifiers (like RTTI symbols) into the
original C++ source identifiers is called
<quote>demangling.</quote>
</para>
<para>
If you have read the <ulink
url="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaceabi.html">source
documentation for <code>namespace abi</code></ulink> then you are
aware of the cross-vendor C++ ABI in use by GCC. One of the
exposed functions is used for demangling,
<code>abi::__cxa_demangle</code>.
</para>
<para>
In programs like <command>c++filt</command>, the linker, and other tools
have the ability to decode C++ ABI names, and now so can you.
</para>
<para>
(The function itself might use different demanglers, but that's the
whole point of abstract interfaces. If we change the implementation,
you won't notice.)
</para>
<para>
Probably the only times you'll be interested in demangling at runtime
are when you're seeing <code>typeid</code> strings in RTTI, or when
you're handling the runtime-support exception classes. For example:
</para>
<programlisting>
#include &lt;exception&gt;
#include &lt;iostream&gt;
#include &lt;cxxabi.h&gt;
struct empty { };
template &lt;typename T, int N&gt;
struct bar { };
int main()
{
int status;
char *realname;
// exception classes not in &lt;stdexcept&gt;, thrown by the implementation
// instead of the user
std::bad_exception e;
realname = abi::__cxa_demangle(e.what(), 0, 0, &amp;status);
std::cout &lt;&lt; e.what() &lt;&lt; "\t=&gt; " &lt;&lt; realname &lt;&lt; "\t: " &lt;&lt; status &lt;&lt; '\n';
free(realname);
// typeid
bar&lt;empty,17&gt; u;
const std::type_info &amp;ti = typeid(u);
realname = abi::__cxa_demangle(ti.name(), 0, 0, &amp;status);
std::cout &lt;&lt; ti.name() &lt;&lt; "\t=&gt; " &lt;&lt; realname &lt;&lt; "\t: " &lt;&lt; status &lt;&lt; '\n';
free(realname);
return 0;
}
</programlisting>
<para>
This prints
</para>
<screen>
<computeroutput>
St13bad_exception =&gt; std::bad_exception : 0
3barI5emptyLi17EE =&gt; bar&lt;empty, 17&gt; : 0
</computeroutput>
</screen>
<para>
The demangler interface is described in the source documentation
linked to above. It is actually written in C, so you don't need to
be writing C++ in order to demangle C++. (That also means we have to
use crummy memory management facilities, so don't forget to free()
the returned char array.)
</para>
</chapter>
<!-- Chapter 12 : Concurrency -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="concurrency.xml">
</xi:include>
</part>

View file

@ -0,0 +1,548 @@
<sect1 id="appendix.porting.internals" xreflabel="internals">
<?dbhtml filename="internals.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
internals
</keyword>
</keywordset>
</sect1info>
<title>Porting to New Hardware or Operating Systems</title>
<para>
</para>
<para>This document explains how to port libstdc++ (the GNU C++ library) to
a new target.
</para>
<para>In order to make the GNU C++ library (libstdc++) work with a new
target, you must edit some configuration files and provide some new
header files. Unless this is done, libstdc++ will use generic
settings which may not be correct for your target; even if they are
correct, they will likely be inefficient.
</para>
<para>Before you get started, make sure that you have a working C library on
your target. The C library need not precisely comply with any
particular standard, but should generally conform to the requirements
imposed by the ANSI/ISO standard.
</para>
<para>In addition, you should try to verify that the C++ compiler generally
works. It is difficult to test the C++ compiler without a working
library, but you should at least try some minimal test cases.
</para>
<para>(Note that what we think of as a "target," the library refers to as
a "host." The comment at the top of <code>configure.ac</code> explains why.)
</para>
<sect2 id="internals.os" xreflabel="internals.os">
<title>Operating System</title>
<para>If you are porting to a new operating system (as opposed to a new chip
using an existing operating system), you will need to create a new
directory in the <code>config/os</code> hierarchy. For example, the IRIX
configuration files are all in <code>config/os/irix</code>. There is no set
way to organize the OS configuration directory. For example,
<code>config/os/solaris/solaris-2.6</code> and
<code>config/os/solaris/solaris-2.7</code> are used as configuration
directories for these two versions of Solaris. On the other hand, both
Solaris 2.7 and Solaris 2.8 use the <code>config/os/solaris/solaris-2.7</code>
directory. The important information is that there needs to be a
directory under <code>config/os</code> to store the files for your operating
system.
</para>
<para>You might have to change the <code>configure.host</code> file to ensure that
your new directory is activated. Look for the switch statement that sets
<code>os_include_dir</code>, and add a pattern to handle your operating system
if the default will not suffice. The switch statement switches on only
the OS portion of the standard target triplet; e.g., the <code>solaris2.8</code>
in <code>sparc-sun-solaris2.8</code>. If the new directory is named after the
OS portion of the triplet (the default), then nothing needs to be changed.
</para>
<para>The first file to create in this directory, should be called
<code>os_defines.h</code>. This file contains basic macro definitions
that are required to allow the C++ library to work with your C library.
</para>
<para>Several libstdc++ source files unconditionally define the macro
<code>_POSIX_SOURCE</code>. On many systems, defining this macro causes
large portions of the C library header files to be eliminated
at preprocessing time. Therefore, you may have to <code>#undef</code> this
macro, or define other macros (like <code>_LARGEFILE_SOURCE</code> or
<code>__EXTENSIONS__</code>). You won't know what macros to define or
undefine at this point; you'll have to try compiling the library and
seeing what goes wrong. If you see errors about calling functions
that have not been declared, look in your C library headers to see if
the functions are declared there, and then figure out what macros you
need to define. You will need to add them to the
<code>CPLUSPLUS_CPP_SPEC</code> macro in the GCC configuration file for your
target. It will not work to simply define these macros in
<code>os_defines.h</code>.
</para>
<para>At this time, there are a few libstdc++-specific macros which may be
defined:
</para>
<para><code>_GLIBCXX_USE_C99_CHECK</code> may be defined to 1 to check C99
function declarations (which are not covered by specialization below)
found in system headers against versions found in the library headers
derived from the standard.
</para>
<para><code>_GLIBCXX_USE_C99_DYNAMIC</code> may be defined to an expression that
yields 0 if and only if the system headers are exposing proper support
for C99 functions (which are not covered by specialization below). If
defined, it must be 0 while bootstrapping the compiler/rebuilding the
library.
</para>
<para><code>_GLIBCXX_USE_C99_LONG_LONG_CHECK</code> may be defined to 1 to check
the set of C99 long long function declarations found in system headers
against versions found in the library headers derived from the
standard.
</para>
<para><code>_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC</code> may be defined to an
expression that yields 0 if and only if the system headers are
exposing proper support for the set of C99 long long functions. If
defined, it must be 0 while bootstrapping the compiler/rebuilding the
library.
</para>
<para><code>_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC</code> may be defined to an
expression that yields 0 if and only if the system headers
are exposing proper support for the related set of macros. If defined,
it must be 0 while bootstrapping the compiler/rebuilding the library.
</para>
<para><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK</code> may be defined
to 1 to check the related set of function declarations found in system
headers against versions found in the library headers derived from
the standard.
</para>
<para><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC</code> may be defined
to an expression that yields 0 if and only if the system headers
are exposing proper support for the related set of functions. If defined,
it must be 0 while bootstrapping the compiler/rebuilding the library.
</para>
<para>Finally, you should bracket the entire file in an include-guard, like
this:
</para>
<programlisting>
#ifndef _GLIBCXX_OS_DEFINES
#define _GLIBCXX_OS_DEFINES
...
#endif
</programlisting>
<para>We recommend copying an existing <code>os_defines.h</code> to use as a
starting point.
</para>
</sect2>
<sect2 id="internals.cpu" xreflabel="internals.cpu">
<title>CPU</title>
<para>If you are porting to a new chip (as opposed to a new operating system
running on an existing chip), you will need to create a new directory in the
<code>config/cpu</code> hierarchy. Much like the <link linkend="internals.os">Operating system</link> setup,
there are no strict rules on how to organize the CPU configuration
directory, but careful naming choices will allow the configury to find your
setup files without explicit help.
</para>
<para>We recommend that for a target triplet <code>&lt;CPU&gt;-&lt;vendor&gt;-&lt;OS&gt;</code>, you
name your configuration directory <code>config/cpu/&lt;CPU&gt;</code>. If you do this,
the configury will find the directory by itself. Otherwise you will need to
edit the <code>configure.host</code> file and, in the switch statement that sets
<code>cpu_include_dir</code>, add a pattern to handle your chip.
</para>
<para>Note that some chip families share a single configuration directory, for
example, <code>alpha</code>, <code>alphaev5</code>, and <code>alphaev6</code> all use the
<code>config/cpu/alpha</code> directory, and there is an entry in the
<code>configure.host</code> switch statement to handle this.
</para>
<para>The <code>cpu_include_dir</code> sets default locations for the files controlling
<link linkend="internals.thread_safety">Thread safety</link> and <link linkend="internals.numeric_limits">Numeric limits</link>, if the defaults are not
appropriate for your chip.
</para>
</sect2>
<sect2 id="internals.char_types" xreflabel="internals.char_types">
<title>Character Types</title>
<para>The library requires that you provide three header files to implement
character classification, analogous to that provided by the C libraries
<code>&lt;ctype.h&gt;</code> header. You can model these on the files provided in
<code>config/os/generic</code>. However, these files will almost
certainly need some modification.
</para>
<para>The first file to write is <code>ctype_base.h</code>. This file provides
some very basic information about character classification. The libstdc++
library assumes that your C library implements <code>&lt;ctype.h&gt;</code> by using
a table (indexed by character code) containing integers, where each of
these integers is a bit-mask indicating whether the character is
upper-case, lower-case, alphabetic, etc. The <code>ctype_base.h</code>
file gives the type of the integer, and the values of the various bit
masks. You will have to peer at your own <code>&lt;ctype.h&gt;</code> to figure out
how to define the values required by this file.
</para>
<para>The <code>ctype_base.h</code> header file does not need include guards.
It should contain a single <code>struct</code> definition called
<code>ctype_base</code>. This <code>struct</code> should contain two type
declarations, and one enumeration declaration, like this example, taken
from the IRIX configuration:
</para>
<programlisting>
struct ctype_base
{
typedef unsigned int mask;
typedef int* __to_type;
enum
{
space = _ISspace,
print = _ISprint,
cntrl = _IScntrl,
upper = _ISupper,
lower = _ISlower,
alpha = _ISalpha,
digit = _ISdigit,
punct = _ISpunct,
xdigit = _ISxdigit,
alnum = _ISalnum,
graph = _ISgraph
};
};
</programlisting>
<para>The <code>mask</code> type is the type of the elements in the table. If your
C library uses a table to map lower-case numbers to upper-case numbers,
and vice versa, you should define <code>__to_type</code> to be the type of the
elements in that table. If you don't mind taking a minor performance
penalty, or if your library doesn't implement <code>toupper</code> and
<code>tolower</code> in this way, you can pick any pointer-to-integer type,
but you must still define the type.
</para>
<para>The enumeration should give definitions for all the values in the above
example, using the values from your native <code>&lt;ctype.h&gt;</code>. They can
be given symbolically (as above), or numerically, if you prefer. You do
not have to include <code>&lt;ctype.h&gt;</code> in this header; it will always be
included before <code>ctype_base.h</code> is included.
</para>
<para>The next file to write is <code>ctype_noninline.h</code>, which also does
not require include guards. This file defines a few member functions
that will be included in <code>include/bits/locale_facets.h</code>. The first
function that must be written is the <code>ctype&lt;char&gt;::ctype</code>
constructor. Here is the IRIX example:
</para>
<programlisting>
ctype&lt;char&gt;::ctype(const mask* __table = 0, bool __del = false,
size_t __refs = 0)
: _Ctype_nois&lt;char&gt;(__refs), _M_del(__table != 0 &amp;&amp; __del),
_M_toupper(NULL),
_M_tolower(NULL),
_M_ctable(NULL),
_M_table(!__table
? (const mask*) (__libc_attr._ctype_tbl-&gt;_class + 1)
: __table)
{ }
</programlisting>
<para>There are two parts of this that you might choose to alter. The first,
and most important, is the line involving <code>__libc_attr</code>. That is
IRIX system-dependent code that gets the base of the table mapping
character codes to attributes. You need to substitute code that obtains
the address of this table on your system. If you want to use your
operating system's tables to map upper-case letters to lower-case, and
vice versa, you should initialize <code>_M_toupper</code> and
<code>_M_tolower</code> with those tables, in similar fashion.
</para>
<para>Now, you have to write two functions to convert from upper-case to
lower-case, and vice versa. Here are the IRIX versions:
</para>
<programlisting>
char
ctype&lt;char&gt;::do_toupper(char __c) const
{ return _toupper(__c); }
char
ctype&lt;char&gt;::do_tolower(char __c) const
{ return _tolower(__c); }
</programlisting>
<para>Your C library provides equivalents to IRIX's <code>_toupper</code> and
<code>_tolower</code>. If you initialized <code>_M_toupper</code> and
<code>_M_tolower</code> above, then you could use those tables instead.
</para>
<para>Finally, you have to provide two utility functions that convert strings
of characters. The versions provided here will always work - but you
could use specialized routines for greater performance if you have
machinery to do that on your system:
</para>
<programlisting>
const char*
ctype&lt;char&gt;::do_toupper(char* __low, const char* __high) const
{
while (__low &lt; __high)
{
*__low = do_toupper(*__low);
++__low;
}
return __high;
}
const char*
ctype&lt;char&gt;::do_tolower(char* __low, const char* __high) const
{
while (__low &lt; __high)
{
*__low = do_tolower(*__low);
++__low;
}
return __high;
}
</programlisting>
<para>You must also provide the <code>ctype_inline.h</code> file, which
contains a few more functions. On most systems, you can just copy
<code>config/os/generic/ctype_inline.h</code> and use it on your system.
</para>
<para>In detail, the functions provided test characters for particular
properties; they are analogous to the functions like <code>isalpha</code> and
<code>islower</code> provided by the C library.
</para>
<para>The first function is implemented like this on IRIX:
</para>
<programlisting>
bool
ctype&lt;char&gt;::
is(mask __m, char __c) const throw()
{ return (_M_table)[(unsigned char)(__c)] &amp; __m; }
</programlisting>
<para>The <code>_M_table</code> is the table passed in above, in the constructor.
This is the table that contains the bitmasks for each character. The
implementation here should work on all systems.
</para>
<para>The next function is:
</para>
<programlisting>
const char*
ctype&lt;char&gt;::
is(const char* __low, const char* __high, mask* __vec) const throw()
{
while (__low &lt; __high)
*__vec++ = (_M_table)[(unsigned char)(*__low++)];
return __high;
}
</programlisting>
<para>This function is similar; it copies the masks for all the characters
from <code>__low</code> up until <code>__high</code> into the vector given by
<code>__vec</code>.
</para>
<para>The last two functions again are entirely generic:
</para>
<programlisting>
const char*
ctype&lt;char&gt;::
scan_is(mask __m, const char* __low, const char* __high) const throw()
{
while (__low &lt; __high &amp;&amp; !this-&gt;is(__m, *__low))
++__low;
return __low;
}
const char*
ctype&lt;char&gt;::
scan_not(mask __m, const char* __low, const char* __high) const throw()
{
while (__low &lt; __high &amp;&amp; this-&gt;is(__m, *__low))
++__low;
return __low;
}
</programlisting>
</sect2>
<sect2 id="internals.thread_safety" xreflabel="internals.thread_safety">
<title>Thread Safety</title>
<para>The C++ library string functionality requires a couple of atomic
operations to provide thread-safety. If you don't take any special
action, the library will use stub versions of these functions that are
not thread-safe. They will work fine, unless your applications are
multi-threaded.
</para>
<para>If you want to provide custom, safe, versions of these functions, there
are two distinct approaches. One is to provide a version for your CPU,
using assembly language constructs. The other is to use the
thread-safety primitives in your operating system. In either case, you
make a file called <code>atomicity.h</code>, and the variable
<code>ATOMICITYH</code> must point to this file.
</para>
<para>If you are using the assembly-language approach, put this code in
<code>config/cpu/&lt;chip&gt;/atomicity.h</code>, where chip is the name of
your processor (see <link linkend="internals.cpu">CPU</link>). No additional changes are necessary to
locate the file in this case; <code>ATOMICITYH</code> will be set by default.
</para>
<para>If you are using the operating system thread-safety primitives approach,
you can also put this code in the same CPU directory, in which case no more
work is needed to locate the file. For examples of this approach,
see the <code>atomicity.h</code> file for IRIX or IA64.
</para>
<para>Alternatively, if the primitives are more closely related to the OS
than they are to the CPU, you can put the <code>atomicity.h</code> file in
the <link linkend="internals.os">Operating system</link> directory instead. In this case, you must
edit <code>configure.host</code>, and in the switch statement that handles
operating systems, override the <code>ATOMICITYH</code> variable to point to
the appropriate <code>os_include_dir</code>. For examples of this approach,
see the <code>atomicity.h</code> file for AIX.
</para>
<para>With those bits out of the way, you have to actually write
<code>atomicity.h</code> itself. This file should be wrapped in an
include guard named <code>_GLIBCXX_ATOMICITY_H</code>. It should define one
type, and two functions.
</para>
<para>The type is <code>_Atomic_word</code>. Here is the version used on IRIX:
</para>
<programlisting>
typedef long _Atomic_word;
</programlisting>
<para>This type must be a signed integral type supporting atomic operations.
If you're using the OS approach, use the same type used by your system's
primitives. Otherwise, use the type for which your CPU provides atomic
primitives.
</para>
<para>Then, you must provide two functions. The bodies of these functions
must be equivalent to those provided here, but using atomic operations:
</para>
<programlisting>
static inline _Atomic_word
__attribute__ ((__unused__))
__exchange_and_add (_Atomic_word* __mem, int __val)
{
_Atomic_word __result = *__mem;
*__mem += __val;
return __result;
}
static inline void
__attribute__ ((__unused__))
__atomic_add (_Atomic_word* __mem, int __val)
{
*__mem += __val;
}
</programlisting>
</sect2>
<sect2 id="internals.numeric_limits" xreflabel="internals.numeric_limits">
<title>Numeric Limits</title>
<para>The C++ library requires information about the fundamental data types,
such as the minimum and maximum representable values of each type.
You can define each of these values individually, but it is usually
easiest just to indicate how many bits are used in each of the data
types and let the library do the rest. For information about the
macros to define, see the top of <code>include/bits/std_limits.h</code>.
</para>
<para>If you need to define any macros, you can do so in <code>os_defines.h</code>.
However, if all operating systems for your CPU are likely to use the
same values, you can provide a CPU-specific file instead so that you
do not have to provide the same definitions for each operating system.
To take that approach, create a new file called <code>cpu_limits.h</code> in
your CPU configuration directory (see <link linkend="internals.cpu">CPU</link>).
</para>
</sect2>
<sect2 id="internals.libtool" xreflabel="internals.libtool">
<title>Libtool</title>
<para>The C++ library is compiled, archived and linked with libtool.
Explaining the full workings of libtool is beyond the scope of this
document, but there are a few, particular bits that are necessary for
porting.
</para>
<para>Some parts of the libstdc++ library are compiled with the libtool
<code>--tags CXX</code> option (the C++ definitions for libtool). Therefore,
<code>ltcf-cxx.sh</code> in the top-level directory needs to have the correct
logic to compile and archive objects equivalent to the C version of libtool,
<code>ltcf-c.sh</code>. Some libtool targets have definitions for C but not
for C++, or C++ definitions which have not been kept up to date.
</para>
<para>The C++ run-time library contains initialization code that needs to be
run as the library is loaded. Often, that requires linking in special
object files when the C++ library is built as a shared library, or
taking other system-specific actions.
</para>
<para>The libstdc++ library is linked with the C version of libtool, even
though it is a C++ library. Therefore, the C version of libtool needs to
ensure that the run-time library initializers are run. The usual way to
do this is to build the library using <code>gcc -shared</code>.
</para>
<para>If you need to change how the library is linked, look at
<code>ltcf-c.sh</code> in the top-level directory. Find the switch statement
that sets <code>archive_cmds</code>. Here, adjust the setting for your
operating system.
</para>
</sect2>
</sect1>

View file

@ -0,0 +1,664 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.intro" xreflabel="Introduction">
<?dbhtml filename="intro.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Introduction</title>
<!-- Chapter 01 : Status -->
<chapter id="manual.intro.status" xreflabel="Status">
<title>Status</title>
<sect1 id="manual.intro.status.standard" xreflabel="Implementation Status">
<title>Implementation Status</title>
<!-- Section 01 : Status C++ 1998 -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="status_cxx1998.xml">
</xi:include>
<!-- Section 02 : Status C++ TR1 -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="status_cxxtr1.xml">
</xi:include>
<!-- Section 03 : Status C++ 200x -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="status_cxx200x.xml">
</xi:include>
</sect1>
<!-- Section 02 : License -->
<sect1 id="manual.intro.status.license" xreflabel="License">
<title>License</title>
<para>
There are two licenses affecting GNU libstdc++: one for the code,
and one for the documentation.
</para>
<para>
There is a license section in the FAQ regarding common <link
linkend="faq.license">questions</link>. If you have more
questions, ask the FSF or the <ulink
url="http://gcc.gnu.org/lists.html">gcc mailing list</ulink>.
</para>
<sect2 id="manual.intro.status.license.gpl" xreflabel="License GPL">
<title>The Code: GPL</title>
<para>
The source code is distributed under the <link
linkend="appendix.gpl-2.0">GNU General Public License version 2</link>,
with the so-called <quote>Runtime Exception</quote>
as follows (or see any header or implementation file):
</para>
<literallayout>
As a special exception, you may use this file as part of a free software
library without restriction. Specifically, if other files instantiate
templates or use macros or inline functions from this file, or you compile
this file and link it with other files to produce an executable, this
file does not by itself cause the resulting executable to be covered by
the GNU General Public License. This exception does not however
invalidate any other reasons why the executable file might be covered by
the GNU General Public License.
</literallayout>
<para>
Hopefully that text is self-explanatory. If it isn't, you need to speak
to your lawyer, or the Free Software Foundation.
</para>
</sect2>
<sect2 id="manual.intro.status.license.fdl" xreflabel="License FDL">
<title>The Documentation: GPL, FDL</title>
<para>
The documentation shipped with the library and made available over
the web, excluding the pages generated from source comments, are
copyrighted by the Free Software Foundation, and placed under the
<link linkend="appendix.gfdl-1.2"> GNU Free Documentation
License version 1.2</link>. There are no Front-Cover Texts, no
Back-Cover Texts, and no Invariant Sections.
</para>
<para>
For documentation generated by doxygen or other automated tools
via processing source code comments and markup, the original source
code license applies to the generated files. Thus, the doxygen
documents are licensed <link linkend="appendix.gpl-2.0">GPL</link>.
</para>
<para>
If you plan on making copies of the documentation, please let us know.
We can probably offer suggestions.
</para>
</sect2>
</sect1>
<!-- Section 03 : Known Bugs -->
<sect1 id="manual.intro.status.bugs" xreflabel="Bugs">
<title>Bugs</title>
<sect2 id="manual.intro.status.bugs.impl" xreflabel="Bugs impl">
<title>Implementation Bugs</title>
<para>
Information on known bugs, details on efforts to fix them, and
fixed bugs are all available as part of the GCC bug tracking
system, <ulink
url="http://gcc.gnu.org/bugzilla">bugzilla</ulink>, with the
category set to <literal>libstdc++</literal>.
</para>
</sect2>
<sect2 id="manual.intro.status.bugs.iso" xreflabel="Bugs iso">
<title>Standard Bugs</title>
<para>
Everybody's got issues. Even the C++ Standard Library.
</para>
<para>
The Library Working Group, or LWG, is the ISO subcommittee responsible
for making changes to the library. They periodically publish an
Issues List containing problems and possible solutions. As they reach
a consensus on proposed solutions, we often incorporate the solution.
</para>
<para>
Here are the issues which have resulted in code changes to the library.
The links are to the specific defect reports from a <emphasis>partial
copy</emphasis> of the Issues List. You can read the full version online
at the <ulink url="http://www.open-std.org/jtc1/sc22/wg21/">ISO C++
Committee homepage</ulink>, linked to on the
<ulink url="http://gcc.gnu.org/readings.html">GCC &quot;Readings&quot;
page</ulink>. If
you spend a lot of time reading the issues, we recommend downloading
the ZIP file and reading them locally.
</para>
<para>
(NB: <emphasis>partial copy</emphasis> means that not all
links within the lwg-*.html pages will work. Specifically,
links to defect reports that have not been accorded full DR
status will probably break. Rather than trying to mirror the
entire issues list on our overworked web server, we recommend
you go to the LWG homepage instead.)
</para>
<para>
If a DR is not listed here, we may simply not have gotten to
it yet; feel free to submit a patch. Search the include/bits
and src directories for appearances of
<constant>_GLIBCXX_RESOLVE_LIB_DEFECTS</constant> for examples
of style. Note that we usually do not make changes to the
code until an issue has reached <ulink url="lwg-active.html#DR">DR</ulink> status.
</para>
<variablelist>
<varlistentry><term><ulink url="lwg-defects.html#5">5</ulink>:
<emphasis>string::compare specification questionable</emphasis>
</term>
<listitem><para>This should be two overloaded functions rather than a single function.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#17">17</ulink>:
<emphasis>Bad bool parsing</emphasis>
</term>
<listitem><para>Apparently extracting Boolean values was messed up...
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#19">19</ulink>:
<emphasis>&quot;Noconv&quot; definition too vague</emphasis>
</term>
<listitem><para>If <code>codecvt::do_in</code> returns <code>noconv</code> there are
no changes to the values in <code>[to, to_limit)</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#22">22</ulink>:
<emphasis>Member open vs flags</emphasis>
</term>
<listitem><para>Re-opening a file stream does <emphasis>not</emphasis> clear the state flags.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#25">25</ulink>:
<emphasis>String operator&lt;&lt; uses width() value wrong</emphasis>
</term>
<listitem><para>Padding issues.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#48">48</ulink>:
<emphasis>Use of non-existent exception constructor</emphasis>
</term>
<listitem><para>An instance of <code>ios_base::failure</code> is constructed instead.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#49">49</ulink>:
<emphasis>Underspecification of ios_base::sync_with_stdio</emphasis>
</term>
<listitem><para>The return type is the <emphasis>previous</emphasis> state of synchronization.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#50">50</ulink>:
<emphasis>Copy constructor and assignment operator of ios_base</emphasis>
</term>
<listitem><para>These members functions are declared <code>private</code> and are
thus inaccessible. Specifying the correct semantics of
&quot;copying stream state&quot; was deemed too complicated.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#60">60</ulink>:
<emphasis>What is a formatted input function?</emphasis>
</term>
<listitem><para>This DR made many widespread changes to <code>basic_istream</code>
and <code>basic_ostream</code> all of which have been implemented.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#63">63</ulink>:
<emphasis>Exception-handling policy for unformatted output</emphasis>
</term>
<listitem><para>Make the policy consistent with that of formatted input, unformatted
input, and formatted output.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#68">68</ulink>:
<emphasis>Extractors for char* should store null at end</emphasis>
</term>
<listitem><para>And they do now. An editing glitch in the last item in the list of
[27.6.1.2.3]/7.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#74">74</ulink>:
<emphasis>Garbled text for codecvt::do_max_length</emphasis>
</term>
<listitem><para>The text of the standard was gibberish. Typos gone rampant.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#75">75</ulink>:
<emphasis>Contradiction in codecvt::length's argument types</emphasis>
</term>
<listitem><para>Change the first parameter to <code>stateT&amp;</code> and implement
the new effects paragraph.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#83">83</ulink>:
<emphasis>string::npos vs. string::max_size()</emphasis>
</term>
<listitem><para>Safety checks on the size of the string should test against
<code>max_size()</code> rather than <code>npos</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#90">90</ulink>:
<emphasis>Incorrect description of operator&gt;&gt; for strings</emphasis>
</term>
<listitem><para>The effect contain <code>isspace(c,getloc())</code> which must be
replaced by <code>isspace(c,is.getloc())</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#91">91</ulink>:
<emphasis>Description of operator&gt;&gt; and getline() for string&lt;&gt;
might cause endless loop</emphasis>
</term>
<listitem><para>They behave as a formatted input function and as an unformatted
input function, respectively (except that <code>getline</code> is
not required to set <code>gcount</code>).
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#103">103</ulink>:
<emphasis>set::iterator is required to be modifiable, but this allows
modification of keys.</emphasis>
</term>
<listitem><para>For associative containers where the value type is the same as
the key type, both <code>iterator</code> and <code>const_iterator
</code> are constant iterators.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#109">109</ulink>:
<emphasis>Missing binders for non-const sequence elements</emphasis>
</term>
<listitem><para>The <code>binder1st</code> and <code>binder2nd</code> didn't have an
<code>operator()</code> taking a non-const parameter.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#110">110</ulink>:
<emphasis>istreambuf_iterator::equal not const</emphasis>
</term>
<listitem><para>This was not a const member function. Note that the DR says to
replace the function with a const one; we have instead provided an
overloaded version with identical contents.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#117">117</ulink>:
<emphasis>basic_ostream uses nonexistent num_put member functions</emphasis>
</term>
<listitem><para><code>num_put::put()</code> was overloaded on the wrong types.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#118">118</ulink>:
<emphasis>basic_istream uses nonexistent num_get member functions</emphasis>
</term>
<listitem><para>Same as 117, but for <code>num_get::get()</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#129">129</ulink>:
<emphasis>Need error indication from seekp() and seekg()</emphasis>
</term>
<listitem><para>These functions set <code>failbit</code> on error now.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#136">136</ulink>:
<emphasis>seekp, seekg setting wrong streams?</emphasis>
</term>
<listitem><para><code>seekp</code> should only set the output stream, and
<code>seekg</code> should only set the input stream.
</para></listitem></varlistentry>
<!--<varlistentry><term><ulink url="lwg-defects.html#159">159</ulink>:
<emphasis>Strange use of underflow()</emphasis>
</term>
<listitem><para>In fstream.tcc, the basic_filebuf&lt;&gt;::showmanyc() function
should probably not be calling <code>underflow()</code>.
</para></listitem></varlistentry> -->
<varlistentry><term><ulink url="lwg-defects.html#167">167</ulink>:
<emphasis>Improper use of traits_type::length()</emphasis>
</term>
<listitem><para><code>op&lt;&lt;</code> with a <code>const char*</code> was
calculating an incorrect number of characters to write.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#169">169</ulink>:
<emphasis>Bad efficiency of overflow() mandated</emphasis>
</term>
<listitem><para>Grow efficiently the internal array object.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#171">171</ulink>:
<emphasis>Strange seekpos() semantics due to joint position</emphasis>
</term>
<listitem><para>Quite complex to summarize...
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#181">181</ulink>:
<emphasis>make_pair() unintended behavior</emphasis>
</term>
<listitem><para>This function used to take its arguments as reference-to-const, now
it copies them (pass by value).
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#195">195</ulink>:
<emphasis>Should basic_istream::sentry's constructor ever set eofbit?</emphasis>
</term>
<listitem><para>Yes, it can, specifically if EOF is reached while skipping whitespace.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#211">211</ulink>:
<emphasis>operator&gt;&gt;(istream&amp;, string&amp;) doesn't set failbit</emphasis>
</term>
<listitem><para>If nothing is extracted into the string, <code>op&gt;&gt;</code> now
sets <code>failbit</code> (which can cause an exception, etc., etc.).
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#214">214</ulink>:
<emphasis>set::find() missing const overload</emphasis>
</term>
<listitem><para>Both <code>set</code> and <code>multiset</code> were missing
overloaded find, lower_bound, upper_bound, and equal_range functions
for const instances.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#231">231</ulink>:
<emphasis>Precision in iostream?</emphasis>
</term>
<listitem><para>For conversion from a floating-point type, <code>str.precision()</code>
is specified in the conversion specification.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-active.html#233">233</ulink>:
<emphasis>Insertion hints in associative containers</emphasis>
</term>
<listitem><para>Implement N1780, first check before then check after, insert as close
to hint as possible.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#235">235</ulink>:
<emphasis>No specification of default ctor for reverse_iterator</emphasis>
</term>
<listitem><para>The declaration of <code>reverse_iterator</code> lists a default constructor.
However, no specification is given what this constructor should do.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#241">241</ulink>:
<emphasis>Does unique_copy() require CopyConstructible and Assignable?</emphasis>
</term>
<listitem><para>Add a helper for forward_iterator/output_iterator, fix the existing
one for input_iterator/output_iterator to not rely on Assignability.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#243">243</ulink>:
<emphasis>get and getline when sentry reports failure</emphasis>
</term>
<listitem><para>Store a null character only if the character array has a non-zero size.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#251">251</ulink>:
<emphasis>basic_stringbuf missing allocator_type</emphasis>
</term>
<listitem><para>This nested typedef was originally not specified.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#253">253</ulink>:
<emphasis>valarray helper functions are almost entirely useless</emphasis>
</term>
<listitem><para>Make the copy constructor and copy-assignment operator declarations
public in gslice_array, indirect_array, mask_array, slice_array; provide
definitions.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#265">265</ulink>:
<emphasis>std::pair::pair() effects overly restrictive</emphasis>
</term>
<listitem><para>The default ctor would build its members from copies of temporaries;
now it simply uses their respective default ctors.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#266">266</ulink>:
<emphasis>bad_exception::~bad_exception() missing Effects clause</emphasis>
</term>
<listitem><para>The <code>bad_</code>* classes no longer have destructors (they
are trivial), since no description of them was ever given.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#271">271</ulink>:
<emphasis>basic_iostream missing typedefs</emphasis>
</term>
<listitem><para>The typedefs it inherits from its base classes can't be used, since
(for example) <code>basic_iostream&lt;T&gt;::traits_type</code> is ambiguous.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#275">275</ulink>:
<emphasis>Wrong type in num_get::get() overloads</emphasis>
</term>
<listitem><para>Similar to 118.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#280">280</ulink>:
<emphasis>Comparison of reverse_iterator to const reverse_iterator</emphasis>
</term>
<listitem><para>Add global functions with two template parameters.
(NB: not added for now a templated assignment operator)
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#292">292</ulink>:
<emphasis>Effects of a.copyfmt (a)</emphasis>
</term>
<listitem><para>If <code>(this == &amp;rhs)</code> do nothing.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#300">300</ulink>:
<emphasis>List::merge() specification incomplete</emphasis>
</term>
<listitem><para>If <code>(this == &amp;x)</code> do nothing.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#303">303</ulink>:
<emphasis>Bitset input operator underspecified</emphasis>
</term>
<listitem><para>Basically, compare the input character to <code>is.widen(0)</code>
and <code>is.widen(1)</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#305">305</ulink>:
<emphasis>Default behavior of codecvt&lt;wchar_t, char, mbstate_t&gt;::length()</emphasis>
</term>
<listitem><para>Do not specify what <code>codecvt&lt;wchar_t, char, mbstate_t&gt;::do_length</code>
must return.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#328">328</ulink>:
<emphasis>Bad sprintf format modifier in money_put&lt;&gt;::do_put()</emphasis>
</term>
<listitem><para>Change the format string to &quot;%.0Lf&quot;.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#365">365</ulink>:
<emphasis>Lack of const-qualification in clause 27</emphasis>
</term>
<listitem><para>Add const overloads of <code>is_open</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#389">389</ulink>:
<emphasis>Const overload of valarray::operator[] returns by value</emphasis>
</term>
<listitem><para>Change it to return a <code>const T&amp;</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#402">402</ulink>:
<emphasis>Wrong new expression in [some_]allocator::construct</emphasis>
</term>
<listitem><para>Replace &quot;new&quot; with &quot;::new&quot;.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#409">409</ulink>:
<emphasis>Closing an fstream should clear the error state</emphasis>
</term>
<listitem><para>Have <code>open</code> clear the error flags.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-active.html#431">431</ulink>:
<emphasis>Swapping containers with unequal allocators</emphasis>
</term>
<listitem><para>Implement Option 3, as per N1599.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#432">432</ulink>:
<emphasis>stringbuf::overflow() makes only one write position
available</emphasis>
</term>
<listitem><para>Implement the resolution, beyond DR 169.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#434">434</ulink>:
<emphasis>bitset::to_string() hard to use</emphasis>
</term>
<listitem><para>Add three overloads, taking fewer template arguments.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#438">438</ulink>:
<emphasis>Ambiguity in the "do the right thing" clause</emphasis>
</term>
<listitem><para>Implement the resolution, basically cast less.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#453">453</ulink>:
<emphasis>basic_stringbuf::seekoff need not always fail for an empty stream</emphasis>
</term>
<listitem><para>Don't fail if the next pointer is null and newoff is zero.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#455">455</ulink>:
<emphasis>cerr::tie() and wcerr::tie() are overspecified</emphasis>
</term>
<listitem><para>Initialize cerr tied to cout and wcerr tied to wcout.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#464">464</ulink>:
<emphasis>Suggestion for new member functions in standard containers</emphasis>
</term>
<listitem><para>Add <code>data()</code> to <code>std::vector</code> and
<code>at(const key_type&amp;)</code> to <code>std::map</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#508">508</ulink>:
<emphasis>Bad parameters for ranlux64_base_01</emphasis>
</term>
<listitem><para>Fix the parameters.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-closed.html#512">512</ulink>:
<emphasis>Seeding subtract_with_carry_01 from a single unsigned long</emphasis>
</term>
<listitem><para>Construct a <code>linear_congruential</code> engine and seed with it.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-closed.html#526">526</ulink>:
<emphasis>Is it undefined if a function in the standard changes in
parameters?</emphasis>
</term>
<listitem><para>Use &amp;value.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#538">538</ulink>:
<emphasis>241 again: Does unique_copy() require CopyConstructible
and Assignable?</emphasis>
</term>
<listitem><para>In case of input_iterator/output_iterator rely on Assignability of
input_iterator' value_type.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#541">541</ulink>:
<emphasis>shared_ptr template assignment and void</emphasis>
</term>
<listitem><para>Add an auto_ptr&lt;void&gt; specialization.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#543">543</ulink>:
<emphasis>valarray slice default constructor</emphasis>
</term>
<listitem><para>Follow the straightforward proposed resolution.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#586">586</ulink>:
<emphasis>string inserter not a formatted function</emphasis>
</term>
<listitem><para>Change it to be a formatted output function (i.e. catch exceptions).
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-active.html#596">596</ulink>:
<emphasis>27.8.1.3 Table 112 omits "a+" and "a+b" modes</emphasis>
</term>
<listitem><para>Add the missing modes to fopen_mode.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-defects.html#660">660</ulink>:
<emphasis>Missing bitwise operations</emphasis>
</term>
<listitem><para>Add the missing operations.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-active.html#693">693</ulink>:
<emphasis>std::bitset::all() missing</emphasis>
</term>
<listitem><para>Add it, consistently with the discussion.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="lwg-active.html#695">695</ulink>:
<emphasis>ctype&lt;char&gt;::classic_table() not accessible</emphasis>
</term>
<listitem><para>Make the member functions table and classic_table public.
</para></listitem></varlistentry>
</variablelist>
</sect2>
</sect1>
</chapter>
<!-- Chapter 02 : Setup -->
<chapter id="manual.intro.setup" xreflabel="Setup">
<title>Setup</title>
<!-- Section 01 : Configure -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="configure.xml">
</xi:include>
<!-- Section 02 : Build -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="build.xml">
</xi:include>
<!-- Section 03 : Test -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="test.xml">
</xi:include>
</chapter>
<!-- Chapter 03 : Using -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="using.xml">
</xi:include>
</part>

View file

@ -0,0 +1,665 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.io" xreflabel="Input and Output">
<?dbhtml filename="io.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Input and Output</title>
<!-- Chapter 01 : Iostream Objects -->
<chapter id="manual.io.objects" xreflabel="IO Objects">
<title>Iostream Objects</title>
<para>To minimize the time you have to wait on the compiler, it's good to
only include the headers you really need. Many people simply include
&lt;iostream&gt; when they don't need to -- and that can <emphasis>penalize
your runtime as well.</emphasis> Here are some tips on which header to use
for which situations, starting with the simplest.
</para>
<para><emphasis>&lt;iosfwd&gt;</emphasis> should be included whenever you simply
need the <emphasis>name</emphasis> of an I/O-related class, such as
&quot;ofstream&quot; or &quot;basic_streambuf&quot;. Like the name
implies, these are forward declarations. (A word to all you fellow
old school programmers: trying to forward declare classes like
&quot;class istream;&quot; won't work. Look in the iosfwd header if
you'd like to know why.) For example,
</para>
<programlisting>
#include &lt;iosfwd&gt;
class MyClass
{
....
std::ifstream&amp; input_file;
};
extern std::ostream&amp; operator&lt;&lt; (std::ostream&amp;, MyClass&amp;);
</programlisting>
<para><emphasis>&lt;ios&gt;</emphasis> declares the base classes for the entire
I/O stream hierarchy, std::ios_base and std::basic_ios&lt;charT&gt;, the
counting types std::streamoff and std::streamsize, the file
positioning type std::fpos, and the various manipulators like
std::hex, std::fixed, std::noshowbase, and so forth.
</para>
<para>The ios_base class is what holds the format flags, the state flags,
and the functions which change them (setf(), width(), precision(),
etc). You can also store extra data and register callback functions
through ios_base, but that has been historically underused. Anything
which doesn't depend on the type of characters stored is consolidated
here.
</para>
<para>The template class basic_ios is the highest template class in the
hierarchy; it is the first one depending on the character type, and
holds all general state associated with that type: the pointer to the
polymorphic stream buffer, the facet information, etc.
</para>
<para><emphasis>&lt;streambuf&gt;</emphasis> declares the template class
basic_streambuf, and two standard instantiations, streambuf and
wstreambuf. If you need to work with the vastly useful and capable
stream buffer classes, e.g., to create a new form of storage
transport, this header is the one to include.
</para>
<para><emphasis>&lt;istream&gt;</emphasis>/<emphasis>&lt;ostream&gt;</emphasis> are
the headers to include when you are using the &gt;&gt;/&lt;&lt;
interface, or any of the other abstract stream formatting functions.
For example,
</para>
<programlisting>
#include &lt;istream&gt;
std::ostream&amp; operator&lt;&lt; (std::ostream&amp; os, MyClass&amp; c)
{
return os &lt;&lt; c.data1() &lt;&lt; c.data2();
}
</programlisting>
<para>The std::istream and std::ostream 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.
</para>
<para><emphasis>&lt;iomanip&gt;</emphasis> provides &quot;extractors and inserters
that alter information maintained by class ios_base and its derived
classes,&quot; such as std::setprecision and std::setw. If you need
to write expressions like <code>os &lt;&lt; setw(3);</code> or
<code>is &gt;&gt; setbase(8);</code>, you must include &lt;iomanip&gt;.
</para>
<para><emphasis>&lt;sstream&gt;</emphasis>/<emphasis>&lt;fstream&gt;</emphasis>
declare the six stringstream and fstream classes. As they are the
standard concrete descendants of istream and ostream, you will already
know about them.
</para>
<para>Finally, <emphasis>&lt;iostream&gt;</emphasis> provides the eight standard
global objects (cin, cout, etc). To do this correctly, this header
also provides the contents of the &lt;istream&gt; and &lt;ostream&gt;
headers, but nothing else. The contents of this header look like
</para>
<programlisting>
#include &lt;ostream&gt;
#include &lt;istream&gt;
namespace std
{
extern istream cin;
extern ostream cout;
....
// this is explained below
<emphasis>static ios_base::Init __foo;</emphasis> // not its real name
}
</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
be initialized once and only once. This is typically done with a
construct like the one above, and the nested class ios_base::Init is
specified in the standard for just this reason.
</para>
<para>How does it work? Because the header is included before any of your
code, the <emphasis>__foo</emphasis> object is constructed before any of
your objects. (Global objects are built in the order in which they
are declared, and destroyed in reverse order.) The first time the
constructor runs, the eight stream objects are set up.
</para>
<para>The <code>static</code> keyword means that each object file compiled
from a source file containing &lt;iostream&gt; will have its own
private copy of <emphasis>__foo</emphasis>. There is no specified order
of construction across object files (it's one of those pesky NP
problems that make life so interesting), so one copy in each object
file means that the stream objects are guaranteed to be set up before
any of your code which uses them could run, thereby meeting the
requirements of the standard.
</para>
<para>The penalty, of course, is that after the first copy of
<emphasis>__foo</emphasis> is constructed, all the others are just wasted
processor time. The time spent is merely for an increment-and-test
inside a function call, but over several dozen or hundreds of object
files, that time can add up. (It's not in a tight loop, either.)
</para>
<para>The lesson? Only include &lt;iostream&gt; when you need to use one of
the standard objects in that source file; you'll pay less startup
time. Only include the header files you need to in general; your
compile times will go down when there's less parsing work to do.
</para>
</chapter>
<!-- Chapter 02 : Stream Buffers -->
<chapter id="manual.io.streambufs" xreflabel="Stream Buffers">
<title>Stream Buffers</title>
<sect1 id="io.streambuf.derived" xreflabel="Derived streambuf Classes">
<title>Derived streambuf Classes</title>
<para>
</para>
<para>Creating your own stream buffers for I/O can be remarkably easy.
If you are interested in doing so, we highly recommend two very
excellent books:
<ulink url="http://www.langer.camelot.de/iostreams.html">Standard C++
IOStreams and Locales</ulink> by Langer and Kreft, ISBN 0-201-18395-1, and
<ulink url="http://www.josuttis.com/libbook/">The C++ Standard Library</ulink>
by Nicolai Josuttis, ISBN 0-201-37926-0. Both are published by
Addison-Wesley, who isn't paying us a cent for saying that, honest.
</para>
<para>Here is a simple example, io/outbuf1, from the Josuttis text. It
transforms everything sent through it to uppercase. This version
assumes many things about the nature of the character type being
used (for more information, read the books or the newsgroups):
</para>
<programlisting>
#include &lt;iostream&gt;
#include &lt;streambuf&gt;
#include &lt;locale&gt;
#include &lt;cstdio&gt;
class outbuf : public std::streambuf
{
protected:
/* central output function
* - print characters in uppercase mode
*/
virtual int_type overflow (int_type c) {
if (c != EOF) {
// convert lowercase to uppercase
c = std::toupper(static_cast&lt;char&gt;(c),getloc());
// and write the character to the standard output
if (putchar(c) == EOF) {
return EOF;
}
}
return c;
}
};
int main()
{
// create special output buffer
outbuf ob;
// initialize output stream with that output buffer
std::ostream out(&amp;ob);
out &lt;&lt; "31 hexadecimal: "
&lt;&lt; std::hex &lt;&lt; 31 &lt;&lt; std::endl;
return 0;
}
</programlisting>
<para>Try it yourself! More examples can be found in 3.1.x code, in
<code>include/ext/*_filebuf.h</code>, and on
<ulink url="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">Dietmar
K&uuml;hl's IOStreams page</ulink>.
</para>
</sect1>
<sect1 id="io.streambuf.buffering" xreflabel="Buffering">
<title>Buffering</title>
<para>First, are you sure that you understand buffering? Particularly
the fact that C++ may not, in fact, have anything to do with it?
</para>
<para>The rules for buffering can be a little odd, but they aren't any
different from those of C. (Maybe that's why they can be a bit
odd.) Many people think that writing a newline to an output
stream automatically flushes the output buffer. This is true only
when the output stream is, in fact, a terminal and not a file
or some other device -- and <emphasis>that</emphasis> may not even be true
since C++ says nothing about files nor terminals. All of that is
system-dependent. (The &quot;newline-buffer-flushing only occurring
on terminals&quot; thing is mostly true on Unix systems, though.)
</para>
<para>Some people also believe that sending <code>endl</code> down an
output stream only writes a newline. This is incorrect; after a
newline is written, the buffer is also flushed. Perhaps this
is the effect you want when writing to a screen -- get the text
out as soon as possible, etc -- but the buffering is largely
wasted when doing this to a file:
</para>
<programlisting>
output &lt;&lt; &quot;a line of text&quot; &lt;&lt; endl;
output &lt;&lt; some_data_variable &lt;&lt; endl;
output &lt;&lt; &quot;another line of text&quot; &lt;&lt; endl; </programlisting>
<para>The proper thing to do in this case to just write the data out
and let the libraries and the system worry about the buffering.
If you need a newline, just write a newline:
</para>
<programlisting>
output &lt;&lt; &quot;a line of text\n&quot;
&lt;&lt; some_data_variable &lt;&lt; '\n'
&lt;&lt; &quot;another line of text\n&quot;; </programlisting>
<para>I have also joined the output statements into a single statement.
You could make the code prettier by moving the single newline to
the start of the quoted text on the last line, for example.
</para>
<para>If you do need to flush the buffer above, you can send an
<code>endl</code> if you also need a newline, or just flush the buffer
yourself:
</para>
<programlisting>
output &lt;&lt; ...... &lt;&lt; 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
be like writing to standard error; no buffering should be done
because the data needs to appear quickly (a prime example is a
log file for security-related information). The way to do this is
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>
std::ofstream os;
std::ifstream is;
int i;
os.rdbuf()-&gt;pubsetbuf(0,0);
is.rdbuf()-&gt;pubsetbuf(0,0);
os.open(&quot;/foo/bar/baz&quot;);
is.open(&quot;/qux/quux/quuux&quot;);
...
os &lt;&lt; &quot;this data is written immediately\n&quot;;
is &gt;&gt; i; // and this will probably cause a disk read </programlisting>
<para>Since all aspects of buffering are handled by a streambuf-derived
member, it is necessary to get at that member with <code>rdbuf()</code>.
Then the public version of <code>setbuf</code> can be called. The
arguments are the same as those for the Standard C I/O Library
function (a buffer area followed by its size).
</para>
<para>A great deal of this is implementation-dependent. For example,
<code>streambuf</code> does not specify any actions for its own
<code>setbuf()</code>-ish functions; the classes derived from
<code>streambuf</code> each define behavior that &quot;makes
sense&quot; for that class: an argument of (0,0) turns off buffering
for <code>filebuf</code> but does nothing at all for its siblings
<code>stringbuf</code> and <code>strstreambuf</code>, and specifying
anything other than (0,0) has varying effects.
User-defined classes derived from <code>streambuf</code> can
do whatever they want. (For <code>filebuf</code> and arguments for
<code>(p,s)</code> other than zeros, libstdc++ does what you'd expect:
the first <code>s</code> bytes of <code>p</code> are used as a buffer,
which you must allocate and deallocate.)
</para>
<para>A last reminder: there are usually more buffers involved than
just those at the language/library level. Kernel buffers, disk
buffers, and the like will also have an effect. Inspecting and
changing those are system-dependent.
</para>
</sect1>
</chapter>
<!-- Chapter 03 : Memory-based Streams -->
<chapter id="manual.io.memstreams" xreflabel="Memory Streams">
<title>Memory Based Streams</title>
<sect1 id="manual.io.memstreams.compat" xreflabel="Compatibility strstream">
<title>Compatibility With strstream</title>
<para>
</para>
<para>Stringstreams (defined in the header <code>&lt;sstream&gt;</code>)
are in this author's opinion one of the coolest things since
sliced time. An example of their use is in the Received Wisdom
section for Chapter 21 (Strings),
<ulink url="../21_strings/howto.html#1.1internal"> describing how to
format strings</ulink>.
</para>
<para>The quick definition is: they are siblings of ifstream and ofstream,
and they do for <code>std::string</code> what their siblings do for
files. All that work you put into writing <code>&lt;&lt;</code> and
<code>&gt;&gt;</code> functions for your classes now pays off
<emphasis>again!</emphasis> Need to format a string before passing the string
to a function? Send your stuff via <code>&lt;&lt;</code> to an
ostringstream. You've read a string as input and need to parse it?
Initialize an istringstream with that string, and then pull pieces
out of it with <code>&gt;&gt;</code>. Have a stringstream and need to
get a copy of the string inside? Just call the <code>str()</code>
member function.
</para>
<para>This only works if you've written your
<code>&lt;&lt;</code>/<code>&gt;&gt;</code> functions correctly, though,
and correctly means that they take istreams and ostreams as
parameters, not i<emphasis>f</emphasis>streams and o<emphasis>f</emphasis>streams. If they
take the latter, then your I/O operators will work fine with
file streams, but with nothing else -- including stringstreams.
</para>
<para>If you are a user of the strstream classes, you need to update
your code. You don't have to explicitly append <code>ends</code> to
terminate the C-style character array, you don't have to mess with
&quot;freezing&quot; functions, and you don't have to manage the
memory yourself. The strstreams have been officially deprecated,
which means that 1) future revisions of the C++ Standard won't
support them, and 2) if you use them, people will laugh at you.
</para>
</sect1>
</chapter>
<!-- Chapter 04 : File-based Streams -->
<chapter id="manual.io.filestreams" xreflabel="File Streams">
<title>File Based Streams</title>
<sect1 id="manual.io.filestreams.copying_a_file" xreflabel="Copying a File">
<title>Copying a File</title>
<para>
</para>
<para>So you want to copy a file quickly and easily, and most important,
completely portably. And since this is C++, you have an open
ifstream (call it IN) and an open ofstream (call it OUT):
</para>
<programlisting>
#include &lt;fstream&gt;
std::ifstream IN ("input_file");
std::ofstream OUT ("output_file"); </programlisting>
<para>Here's the easiest way to get it completely wrong:
</para>
<programlisting>
OUT &lt;&lt; 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 &quot;input_file&quot; containing
the sentence
</para>
<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 &quot;output_file&quot; may surprise you.
</para>
<para>Seriously, go do it. Get surprised, then come back. It's worth it.
</para>
<para>The thing to remember is that the <code>basic_[io]stream</code> classes
handle formatting, nothing else. In particular, they break up on
whitespace. The actual reading, writing, and storing of data is
handled by the <code>basic_streambuf</code> family. Fortunately, the
<code>operator&lt;&lt;</code> is overloaded to take an ostream and
a pointer-to-streambuf, in order to help with just this kind of
&quot;dump the data verbatim&quot; situation.
</para>
<para>Why a <emphasis>pointer</emphasis> to streambuf and not just a streambuf? Well,
the [io]streams hold pointers (or references, depending on the
implementation) to their buffers, not the actual
buffers. This allows polymorphic behavior on the part of the buffers
as well as the streams themselves. The pointer is easily retrieved
using the <code>rdbuf()</code> member function. Therefore, the easiest
way to copy the file is:
</para>
<programlisting>
OUT &lt;&lt; IN.rdbuf();</programlisting>
<para>So what <emphasis>was</emphasis> happening with OUT&lt;&lt;IN? Undefined
behavior, since that particular &lt;&lt; isn't defined by the Standard.
I have seen instances where it is implemented, but the character
extraction process removes all the whitespace, leaving you with no
blank lines and only &quot;Thequickbrownfox...&quot;. With
libraries that do not define that operator, IN (or one of IN's
member pointers) sometimes gets converted to a void*, and the output
file then contains a perfect text representation of a hexadecimal
address (quite a big surprise). Others don't compile at all.
</para>
<para>Also note that none of this is specific to o<emphasis>*f*</emphasis>streams.
The operators shown above are all defined in the parent
basic_ostream class and are therefore available with all possible
descendants.
</para>
</sect1>
<sect1 id="manual.io.filestreams.binary" xreflabel="Binary Input and Output">
<title>Binary Input and Output</title>
<para>
</para>
<para>The first and most important thing to remember about binary I/O is
that opening a file with <code>ios::binary</code> is not, repeat
<emphasis>not</emphasis>, the only thing you have to do. It is not a silver
bullet, and will not allow you to use the <code>&lt;&lt;/&gt;&gt;</code>
operators of the normal fstreams to do binary I/O.
</para>
<para>Sorry. Them's the breaks.
</para>
<para>This isn't going to try and be a complete tutorial on reading and
writing binary files (because &quot;binary&quot;
<ulink url="#7">covers a lot of ground)</ulink>, but we will try and clear
up a couple of misconceptions and common errors.
</para>
<para>First, <code>ios::binary</code> has exactly one defined effect, no more
and no less. Normal text mode has to be concerned with the newline
characters, and the runtime system will translate between (for
example) '\n' and the appropriate end-of-line sequence (LF on Unix,
CRLF on DOS, CR on Macintosh, etc). (There are other things that
normal mode does, but that's the most obvious.) Opening a file in
binary mode disables this conversion, so reading a CRLF sequence
under Windows won't accidentally get mapped to a '\n' character, etc.
Binary mode is not supposed to suddenly give you a bitstream, and
if it is doing so in your program then you've discovered a bug in
your vendor's compiler (or some other part of the C++ implementation,
possibly the runtime system).
</para>
<para>Second, using <code>&lt;&lt;</code> to write and <code>&gt;&gt;</code> to
read isn't going to work with the standard file stream classes, even
if you use <code>skipws</code> during reading. Why not? Because
ifstream and ofstream exist for the purpose of <emphasis>formatting</emphasis>,
not reading and writing. Their job is to interpret the data into
text characters, and that's exactly what you don't want to happen
during binary I/O.
</para>
<para>Third, using the <code>get()</code> and <code>put()/write()</code> member
functions still aren't guaranteed to help you. These are
&quot;unformatted&quot; I/O functions, but still character-based.
(This may or may not be what you want, see below.)
</para>
<para>Notice how all the problems here are due to the inappropriate use
of <emphasis>formatting</emphasis> functions and classes to perform something
which <emphasis>requires</emphasis> that formatting not be done? There are a
seemingly infinite number of solutions, and a few are listed here:
</para>
<itemizedlist>
<listitem>
<para><quote>Derive your own fstream-type classes and write your own
&lt;&lt;/&gt;&gt; operators to do binary I/O on whatever data
types you're using.</quote>
</para>
<para>
This is a Bad Thing, because while
the compiler would probably be just fine with it, other humans
are going to be confused. The overloaded bitshift operators
have a well-defined meaning (formatting), and this breaks it.
</para>
</listitem>
<listitem>
<para>
<quote>Build the file structure in memory, then
<code>mmap()</code> the file and copy the
structure.
</quote>
</para>
<para>
Well, this is easy to make work, and easy to break, and is
pretty equivalent to using <code>::read()</code> and
<code>::write()</code> directly, and makes no use of the
iostream library at all...
</para>
</listitem>
<listitem>
<para>
<quote>Use streambufs, that's what they're there for.</quote>
</para>
<para>
While not trivial for the beginner, this is the best of all
solutions. The streambuf/filebuf layer is the layer that is
responsible for actual I/O. If you want to use the C++
library for binary I/O, this is where you start.
</para>
</listitem>
</itemizedlist>
<para>How to go about using streambufs is a bit beyond the scope of this
document (at least for now), but while streambufs go a long way,
they still leave a couple of things up to you, the programmer.
As an example, byte ordering is completely between you and the
operating system, and you have to handle it yourself.
</para>
<para>Deriving a streambuf or filebuf
class from the standard ones, one that is specific to your data
types (or an abstraction thereof) is probably a good idea, and
lots of examples exist in journals and on Usenet. Using the
standard filebufs directly (either by declaring your own or by
using the pointer returned from an fstream's <code>rdbuf()</code>)
is certainly feasible as well.
</para>
<para>One area that causes problems is trying to do bit-by-bit operations
with filebufs. C++ is no different from C in this respect: I/O
must be done at the byte level. If you're trying to read or write
a few bits at a time, you're going about it the wrong way. You
must read/write an integral number of bytes and then process the
bytes. (For example, the streambuf functions take and return
variables of type <code>int_type</code>.)
</para>
<para>Another area of problems is opening text files in binary mode.
Generally, binary mode is intended for binary files, and opening
text files in binary mode means that you now have to deal with all of
those end-of-line and end-of-file problems that we mentioned before.
An instructive thread from comp.lang.c++.moderated delved off into
this topic starting more or less at
<ulink url="http://groups.google.com/groups?oi=djq&amp;selm=an_436187505">this</ulink>
article and continuing to the end of the thread. (You'll have to
sort through some flames every couple of paragraphs, but the points
made are good ones.)
</para>
</sect1>
<sect1 id="manual.io.filestreams.binary2" xreflabel="Binary Input and Output">
<title>More Binary Input and Output</title>
<para>Towards the beginning of February 2001, the subject of
&quot;binary&quot; I/O was brought up in a couple of places at the
same time. One notable place was Usenet, where James Kanze and
Dietmar K&uuml;hl separately posted articles on why attempting
generic binary I/O was not a good idea. (Here are copies of
<ulink url="binary_iostreams_kanze.txt">Kanze's article</ulink> and
<ulink url="binary_iostreams_kuehl.txt">K&uuml;hl's article</ulink>.)
</para>
<para>Briefly, the problems of byte ordering and type sizes mean that
the unformatted functions like <code>ostream::put()</code> and
<code>istream::get()</code> cannot safely be used to communicate
between arbitrary programs, or across a network, or from one
invocation of a program to another invocation of the same program
on a different platform, etc.
</para>
<para>The entire Usenet thread is instructive, and took place under the
subject heading &quot;binary iostreams&quot; on both comp.std.c++
and comp.lang.c++.moderated in parallel. Also in that thread,
Dietmar K&uuml;hl mentioned that he had written a pair of stream
classes that would read and write XDR, which is a good step towards
a portable binary format.
</para>
</sect1>
</chapter>
<!-- Chapter 03 : Interacting with C -->
<chapter id="manual.io.c" xreflabel="Interacting with C">
<title>Interacting with C</title>
<sect1 id="manual.io.c.FILE" xreflabel="Using FILE* and file descriptors">
<title>Using FILE* and file descriptors</title>
<para>
See the <link linkend="manual.ext.io">extensions</link> for using
<type>FILE</type> and <type>file descriptors</type> with
<classname>ofstream</classname> and
<classname>ifstream</classname>.
</para>
</sect1>
<sect1 id="manual.io.c.sync" xreflabel="Performance Issues">
<title>Performance</title>
<para>
Pathetic Performance? Ditch C.
</para>
<para>It sounds like a flame on C, but it isn't. Really. Calm down.
I'm just saying it to get your attention.
</para>
<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>
#include &lt;iostream&gt;
#include &lt;cstdio&gt;
std::cout &lt;&lt; &quot;Hel&quot;;
std::printf (&quot;lo, worl&quot;);
std::cout &lt;&lt; &quot;d!\n&quot;;
</programlisting>
<para>This must do what you think it does.
</para>
<para>Alert members of the audience will immediately notice that buffering
is going to make a hash of the output unless special steps are taken.
</para>
<para>The special steps taken by libstdc++, at least for version 3.0,
involve doing very little buffering for the standard streams, leaving
most of the buffering to the underlying C library. (This kind of
thing is tricky to get right.)
The upside is that correctness is ensured. The downside is that
writing through <code>cout</code> can quite easily lead to awful
performance when the C++ I/O library is layered on top of the C I/O
library (as it is for 3.0 by default). Some patches have been applied
which improve the situation for 3.1.
</para>
<para>However, the C and C++ standard streams only need to be kept in sync
when both libraries' facilities are in use. If your program only uses
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>
#include <emphasis>any of the I/O headers such as ios, iostream, etc</emphasis>
std::ios::sync_with_stdio(false);
</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
company will become fully buffered on their own.
</para>
<para>Note, by the way, that the synchronization requirement only applies to
the standard streams (<code>cin</code>, <code>cout</code>,
<code>cerr</code>,
<code>clog</code>, and their wide-character counterparts). File stream
objects that you declare yourself have no such requirement and are fully
buffered.
</para>
</sect1>
</chapter>
</part>

View file

@ -0,0 +1,177 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.iterators" xreflabel="Iterators">
<?dbhtml filename="iterators.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Iterators</title>
<!-- Chapter 01 : Predefined -->
<chapter id="manual.iterators.predefined" xreflabel="Predefined">
<title>Predefined</title>
<sect1 id="iterators.predefined.vs_pointers" xreflabel="Versus Pointers">
<title>Iterators vs. Pointers</title>
<para><ulink url="../faq/index.html#5_1">FAQ 5.1</ulink> points out that iterators
are not implemented as pointers. They are a generalization of
pointers, but they are implemented in libstdc++ as separate classes.
</para>
<para>Keeping that simple fact in mind as you design your code will
prevent a whole lot of difficult-to-understand bugs.
</para>
<para>You can think of it the other way 'round, even. Since iterators
are a generalization, that means that <emphasis>pointers</emphasis> are
<emphasis>iterators</emphasis>, and that pointers can be used whenever an
iterator would be. All those functions in the Algorithms chapter
of the Standard will work just as well on plain arrays and their
pointers.
</para>
<para>That doesn't mean that when you pass in a pointer, it gets wrapped
into some special delegating iterator-to-pointer class with a layer
of overhead. (If you think that's the case anywhere, you don't
understand templates to begin with...) Oh, no; if you pass
in a pointer, then the compiler will instantiate that template
using T* as a type, and good old high-speed pointer arithmetic as
its operations, so the resulting code will be doing exactly the same
things as it would be doing if you had hand-coded it yourself (for
the 273rd time).
</para>
<para>How much overhead <emphasis>is</emphasis> there when using an iterator class?
Very little. Most of the layering classes contain nothing but
typedefs, and typedefs are &quot;meta-information&quot; that simply
tell the compiler some nicknames; they don't create code. That
information gets passed down through inheritance, so while the
compiler has to do work looking up all the names, your runtime code
does not. (This has been a prime concern from the beginning.)
</para>
</sect1>
<sect1 id="iterators.predefined.end" xreflabel="end() Is One Past the End">
<title>One Past the End</title>
<para>This starts off sounding complicated, but is actually very easy,
especially towards the end. Trust me.
</para>
<para>Beginners usually have a little trouble understand the whole
'past-the-end' thing, until they remember their early algebra classes
(see, they <emphasis>told</emphasis> you that stuff would come in handy!) and
the concept of half-open ranges.
</para>
<para>First, some history, and a reminder of some of the funkier rules in
C and C++ for builtin arrays. The following rules have always been
true for both languages:
</para>
<orderedlist>
<listitem>
<para>You can point anywhere in the array, <emphasis>or to the first element
past the end of the array</emphasis>. A pointer that points to one
past the end of the array is guaranteed to be as unique as a
pointer to somewhere inside the array, so that you can compare
such pointers safely.
</para>
</listitem>
<listitem>
<para>You can only dereference a pointer that points into an array.
If your array pointer points outside the array -- even to just
one past the end -- and you dereference it, Bad Things happen.
</para>
</listitem>
<listitem>
<para>Strictly speaking, simply pointing anywhere else invokes
undefined behavior. Most programs won't puke until such a
pointer is actually dereferenced, but the standards leave that
up to the platform.
</para>
</listitem>
</orderedlist>
<para>The reason this past-the-end addressing was allowed is to make it
easy to write a loop to go over an entire array, e.g.,
while (*d++ = *s++);.
</para>
<para>So, when you think of two pointers delimiting an array, don't think
of them as indexing 0 through n-1. Think of them as <emphasis>boundary
markers</emphasis>:
</para>
<programlisting>
beginning end
| |
| | This is bad. Always having to
| | remember to add or subtract one.
| | Off-by-one bugs very common here.
V V
array of N elements
|---|---|--...--|---|---|
| 0 | 1 | ... |N-2|N-1|
|---|---|--...--|---|---|
^ ^
| |
| | This is good. This is safe. This
| | is guaranteed to work. Just don't
| | dereference 'end'.
beginning end
</programlisting>
<para>See? Everything between the boundary markers is part of the array.
Simple.
</para>
<para>Now think back to your junior-high school algebra course, when you
were learning how to draw graphs. Remember that a graph terminating
with a solid dot meant, &quot;Everything up through this point,&quot;
and a graph terminating with an open dot meant, &quot;Everything up
to, but not including, this point,&quot; respectively called closed
and open ranges? Remember how closed ranges were written with
brackets, <emphasis>[a,b]</emphasis>, and open ranges were written with parentheses,
<emphasis>(a,b)</emphasis>?
</para>
<para>The boundary markers for arrays describe a <emphasis>half-open range</emphasis>,
starting with (and including) the first element, and ending with (but
not including) the last element: <emphasis>[beginning,end)</emphasis>. See, I
told you it would be simple in the end.
</para>
<para>Iterators, and everything working with iterators, follows this same
time-honored tradition. A container's <code>begin()</code> method returns
an iterator referring to the first element, and its <code>end()</code>
method returns a past-the-end iterator, which is guaranteed to be
unique and comparable against any other iterator pointing into the
middle of the container.
</para>
<para>Container constructors, container methods, and algorithms, all take
pairs of iterators describing a range of values on which to operate.
All of these ranges are half-open ranges, so you pass the beginning
iterator as the starting parameter, and the one-past-the-end iterator
as the finishing parameter.
</para>
<para>This generalizes very well. You can operate on sub-ranges quite
easily this way; functions accepting a <emphasis>[first,last)</emphasis> range
don't know or care whether they are the boundaries of an entire {array,
sequence, container, whatever}, or whether they only enclose a few
elements from the center. This approach also makes zero-length
sequences very simple to recognize: if the two endpoints compare
equal, then the {array, sequence, container, whatever} is empty.
</para>
<para>Just don't dereference <code>end()</code>.
</para>
</sect1>
</chapter>
<!-- Chapter 02 : Stream -->
</part>

View file

@ -0,0 +1,653 @@
<sect1 id="manual.localization.locales.locale" xreflabel="locale">
<?dbhtml filename="locale.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
locale
</keyword>
</keywordset>
</sect1info>
<title>locale</title>
<para>
Describes the basic locale object, including nested
classes id, facet, and the reference-counted implementation object,
class _Impl.
</para>
<sect2 id="locales.locale.req" xreflabel="locales.locale.req">
<title>Requirements</title>
<para>
Class locale is non-templatized and has two distinct types nested
inside of it:
</para>
<blockquote>
<para>
<emphasis>
class facet
22.1.1.1.2 Class locale::facet
</emphasis>
</para>
</blockquote>
<para>
Facets actually implement locale functionality. For instance, a facet
called numpunct is the data objects that can be used to query for the
thousands separator is in the German locale.
</para>
<para>
Literally, a facet is strictly defined:
</para>
<itemizedlist>
<listitem>
<para>
Dontaining the following public data member:
</para>
<para>
<code>static locale::id id;</code>
</para>
</listitem>
<listitem>
<para>
Derived from another facet:
</para>
<para>
<code>class gnu_codecvt: public std::ctype&lt;user-defined-type&gt;</code>
</para>
</listitem>
</itemizedlist>
<para>
Of interest in this class are the memory management options explicitly
specified as an argument to facet's constructor. Each constructor of a
facet class takes a std::size_t __refs argument: if __refs == 0, the
facet is deleted when the locale containing it is destroyed. If __refs
== 1, the facet is not destroyed, even when it is no longer
referenced.
</para>
<blockquote>
<para>
<emphasis>
class id
22.1.1.1.3 - Class locale::id
</emphasis>
</para>
</blockquote>
<para>
Provides an index for looking up specific facets.
</para>
</sect2>
<sect2 id="locales.locale.design" xreflabel="locales.locale.design">
<title>Design</title>
<para>
The major design challenge is fitting an object-orientated and
non-global locale design ontop of POSIX and other relevant stanards,
which include the Single Unix (nee X/Open.)
</para>
<para>
Because C and earlier versions of POSIX falls down so completely,
portibility is an issue.
</para>
</sect2>
<sect2 id="locales.locale.impl" xreflabel="locales.locale.impl">
<title>Implementation</title>
<sect3 id="locale.impl.c" xreflabel="locale.impl.c">
<title>Interacting with &quot;C&quot; locales</title>
<itemizedlist>
<listitem>
<para>
<code>`locale -a`</code> displays available locales.
</para>
<blockquote>
<programlisting>
af_ZA
ar_AE
ar_AE.utf8
ar_BH
ar_BH.utf8
ar_DZ
ar_DZ.utf8
ar_EG
ar_EG.utf8
ar_IN
ar_IQ
ar_IQ.utf8
ar_JO
ar_JO.utf8
ar_KW
ar_KW.utf8
ar_LB
ar_LB.utf8
ar_LY
ar_LY.utf8
ar_MA
ar_MA.utf8
ar_OM
ar_OM.utf8
ar_QA
ar_QA.utf8
ar_SA
ar_SA.utf8
ar_SD
ar_SD.utf8
ar_SY
ar_SY.utf8
ar_TN
ar_TN.utf8
ar_YE
ar_YE.utf8
be_BY
be_BY.utf8
bg_BG
bg_BG.utf8
br_FR
bs_BA
C
ca_ES
ca_ES@euro
ca_ES.utf8
ca_ES.utf8@euro
cs_CZ
cs_CZ.utf8
cy_GB
da_DK
da_DK.iso885915
da_DK.utf8
de_AT
de_AT@euro
de_AT.utf8
de_AT.utf8@euro
de_BE
de_BE@euro
de_BE.utf8
de_BE.utf8@euro
de_CH
de_CH.utf8
de_DE
de_DE@euro
de_DE.utf8
de_DE.utf8@euro
de_LU
de_LU@euro
de_LU.utf8
de_LU.utf8@euro
el_GR
el_GR.utf8
en_AU
en_AU.utf8
en_BW
en_BW.utf8
en_CA
en_CA.utf8
en_DK
en_DK.utf8
en_GB
en_GB.iso885915
en_GB.utf8
en_HK
en_HK.utf8
en_IE
en_IE@euro
en_IE.utf8
en_IE.utf8@euro
en_IN
en_NZ
en_NZ.utf8
en_PH
en_PH.utf8
en_SG
en_SG.utf8
en_US
en_US.iso885915
en_US.utf8
en_ZA
en_ZA.utf8
en_ZW
en_ZW.utf8
es_AR
es_AR.utf8
es_BO
es_BO.utf8
es_CL
es_CL.utf8
es_CO
es_CO.utf8
es_CR
es_CR.utf8
es_DO
es_DO.utf8
es_EC
es_EC.utf8
es_ES
es_ES@euro
es_ES.utf8
es_ES.utf8@euro
es_GT
es_GT.utf8
es_HN
es_HN.utf8
es_MX
es_MX.utf8
es_NI
es_NI.utf8
es_PA
es_PA.utf8
es_PE
es_PE.utf8
es_PR
es_PR.utf8
es_PY
es_PY.utf8
es_SV
es_SV.utf8
es_US
es_US.utf8
es_UY
es_UY.utf8
es_VE
es_VE.utf8
et_EE
et_EE.utf8
eu_ES
eu_ES@euro
eu_ES.utf8
eu_ES.utf8@euro
fa_IR
fi_FI
fi_FI@euro
fi_FI.utf8
fi_FI.utf8@euro
fo_FO
fo_FO.utf8
fr_BE
fr_BE@euro
fr_BE.utf8
fr_BE.utf8@euro
fr_CA
fr_CA.utf8
fr_CH
fr_CH.utf8
fr_FR
fr_FR@euro
fr_FR.utf8
fr_FR.utf8@euro
fr_LU
fr_LU@euro
fr_LU.utf8
fr_LU.utf8@euro
ga_IE
ga_IE@euro
ga_IE.utf8
ga_IE.utf8@euro
gl_ES
gl_ES@euro
gl_ES.utf8
gl_ES.utf8@euro
gv_GB
gv_GB.utf8
he_IL
he_IL.utf8
hi_IN
hr_HR
hr_HR.utf8
hu_HU
hu_HU.utf8
id_ID
id_ID.utf8
is_IS
is_IS.utf8
it_CH
it_CH.utf8
it_IT
it_IT@euro
it_IT.utf8
it_IT.utf8@euro
iw_IL
iw_IL.utf8
ja_JP.eucjp
ja_JP.utf8
ka_GE
kl_GL
kl_GL.utf8
ko_KR.euckr
ko_KR.utf8
kw_GB
kw_GB.utf8
lt_LT
lt_LT.utf8
lv_LV
lv_LV.utf8
mi_NZ
mk_MK
mk_MK.utf8
mr_IN
ms_MY
ms_MY.utf8
mt_MT
mt_MT.utf8
nl_BE
nl_BE@euro
nl_BE.utf8
nl_BE.utf8@euro
nl_NL
nl_NL@euro
nl_NL.utf8
nl_NL.utf8@euro
nn_NO
nn_NO.utf8
no_NO
no_NO.utf8
oc_FR
pl_PL
pl_PL.utf8
POSIX
pt_BR
pt_BR.utf8
pt_PT
pt_PT@euro
pt_PT.utf8
pt_PT.utf8@euro
ro_RO
ro_RO.utf8
ru_RU
ru_RU.koi8r
ru_RU.utf8
ru_UA
ru_UA.utf8
se_NO
sk_SK
sk_SK.utf8
sl_SI
sl_SI.utf8
sq_AL
sq_AL.utf8
sr_YU
sr_YU@cyrillic
sr_YU.utf8
sr_YU.utf8@cyrillic
sv_FI
sv_FI@euro
sv_FI.utf8
sv_FI.utf8@euro
sv_SE
sv_SE.iso885915
sv_SE.utf8
ta_IN
te_IN
tg_TJ
th_TH
th_TH.utf8
tl_PH
tr_TR
tr_TR.utf8
uk_UA
uk_UA.utf8
ur_PK
uz_UZ
vi_VN
vi_VN.tcvn
wa_BE
wa_BE@euro
yi_US
zh_CN
zh_CN.gb18030
zh_CN.gbk
zh_CN.utf8
zh_HK
zh_HK.utf8
zh_TW
zh_TW.euctw
zh_TW.utf8
</programlisting>
</blockquote>
</listitem>
<listitem>
<para>
<code>`locale`</code> displays environmental variables that
impact how locale("") will be deduced.
</para>
<blockquote>
<programlisting>
LANG=en_US
LC_CTYPE="en_US"
LC_NUMERIC="en_US"
LC_TIME="en_US"
LC_COLLATE="en_US"
LC_MONETARY="en_US"
LC_MESSAGES="en_US"
LC_PAPER="en_US"
LC_NAME="en_US"
LC_ADDRESS="en_US"
LC_TELEPHONE="en_US"
LC_MEASUREMENT="en_US"
LC_IDENTIFICATION="en_US"
LC_ALL=
</programlisting>
</blockquote>
</listitem>
</itemizedlist>
<para>
From Josuttis, p. 697-698, which says, that "there is only *one*
relation (of the C++ locale mechanism) to the C locale mechanism: the
global C locale is modified if a named C++ locale object is set as the
global locale" (emphasis Paolo), that is:
</para>
<programlisting>std::locale::global(std::locale(""));</programlisting>
<para>affects the C functions as if the following call was made:</para>
<programlisting>std::setlocale(LC_ALL, "");</programlisting>
<para>
On the other hand, there is *no* viceversa, that is, calling
setlocale has *no* whatsoever on the C++ locale mechanism, in
particular on the working of locale(""), which constructs the locale
object from the environment of the running program, that is, in
practice, the set of LC_ALL, LANG, etc. variable of the shell.
</para>
</sect3>
</sect2>
<sect2 id="locales.locale.future" xreflabel="locales.locale.future">
<title>Future</title>
<itemizedlist>
<listitem>
<para>
Locale initialization: at what point does _S_classic, _S_global
get initialized? Can named locales assume this initialization
has already taken place?
</para>
</listitem>
<listitem>
<para>
Document how named locales error check when filling data
members. Ie, a fr_FR locale that doesn't have
numpunct::truename(): does it use "true"? Or is it a blank
string? What's the convention?
</para>
</listitem>
<listitem>
<para>
Explain how locale aliasing happens. When does "de_DE" use "de"
information? What is the rule for locales composed of just an
ISO language code (say, "de") and locales with both an ISO
language code and ISO country code (say, "de_DE").
</para>
</listitem>
<listitem>
<para>
What should non-required facet instantiations do? If the
generic implemenation is provided, then how to end-users
provide specializations?
</para>
</listitem>
</itemizedlist>
</sect2>
<bibliography id="locales.locale.biblio" xreflabel="locales.locale.biblio">
<title>Bibliography</title>
<biblioentry>
<title>
The GNU C Library
</title>
<author>
<surname>McGrath</surname>
<firstname>Roland</firstname>
</author>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2007</year>
<holder>FSF</holder>
</copyright>
<pagenums>Chapters 6 Character Set Handling and 7 Locales and Internationalization</pagenums>
</biblioentry>
<biblioentry>
<title>
Correspondence
</title>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2002</year>
<holder></holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 14882:1998 Programming languages - C++
</title>
<copyright>
<year>1998</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 9899:1999 Programming languages - C
</title>
<copyright>
<year>1999</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</title>
<copyright>
<year>1999</year>
<holder>
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.</holder>
</copyright>
<biblioid>
<ulink url="http://www.opennc.org/austin/docreg.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
The C++ Programming Language, Special Edition
</title>
<author>
<surname>Stroustrup</surname>
<firstname>Bjarne</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley, Inc.</holder>
</copyright>
<pagenums>Appendix D</pagenums>
<publisher>
<publishername>
Addison Wesley
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
Standard C++ IOStreams and Locales
</title>
<subtitle>
Advanced Programmer's Guide and Reference
</subtitle>
<author>
<surname>Langer</surname>
<firstname>Angelika</firstname>
</author>
<author>
<surname>Kreft</surname>
<firstname>Klaus</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley Longman, Inc.</holder>
</copyright>
<publisher>
<publishername>
Addison Wesley Longman
</publishername>
</publisher>
</biblioentry>
</bibliography>
</sect1>

View file

@ -0,0 +1,54 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.localization" xreflabel="Localization">
<?dbhtml filename="localization.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Localization</title>
<!-- Chapter 01 : Locale -->
<chapter id="manual.localization.locales" xreflabel="Locales">
<title>Locales</title>
<!-- Section 01 : locale -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="locale.xml">
</xi:include>
</chapter>
<!-- Chapter 02 : Facet -->
<chapter id="manual.localization.facet" xreflabel="facet">
<title>Facets aka Categories</title>
<!-- Section 01 : ctype -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="ctype.xml">
</xi:include>
<!-- Section 02 : codecvt -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="codecvt.xml">
</xi:include>
<!-- Section 03 : messages -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="messages.xml">
</xi:include>
</chapter>
<!-- Chapter 03 : Interacting with C -->
</part>

View file

@ -0,0 +1,604 @@
<sect1 id="manual.localization.facet.messages" xreflabel="messages">
<?dbhtml filename="messages.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
messages
</keyword>
</keywordset>
</sect1info>
<title>messages</title>
<para>
The std::messages facet implements message retrieval functionality
equivalent to Java's java.text.MessageFormat .using either GNU gettext
or IEEE 1003.1-200 functions.
</para>
<sect2 id="facet.messages.req" xreflabel="facet.messages.req">
<title>Requirements</title>
<para>
The std::messages facet is probably the most vaguely defined facet in
the standard library. It's assumed that this facility was built into
the standard library in order to convert string literals from one
locale to the other. For instance, converting the "C" locale's
<code>const char* c = "please"</code> to a German-localized <code>"bitte"</code>
during program execution.
</para>
<blockquote>
<para>
22.2.7.1 - Template class messages [lib.locale.messages]
</para>
</blockquote>
<para>
This class has three public member functions, which directly
correspond to three protected virtual member functions.
</para>
<para>
The public member functions are:
</para>
<para>
<code>catalog open(const string&amp;, const locale&amp;) const</code>
</para>
<para>
<code>string_type get(catalog, int, int, const string_type&amp;) const</code>
</para>
<para>
<code>void close(catalog) const</code>
</para>
<para>
While the virtual functions are:
</para>
<para>
<code>catalog do_open(const string&amp;, const locale&amp;) const</code>
</para>
<blockquote>
<para>
<emphasis>
-1- Returns: A value that may be passed to get() to retrieve a
message, from the message catalog identified by the string name
according to an implementation-defined mapping. The result can be used
until it is passed to close(). Returns a value less than 0 if no such
catalog can be opened.
</emphasis>
</para>
</blockquote>
<para>
<code>string_type do_get(catalog, int, int, const string_type&amp;) const</code>
</para>
<blockquote>
<para>
<emphasis>
-3- Requires: A catalog cat obtained from open() and not yet closed.
-4- Returns: A message identified by arguments set, msgid, and dfault,
according to an implementation-defined mapping. If no such message can
be found, returns dfault.
</emphasis>
</para>
</blockquote>
<para>
<code>void do_close(catalog) const</code>
</para>
<blockquote>
<para>
<emphasis>
-5- Requires: A catalog cat obtained from open() and not yet closed.
-6- Effects: Releases unspecified resources associated with cat.
-7- Notes: The limit on such resources, if any, is implementation-defined.
</emphasis>
</para>
</blockquote>
</sect2>
<sect2 id="facet.messages.design" xreflabel="facet.messages.design">
<title>Design</title>
<para>
A couple of notes on the standard.
</para>
<para>
First, why is <code>messages_base::catalog</code> specified as a typedef
to int? This makes sense for implementations that use
<code>catopen</code>, but not for others. Fortunately, it's not heavily
used and so only a minor irritant.
</para>
<para>
Second, by making the member functions <code>const</code>, it is
impossible to save state in them. Thus, storing away information used
in the 'open' member function for use in 'get' is impossible. This is
unfortunate.
</para>
<para>
The 'open' member function in particular seems to be oddly
designed. The signature seems quite peculiar. Why specify a <code>const
string&amp; </code> argument, for instance, instead of just <code>const
char*</code>? Or, why specify a <code>const locale&amp;</code> argument that is
to be used in the 'get' member function? How, exactly, is this locale
argument useful? What was the intent? It might make sense if a locale
argument was associated with a given default message string in the
'open' member function, for instance. Quite murky and unclear, on
reflection.
</para>
<para>
Lastly, it seems odd that messages, which explicitly require code
conversion, don't use the codecvt facet. Because the messages facet
has only one template parameter, it is assumed that ctype, and not
codecvt, is to be used to convert between character sets.
</para>
<para>
It is implicitly assumed that the locale for the default message
string in 'get' is in the "C" locale. Thus, all source code is assumed
to be written in English, so translations are always from "en_US" to
other, explicitly named locales.
</para>
</sect2>
<sect2 id="facet.messages.impl" xreflabel="facet.messages.impl">
<title>Implementation</title>
<sect3 id="messages.impl.models" xreflabel="messages.impl.models">
<title>Models</title>
<para>
This is a relatively simple class, on the face of it. The standard
specifies very little in concrete terms, so generic
implementations that are conforming yet do very little are the
norm. Adding functionality that would be useful to programmers and
comparable to Java's java.text.MessageFormat takes a bit of work,
and is highly dependent on the capabilities of the underlying
operating system.
</para>
<para>
Three different mechanisms have been provided, selectable via
configure flags:
</para>
<itemizedlist>
<listitem>
<para>
generic
</para>
<para>
This model does very little, and is what is used by default.
</para>
</listitem>
<listitem>
<para>
gnu
</para>
<para>
The gnu model is complete and fully tested. It's based on the
GNU gettext package, which is part of glibc. It uses the
functions <code>textdomain, bindtextdomain, gettext</code> to
implement full functionality. Creating message catalogs is a
relatively straight-forward process and is lightly documented
below, and fully documented in gettext's distributed
documentation.
</para>
</listitem>
<listitem>
<para>
ieee_1003.1-200x
</para>
<para>
This is a complete, though untested, implementation based on
the IEEE standard. The functions <code>catopen, catgets,
catclose</code> are used to retrieve locale-specific messages
given the appropriate message catalogs that have been
constructed for their use. Note, the script <code>
po2msg.sed</code> that is part of the gettext distribution can
convert gettext catalogs into catalogs that
<code>catopen</code> can use.
</para>
</listitem>
</itemizedlist>
<para>
A new, standards-conformant non-virtual member function signature was
added for 'open' so that a directory could be specified with a given
message catalog. This simplifies calling conventions for the gnu
model.
</para>
</sect3>
<sect3 id="messages.impl.gnu" xreflabel="messages.impl.gnu">
<title>The GNU Model</title>
<para>
The messages facet, because it is retrieving and converting
between characters sets, depends on the ctype and perhaps the
codecvt facet in a given locale. In addition, underlying "C"
library locale support is necessary for more than just the
<code>LC_MESSAGES</code> mask: <code>LC_CTYPE</code> is also
necessary. To avoid any unpleasantness, all bits of the "C" mask
(ie <code>LC_ALL</code>) are set before retrieving messages.
</para>
<para>
Making the message catalogs can be initially tricky, but become
quite simple with practice. For complete info, see the gettext
documentation. Here's an idea of what is required:
</para>
<itemizedlist>
<listitem>
<para>
Make a source file with the required string literals that need
to be translated. See <code>intl/string_literals.cc</code> for
an example.
</para>
</listitem>
<listitem>
<para>
Make initial catalog (see "4 Making the PO Template File" from
the gettext docs).</para>
<para>
<code> xgettext --c++ --debug string_literals.cc -o libstdc++.pot </code>
</para>
</listitem>
<listitem>
<para>Make language and country-specific locale catalogs.</para>
<para>
<code>cp libstdc++.pot fr_FR.po</code>
</para>
<para>
<code>cp libstdc++.pot de_DE.po</code>
</para>
</listitem>
<listitem>
<para>
Edit localized catalogs in emacs so that strings are
translated.
</para>
<para>
<code>emacs fr_FR.po</code>
</para>
</listitem>
<listitem>
<para>Make the binary mo files.</para>
<para>
<code>msgfmt fr_FR.po -o fr_FR.mo</code>
</para>
<para>
<code>msgfmt de_DE.po -o de_DE.mo</code>
</para>
</listitem>
<listitem>
<para>Copy the binary files into the correct directory structure.</para>
<para>
<code>cp fr_FR.mo (dir)/fr_FR/LC_MESSAGES/libstdc++.mo</code>
</para>
<para>
<code>cp de_DE.mo (dir)/de_DE/LC_MESSAGES/libstdc++.mo</code>
</para>
</listitem>
<listitem>
<para>Use the new message catalogs.</para>
<para>
<code>locale loc_de("de_DE");</code>
</para>
<para>
<code>
use_facet&lt;messages&lt;char&gt; &gt;(loc_de).open("libstdc++", locale(), dir);
</code>
</para>
</listitem>
</itemizedlist>
</sect3>
</sect2>
<sect2 id="facet.messages.use" xreflabel="facet.messages.use">
<title>Use</title>
<para>
A simple example using the GNU model of message conversion.
</para>
<programlisting>
#include &lt;iostream&gt;
#include &lt;locale&gt;
using namespace std;
void test01()
{
typedef messages&lt;char&gt;::catalog catalog;
const char* dir =
"/mnt/egcs/build/i686-pc-linux-gnu/libstdc++/po/share/locale";
const locale loc_de("de_DE");
const messages&lt;char&gt;&amp; mssg_de = use_facet&lt;messages&lt;char&gt; &gt;(loc_de);
catalog cat_de = mssg_de.open("libstdc++", loc_de, dir);
string s01 = mssg_de.get(cat_de, 0, 0, "please");
string s02 = mssg_de.get(cat_de, 0, 0, "thank you");
cout &lt;&lt; "please in german:" &lt;&lt; s01 &lt;&lt; '\n';
cout &lt;&lt; "thank you in german:" &lt;&lt; s02 &lt;&lt; '\n';
mssg_de.close(cat_de);
}
</programlisting>
</sect2>
<sect2 id="facet.messages.future" xreflabel="facet.messages.future">
<title>Future</title>
<itemizedlist>
<listitem>
<para>
Things that are sketchy, or remain unimplemented:
</para>
<itemizedlist>
<listitem>
<para>
_M_convert_from_char, _M_convert_to_char are in flux,
depending on how the library ends up doing character set
conversions. It might not be possible to do a real character
set based conversion, due to the fact that the template
parameter for messages is not enough to instantiate the
codecvt facet (1 supplied, need at least 2 but would prefer
3).
</para>
</listitem>
<listitem>
<para>
There are issues with gettext needing the global locale set
to extract a message. This dependence on the global locale
makes the current "gnu" model non MT-safe. Future versions
of glibc, ie glibc 2.3.x will fix this, and the C++ library
bits are already in place.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Development versions of the GNU "C" library, glibc 2.3 will allow
a more efficient, MT implementation of std::messages, and will
allow the removal of the _M_name_messages data member. If this is
done, it will change the library ABI. The C++ parts to support
glibc 2.3 have already been coded, but are not in use: once this
version of the "C" library is released, the marked parts of the
messages implementation can be switched over to the new "C"
library functionality.
</para>
</listitem>
<listitem>
<para>
At some point in the near future, std::numpunct will probably use
std::messages facilities to implement truename/falename
correctly. This is currently not done, but entries in
libstdc++.pot have already been made for "true" and "false" string
literals, so all that remains is the std::numpunct coding and the
configure/make hassles to make the installed library search its
own catalog. Currently the libstdc++.mo catalog is only searched
for the testsuite cases involving messages members.
</para>
</listitem>
<listitem>
<para> The following member functions:</para>
<para>
<code>
catalog
open(const basic_string&lt;char&gt;&amp; __s, const locale&amp; __loc) const
</code>
</para>
<para>
<code>
catalog
open(const basic_string&lt;char&gt;&amp;, const locale&amp;, const char*) const;
</code>
</para>
<para>
Don't actually return a "value less than 0 if no such catalog
can be opened" as required by the standard in the "gnu"
model. As of this writing, it is unknown how to query to see
if a specified message catalog exists using the gettext
package.
</para>
</listitem>
</itemizedlist>
</sect2>
<bibliography id="facet.messages.biblio" xreflabel="facet.messages.biblio">
<title>Bibliography</title>
<biblioentry>
<title>
The GNU C Library
</title>
<author>
<surname>McGrath</surname>
<firstname>Roland</firstname>
</author>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2007</year>
<holder>FSF</holder>
</copyright>
<pagenums>Chapters 6 Character Set Handling, and 7 Locales and Internationalization
</pagenums>
</biblioentry>
<biblioentry>
<title>
Correspondence
</title>
<author>
<surname>Drepper</surname>
<firstname>Ulrich</firstname>
</author>
<copyright>
<year>2002</year>
<holder></holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 14882:1998 Programming languages - C++
</title>
<copyright>
<year>1998</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
ISO/IEC 9899:1999 Programming languages - C
</title>
<copyright>
<year>1999</year>
<holder>ISO</holder>
</copyright>
</biblioentry>
<biblioentry>
<title>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</title>
<copyright>
<year>1999</year>
<holder>
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.</holder>
</copyright>
<biblioid>
<ulink url="http://www.opennc.org/austin/docreg.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
The C++ Programming Language, Special Edition
</title>
<author>
<surname>Stroustrup</surname>
<firstname>Bjarne</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley, Inc.</holder>
</copyright>
<pagenums>Appendix D</pagenums>
<publisher>
<publishername>
Addison Wesley
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
Standard C++ IOStreams and Locales
</title>
<subtitle>
Advanced Programmer's Guide and Reference
</subtitle>
<author>
<surname>Langer</surname>
<firstname>Angelika</firstname>
</author>
<author>
<surname>Kreft</surname>
<firstname>Klaus</firstname>
</author>
<copyright>
<year>2000</year>
<holder>Addison Wesley Longman, Inc.</holder>
</copyright>
<publisher>
<publishername>
Addison Wesley Longman
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
Java 2 Platform, Standard Edition, v 1.3.1 API Specification
</title>
<pagenums>java.util.Properties, java.text.MessageFormat,
java.util.Locale, java.util.ResourceBundle</pagenums>
<biblioid>
<ulink url="http://java.sun.com/j2se/1.3/docs/api">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<title>
GNU gettext tools, version 0.10.38, Native Language Support
Library and Tools.
</title>
<biblioid>
<ulink url="http://sources.redhat.com/gettext">
</ulink>
</biblioid>
</biblioentry>
</bibliography>
</sect1>

View file

@ -0,0 +1,554 @@
<sect1 id="manual.ext.allocator.mt" xreflabel="mt allocator">
<?dbhtml filename="mt_allocator.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
allocator
</keyword>
</keywordset>
</sect1info>
<title>mt_allocator</title>
<para>
</para>
<sect2 id="allocator.mt.intro" xreflabel="allocator.mt.intro">
<title>Intro</title>
<para>
The mt allocator [hereinafter referred to simply as "the allocator"]
is a fixed size (power of two) allocator that was initially
developed specifically to suit the needs of multi threaded
applications [hereinafter referred to as an MT application]. Over
time the allocator has evolved and been improved in many ways, in
particular it now also does a good job in single threaded
applications [hereinafter referred to as a ST application]. (Note:
In this document, when referring to single threaded applications
this also includes applications that are compiled with gcc without
thread support enabled. This is accomplished using ifdef's on
__GTHREADS). This allocator is tunable, very flexible, and capable
of high-performance.
</para>
<para>
The aim of this document is to describe - from an application point of
view - the "inner workings" of the allocator.
</para>
</sect2>
<sect2 id="allocator.mt.design_issues" xreflabel="allocator.mt.design_issues">
<title>Design Issues</title>
<sect3 id="allocator.mt.overview" xreflabel="allocator.mt.overview">
<title>Overview</title>
<para> There are three general components to the allocator: a datum
describing the characteristics of the memory pool, a policy class
containing this pool that links instantiation types to common or
individual pools, and a class inheriting from the policy class that is
the actual allocator.
</para>
<para>The datum describing pools characteristics is
</para>
<programlisting>
template&lt;bool _Thread&gt;
class __pool
</programlisting>
<para> This class is parametrized on thread support, and is explicitly
specialized for both multiple threads (with <code>bool==true</code>)
and single threads (via <code>bool==false</code>.) It is possible to
use a custom pool datum instead of the default class that is provided.
</para>
<para> There are two distinct policy classes, each of which can be used
with either type of underlying pool datum.
</para>
<programlisting>
template&lt;bool _Thread&gt;
struct __common_pool_policy
template&lt;typename _Tp, bool _Thread&gt;
struct __per_type_pool_policy
</programlisting>
<para> The first policy, <code>__common_pool_policy</code>, implements a
common pool. This means that allocators that are instantiated with
different types, say <code>char</code> and <code>long</code> will both
use the same pool. This is the default policy.
</para>
<para> The second policy, <code>__per_type_pool_policy</code>, implements
a separate pool for each instantiating type. Thus, <code>char</code>
and <code>long</code> will use separate pools. This allows per-type
tuning, for instance.
</para>
<para> Putting this all together, the actual allocator class is
</para>
<programlisting>
template&lt;typename _Tp, typename _Poolp = __default_policy&gt;
class __mt_alloc : public __mt_alloc_base&lt;_Tp&gt;, _Poolp
</programlisting>
<para> This class has the interface required for standard library allocator
classes, namely member functions <code>allocate</code> and
<code>deallocate</code>, plus others.
</para>
</sect3>
</sect2>
<sect2 id="allocator.mt.impl" xreflabel="allocator.mt.impl">
<title>Implementation</title>
<sect3 id="allocator.mt.tune" xreflabel="allocator.mt.tune">
<title>Tunable Parameters</title>
<para>Certain allocation parameters can be modified, or tuned. There
exists a nested <code>struct __pool_base::_Tune</code> that contains all
these parameters, which include settings for
</para>
<itemizedlist>
<listitem><para>Alignment</para></listitem>
<listitem><para>Maximum bytes before calling <code>::operator new</code> directly</para></listitem>
<listitem><para>Minimum bytes</para></listitem>
<listitem><para>Size of underlying global allocations</para></listitem>
<listitem><para>Maximum number of supported threads</para></listitem>
<listitem><para>Migration of deallocations to the global free list</para></listitem>
<listitem><para>Shunt for global <code>new</code> and <code>delete</code></para></listitem>
</itemizedlist>
<para>Adjusting parameters for a given instance of an allocator can only
happen before any allocations take place, when the allocator itself is
initialized. For instance:
</para>
<programlisting>
#include &lt;ext/mt_allocator.h&gt;
struct pod
{
int i;
int j;
};
int main()
{
typedef pod value_type;
typedef __gnu_cxx::__mt_alloc&lt;value_type&gt; allocator_type;
typedef __gnu_cxx::__pool_base::_Tune tune_type;
tune_type t_default;
tune_type t_opt(16, 5120, 32, 5120, 20, 10, false);
tune_type t_single(16, 5120, 32, 5120, 1, 10, false);
tune_type t;
t = allocator_type::_M_get_options();
allocator_type::_M_set_options(t_opt);
t = allocator_type::_M_get_options();
allocator_type a;
allocator_type::pointer p1 = a.allocate(128);
allocator_type::pointer p2 = a.allocate(5128);
a.deallocate(p1, 128);
a.deallocate(p2, 5128);
return 0;
}
</programlisting>
</sect3>
<sect3 id="allocator.mt.init" xreflabel="allocator.mt.init">
<title>Initialization</title>
<para>
The static variables (pointers to freelists, tuning parameters etc)
are initialized as above, or are set to the global defaults.
</para>
<para>
The very first allocate() call will always call the
_S_initialize_once() function. In order to make sure that this
function is called exactly once we make use of a __gthread_once call
in MT applications and check a static bool (_S_init) in ST
applications.
</para>
<para>
The _S_initialize() function:
- If the GLIBCXX_FORCE_NEW environment variable is set, it sets the bool
_S_force_new to true and then returns. This will cause subsequent calls to
allocate() to return memory directly from a new() call, and deallocate will
only do a delete() call.
</para>
<para>
- If the GLIBCXX_FORCE_NEW environment variable is not set, both ST and MT
applications will:
- Calculate the number of bins needed. A bin is a specific power of two size
of bytes. I.e., by default the allocator will deal with requests of up to
128 bytes (or whatever the value of _S_max_bytes is when _S_init() is
called). This means that there will be bins of the following sizes
(in bytes): 1, 2, 4, 8, 16, 32, 64, 128.
- Create the _S_binmap array. All requests are rounded up to the next
"large enough" bin. I.e., a request for 29 bytes will cause a block from
the "32 byte bin" to be returned to the application. The purpose of
_S_binmap is to speed up the process of finding out which bin to use.
I.e., the value of _S_binmap[ 29 ] is initialized to 5 (bin 5 = 32 bytes).
</para>
<para>
- Create the _S_bin array. This array consists of bin_records. There will be
as many bin_records in this array as the number of bins that we calculated
earlier. I.e., if _S_max_bytes = 128 there will be 8 entries.
Each bin_record is then initialized:
- bin_record-&gt;first = An array of pointers to block_records. There will be
as many block_records pointers as there are maximum number of threads
(in a ST application there is only 1 thread, in a MT application there
are _S_max_threads).
This holds the pointer to the first free block for each thread in this
bin. I.e., if we would like to know where the first free block of size 32
for thread number 3 is we would look this up by: _S_bin[ 5 ].first[ 3 ]
The above created block_record pointers members are now initialized to
their initial values. I.e. _S_bin[ n ].first[ n ] = NULL;
</para>
<para>
- Additionally a MT application will:
- Create a list of free thread id's. The pointer to the first entry
is stored in _S_thread_freelist_first. The reason for this approach is
that the __gthread_self() call will not return a value that corresponds to
the maximum number of threads allowed but rather a process id number or
something else. So what we do is that we create a list of thread_records.
This list is _S_max_threads long and each entry holds a size_t thread_id
which is initialized to 1, 2, 3, 4, 5 and so on up to _S_max_threads.
Each time a thread calls allocate() or deallocate() we call
_S_get_thread_id() which looks at the value of _S_thread_key which is a
thread local storage pointer. If this is NULL we know that this is a newly
created thread and we pop the first entry from this list and saves the
pointer to this record in the _S_thread_key variable. The next time
we will get the pointer to the thread_record back and we use the
thread_record-&gt;thread_id as identification. I.e., the first thread that
calls allocate will get the first record in this list and thus be thread
number 1 and will then find the pointer to its first free 32 byte block
in _S_bin[ 5 ].first[ 1 ]
When we create the _S_thread_key we also define a destructor
(_S_thread_key_destr) which means that when the thread dies, this
thread_record is returned to the front of this list and the thread id
can then be reused if a new thread is created.
This list is protected by a mutex (_S_thread_freelist_mutex) which is only
locked when records are removed or added to the list.
</para>
<para>
- Initialize the free and used counters of each bin_record:
- bin_record-&gt;free = An array of size_t. This keeps track of the number
of blocks on a specific thread's freelist in each bin. I.e., if a thread
has 12 32-byte blocks on it's freelists and allocates one of these, this
counter would be decreased to 11.
- bin_record-&gt;used = An array of size_t. This keeps track of the number
of blocks currently in use of this size by this thread. I.e., if a thread
has made 678 requests (and no deallocations...) of 32-byte blocks this
counter will read 678.
The above created arrays are now initialized with their initial values.
I.e. _S_bin[ n ].free[ n ] = 0;
</para>
<para>
- Initialize the mutex of each bin_record: The bin_record-&gt;mutex
is used to protect the global freelist. This concept of a global
freelist is explained in more detail in the section "A multi
threaded example", but basically this mutex is locked whenever a
block of memory is retrieved or returned to the global freelist
for this specific bin. This only occurs when a number of blocks
are grabbed from the global list to a thread specific list or when
a thread decides to return some blocks to the global freelist.
</para>
</sect3>
<sect3 id="allocator.mt.deallocation" xreflabel="allocator.mt.deallocation">
<title>Deallocation Notes</title>
<para> Notes about deallocation. This allocator does not explicitly
release memory. Because of this, memory debugging programs like
valgrind or purify may notice leaks: sorry about this
inconvenience. Operating systems will reclaim allocated memory at
program termination anyway. If sidestepping this kind of noise is
desired, there are three options: use an allocator, like
<code>new_allocator</code> that releases memory while debugging, use
GLIBCXX_FORCE_NEW to bypass the allocator's internal pools, or use a
custom pool datum that releases resources on destruction.
</para>
<para>
On systems with the function <code>__cxa_atexit</code>, the
allocator can be forced to free all memory allocated before program
termination with the member function
<code>__pool_type::_M_destroy</code>. However, because this member
function relies on the precise and exactly-conforming ordering of
static destructors, including those of a static local
<code>__pool</code> object, it should not be used, ever, on systems
that don't have the necessary underlying support. In addition, in
practice, forcing deallocation can be tricky, as it requires the
<code>__pool</code> object to be fully-constructed before the object
that uses it is fully constructed. For most (but not all) STL
containers, this works, as an instance of the allocator is constructed
as part of a container's constructor. However, this assumption is
implementation-specific, and subject to change. For an example of a
pool that frees memory, see the following
<ulink url="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?view=markup">
example.</ulink>
</para>
</sect3>
</sect2>
<sect2 id="allocator.mt.example_single" xreflabel="allocator.mt.example_single">
<title>Single Thread Example</title>
<para>
Let's start by describing how the data on a freelist is laid out in memory.
This is the first two blocks in freelist for thread id 3 in bin 3 (8 bytes):
</para>
<programlisting>
+----------------+
| next* ---------|--+ (_S_bin[ 3 ].first[ 3 ] points here)
| | |
| | |
| | |
+----------------+ |
| thread_id = 3 | |
| | |
| | |
| | |
+----------------+ |
| DATA | | (A pointer to here is what is returned to the
| | | the application when needed)
| | |
| | |
| | |
| | |
| | |
| | |
+----------------+ |
+----------------+ |
| next* |&lt;-+ (If next == NULL it's the last one on the list)
| |
| |
| |
+----------------+
| thread_id = 3 |
| |
| |
| |
+----------------+
| DATA |
| |
| |
| |
| |
| |
| |
| |
+----------------+
</programlisting>
<para>
With this in mind we simplify things a bit for a while and say that there is
only one thread (a ST application). In this case all operations are made to
what is referred to as the global pool - thread id 0 (No thread may be
assigned this id since they span from 1 to _S_max_threads in a MT application).
</para>
<para>
When the application requests memory (calling allocate()) we first look at the
requested size and if this is &gt; _S_max_bytes we call new() directly and return.
</para>
<para>
If the requested size is within limits we start by finding out from which
bin we should serve this request by looking in _S_binmap.
</para>
<para>
A quick look at _S_bin[ bin ].first[ 0 ] tells us if there are any blocks of
this size on the freelist (0). If this is not NULL - fine, just remove the
block that _S_bin[ bin ].first[ 0 ] points to from the list,
update _S_bin[ bin ].first[ 0 ] and return a pointer to that blocks data.
</para>
<para>
If the freelist is empty (the pointer is NULL) we must get memory from the
system and build us a freelist within this memory. All requests for new memory
is made in chunks of _S_chunk_size. Knowing the size of a block_record and
the bytes that this bin stores we then calculate how many blocks we can create
within this chunk, build the list, remove the first block, update the pointer
(_S_bin[ bin ].first[ 0 ]) and return a pointer to that blocks data.
</para>
<para>
Deallocation is equally simple; the pointer is casted back to a block_record
pointer, lookup which bin to use based on the size, add the block to the front
of the global freelist and update the pointer as needed
(_S_bin[ bin ].first[ 0 ]).
</para>
<para>
The decision to add deallocated blocks to the front of the freelist was made
after a set of performance measurements that showed that this is roughly 10%
faster than maintaining a set of "last pointers" as well.
</para>
</sect2>
<sect2 id="allocator.mt.example_multi" xreflabel="allocator.mt.example_multi">
<title>Multiple Thread Example</title>
<para>
In the ST example we never used the thread_id variable present in each block.
Let's start by explaining the purpose of this in a MT application.
</para>
<para>
The concept of "ownership" was introduced since many MT applications
allocate and deallocate memory to shared containers from different
threads (such as a cache shared amongst all threads). This introduces
a problem if the allocator only returns memory to the current threads
freelist (I.e., there might be one thread doing all the allocation and
thus obtaining ever more memory from the system and another thread
that is getting a longer and longer freelist - this will in the end
consume all available memory).
</para>
<para>
Each time a block is moved from the global list (where ownership is
irrelevant), to a threads freelist (or when a new freelist is built
from a chunk directly onto a threads freelist or when a deallocation
occurs on a block which was not allocated by the same thread id as the
one doing the deallocation) the thread id is set to the current one.
</para>
<para>
What's the use? Well, when a deallocation occurs we can now look at
the thread id and find out if it was allocated by another thread id
and decrease the used counter of that thread instead, thus keeping the
free and used counters correct. And keeping the free and used counters
corrects is very important since the relationship between these two
variables decides if memory should be returned to the global pool or
not when a deallocation occurs.
</para>
<para>
When the application requests memory (calling allocate()) we first
look at the requested size and if this is &gt;_S_max_bytes we call new()
directly and return.
</para>
<para>
If the requested size is within limits we start by finding out from which
bin we should serve this request by looking in _S_binmap.
</para>
<para>
A call to _S_get_thread_id() returns the thread id for the calling thread
(and if no value has been set in _S_thread_key, a new id is assigned and
returned).
</para>
<para>
A quick look at _S_bin[ bin ].first[ thread_id ] tells us if there are
any blocks of this size on the current threads freelist. If this is
not NULL - fine, just remove the block that _S_bin[ bin ].first[
thread_id ] points to from the list, update _S_bin[ bin ].first[
thread_id ], update the free and used counters and return a pointer to
that blocks data.
</para>
<para>
If the freelist is empty (the pointer is NULL) we start by looking at
the global freelist (0). If there are blocks available on the global
freelist we lock this bins mutex and move up to block_count (the
number of blocks of this bins size that will fit into a _S_chunk_size)
or until end of list - whatever comes first - to the current threads
freelist and at the same time change the thread_id ownership and
update the counters and pointers. When the bins mutex has been
unlocked, we remove the block that _S_bin[ bin ].first[ thread_id ]
points to from the list, update _S_bin[ bin ].first[ thread_id ],
update the free and used counters, and return a pointer to that blocks
data.
</para>
<para>
The reason that the number of blocks moved to the current threads
freelist is limited to block_count is to minimize the chance that a
subsequent deallocate() call will return the excess blocks to the
global freelist (based on the _S_freelist_headroom calculation, see
below).
</para>
<para>
However if there isn't any memory on the global pool we need to get
memory from the system - this is done in exactly the same way as in a
single threaded application with one major difference; the list built
in the newly allocated memory (of _S_chunk_size size) is added to the
current threads freelist instead of to the global.
</para>
<para>
The basic process of a deallocation call is simple: always add the
block to the front of the current threads freelist and update the
counters and pointers (as described earlier with the specific check of
ownership that causes the used counter of the thread that originally
allocated the block to be decreased instead of the current threads
counter).
</para>
<para>
And here comes the free and used counters to service. Each time a
deallocation() call is made, the length of the current threads
freelist is compared to the amount memory in use by this thread.
</para>
<para>
Let's go back to the example of an application that has one thread
that does all the allocations and one that deallocates. Both these
threads use say 516 32-byte blocks that was allocated during thread
creation for example. Their used counters will both say 516 at this
point. The allocation thread now grabs 1000 32-byte blocks and puts
them in a shared container. The used counter for this thread is now
1516.
</para>
<para>
The deallocation thread now deallocates 500 of these blocks. For each
deallocation made the used counter of the allocating thread is
decreased and the freelist of the deallocation thread gets longer and
longer. But the calculation made in deallocate() will limit the length
of the freelist in the deallocation thread to _S_freelist_headroom %
of it's used counter. In this case, when the freelist (given that the
_S_freelist_headroom is at it's default value of 10%) exceeds 52
(516/10) blocks will be returned to the global pool where the
allocating thread may pick them up and reuse them.
</para>
<para>
In order to reduce lock contention (since this requires this bins
mutex to be locked) this operation is also made in chunks of blocks
(just like when chunks of blocks are moved from the global freelist to
a threads freelist mentioned above). The "formula" used can probably
be improved to further reduce the risk of blocks being "bounced back
and forth" between freelists.
</para>
</sect2>
</sect1>

View file

@ -0,0 +1,143 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.numerics" xreflabel="Numerics">
<?dbhtml filename="numerics.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Numerics</title>
<!-- Chapter 01 : Complex -->
<chapter id="manual.numerics.complex" xreflabel="complex">
<title>Complex</title>
<para>
</para>
<sect1 id="numerics.complex.processing" xreflabel="complex Processing">
<title>complex Processing</title>
<para>
</para>
<para>Using <code>complex&lt;&gt;</code> becomes even more comple- er, sorry,
<emphasis>complicated</emphasis>, with the not-quite-gratuitously-incompatible
addition of complex types to the C language. David Tribble has
compiled a list of C++98 and C99 conflict points; his description of
C's new type versus those of C++ and how to get them playing together
nicely is
<ulink url="http://david.tribble.com/text/cdiffs.htm#C99-complex">here</ulink>.
</para>
<para><code>complex&lt;&gt;</code> is intended to be instantiated with a
floating-point type. As long as you meet that and some other basic
requirements, then the resulting instantiation has all of the usual
math operators defined, as well as definitions of <code>op&lt;&lt;</code>
and <code>op&gt;&gt;</code> that work with iostreams: <code>op&lt;&lt;</code>
prints <code>(u,v)</code> and <code>op&gt;&gt;</code> can read <code>u</code>,
<code>(u)</code>, and <code>(u,v)</code>.
</para>
</sect1>
</chapter>
<!-- Chapter 02 : Generalized Operations -->
<chapter id="manual.numerics.generalized_ops" xreflabel="Generalized Ops">
<title>Generalized Operations</title>
<para>
</para>
<para>There are four generalized functions in the &lt;numeric&gt; header
that follow the same conventions as those in &lt;algorithm&gt;. Each
of them is overloaded: one signature for common default operations,
and a second for fully general operations. Their names are
self-explanatory to anyone who works with numerics on a regular basis:
</para>
<itemizedlist>
<listitem><para><code>accumulate</code></para></listitem>
<listitem><para><code>inner_product</code></para></listitem>
<listitem><para><code>partial_sum</code></para></listitem>
<listitem><para><code>adjacent_difference</code></para></listitem>
</itemizedlist>
<para>Here is a simple example of the two forms of <code>accumulate</code>.
</para>
<programlisting>
int ar[50];
int someval = somefunction();
// ...initialize members of ar to something...
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&lt;int&gt;());
</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 +
someval</code>). The final call uses the second of the two signatures,
and multiplies all the members of the array; here we must obviously
use 1 as a starting value instead of 0.
</para>
<para>The other three functions have similar dual-signature forms.
</para>
</chapter>
<!-- Chapter 03 : Interacting with C -->
<chapter id="manual.numerics.c" xreflabel="Interacting with C">
<title>Interacting with C</title>
<sect1 id="numerics.c.array" xreflabel="Numerics vs. Arrays">
<title>Numerics vs. Arrays</title>
<para>One of the major reasons why FORTRAN can chew through numbers so well
is that it is defined to be free of pointer aliasing, an assumption
that C89 is not allowed to make, and neither is C++98. C99 adds a new
keyword, <code>restrict</code>, to apply to individual pointers. The
C++ solution is contained in the library rather than the language
(although many vendors can be expected to add this to their compilers
as an extension).
</para>
<para>That library solution is a set of two classes, five template classes,
and &quot;a whole bunch&quot; of functions. The classes are required
to be free of pointer aliasing, so compilers can optimize the
daylights out of them the same way that they have been for FORTRAN.
They are collectively called <code>valarray</code>, although strictly
speaking this is only one of the five template classes, and they are
designed to be familiar to people who have worked with the BLAS
libraries before.
</para>
</sect1>
<sect1 id="numerics.c.c99" xreflabel="C99">
<title>C99</title>
<para>In addition to the other topics on this page, we'll note here some
of the C99 features that appear in libstdc++.
</para>
<para>The C99 features depend on the <code>--enable-c99</code> configure flag.
This flag is already on by default, but it can be disabled by the
user. Also, the configuration machinery will disable it if the
necessary support for C99 (e.g., header files) cannot be found.
</para>
<para>As of GCC 3.0, C99 support includes classification functions
such as <code>isnormal</code>, <code>isgreater</code>,
<code>isnan</code>, etc.
The functions used for 'long long' support such as <code>strtoll</code>
are supported, as is the <code>lldiv_t</code> typedef. Also supported
are the wide character functions using 'long long', like
<code>wcstoll</code>.
</para>
</sect1>
</chapter>
</part>

View file

@ -0,0 +1,674 @@
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<chapter id="manual.ext.parallel_mode" xreflabel="Parallel Mode">
<?dbhtml filename="parallel_mode.html"?>
<chapterinfo>
<keywordset>
<keyword>
C++
</keyword>
<keyword>
library
</keyword>
<keyword>
parallel
</keyword>
</keywordset>
</chapterinfo>
<title>Parallel Mode</title>
<para> The libstdc++ parallel mode is an experimental parallel
implementation of many algorithms the C++ Standard Library.
</para>
<para>
Several of the standard algorithms, for instance
<code>std::sort</code>, are made parallel using OpenMP
annotations. These parallel mode constructs and can be invoked by
explicit source declaration or by compiling existing sources with a
specific compiler flag.
</para>
<sect1 id="manual.ext.parallel_mode.intro" xreflabel="Intro">
<title>Intro</title>
<para>The following library components in the include
<code>&lt;numeric&gt;</code> are included in the parallel mode:</para>
<itemizedlist>
<listitem><para><code>std::accumulate</code></para></listitem>
<listitem><para><code>std::adjacent_difference</code></para></listitem>
<listitem><para><code>std::inner_product</code></para></listitem>
<listitem><para><code>std::partial_sum</code></para></listitem>
</itemizedlist>
<para>The following library components in the include
<code>&lt;algorithm&gt;</code> are included in the parallel mode:</para>
<itemizedlist>
<listitem><para><code>std::adjacent_find</code></para></listitem>
<listitem><para><code>std::count</code></para></listitem>
<listitem><para><code>std::count_if</code></para></listitem>
<listitem><para><code>std::equal</code></para></listitem>
<listitem><para><code>std::find</code></para></listitem>
<listitem><para><code>std::find_if</code></para></listitem>
<listitem><para><code>std::find_first_of</code></para></listitem>
<listitem><para><code>std::for_each</code></para></listitem>
<listitem><para><code>std::generate</code></para></listitem>
<listitem><para><code>std::generate_n</code></para></listitem>
<listitem><para><code>std::lexicographical_compare</code></para></listitem>
<listitem><para><code>std::mismatch</code></para></listitem>
<listitem><para><code>std::search</code></para></listitem>
<listitem><para><code>std::search_n</code></para></listitem>
<listitem><para><code>std::transform</code></para></listitem>
<listitem><para><code>std::replace</code></para></listitem>
<listitem><para><code>std::replace_if</code></para></listitem>
<listitem><para><code>std::max_element</code></para></listitem>
<listitem><para><code>std::merge</code></para></listitem>
<listitem><para><code>std::min_element</code></para></listitem>
<listitem><para><code>std::nth_element</code></para></listitem>
<listitem><para><code>std::partial_sort</code></para></listitem>
<listitem><para><code>std::partition</code></para></listitem>
<listitem><para><code>std::random_shuffle</code></para></listitem>
<listitem><para><code>std::set_union</code></para></listitem>
<listitem><para><code>std::set_intersection</code></para></listitem>
<listitem><para><code>std::set_symmetric_difference</code></para></listitem>
<listitem><para><code>std::set_difference</code></para></listitem>
<listitem><para><code>std::sort</code></para></listitem>
<listitem><para><code>std::stable_sort</code></para></listitem>
<listitem><para><code>std::unique_copy</code></para></listitem>
</itemizedlist>
<para>The following library components in the includes
<code>&lt;set&gt;</code> and <code>&lt;map&gt;</code> are included in the parallel mode:</para>
<itemizedlist>
<listitem><para><code>std::(multi_)map/set&lt;T&gt;::(multi_)map/set(Iterator begin, Iterator end)</code> (bulk construction)</para></listitem>
<listitem><para><code>std::(multi_)map/set&lt;T&gt;::insert(Iterator begin, Iterator end)</code> (bulk insertion)</para></listitem>
</itemizedlist>
</sect1>
<sect1 id="manual.ext.parallel_mode.semantics" xreflabel="Semantics">
<title>Semantics</title>
<para> The parallel mode STL algorithms are currently not exception-safe,
i. e. user-defined functors must not throw exceptions.
</para>
<para> Since the current GCC OpenMP implementation does not support
OpenMP parallel regions in concurrent threads,
it is not possible to call parallel STL algorithm in
concurrent threads, either.
It might work with other compilers, though.</para>
</sect1>
<sect1 id="manual.ext.parallel_mode.using" xreflabel="Using">
<title>Using</title>
<sect2 id="parallel_mode.using.parallel_mode" xreflabel="using.parallel_mode">
<title>Using Parallel Mode</title>
<para>To use the libstdc++ parallel mode, compile your application with
the compiler flag <code>-D_GLIBCXX_PARALLEL -fopenmp</code>. This
will link in <code>libgomp</code>, the GNU OpenMP <ulink url="http://gcc.gnu.org/onlinedocs/libgomp">implementation</ulink>,
whose presence is mandatory. In addition, hardware capable of atomic
operations is mandatory. Actually activating these atomic
operations may require explicit compiler flags on some targets
(like sparc and x86), such as <code>-march=i686</code>,
<code>-march=native</code> or <code>-mcpu=v9</code>.
</para>
<para>Note that the <code>_GLIBCXX_PARALLEL</code> define may change the
sizes and behavior of standard class templates such as
<code>std::search</code>, and therefore one can only link code
compiled with parallel mode and code compiled without parallel mode
if no instantiation of a container is passed between the two
translation units. Parallel mode functionality has distinct linkage,
and cannot be confused with normal mode symbols.</para>
</sect2>
<sect2 id="manual.ext.parallel_mode.usings" xreflabel="using.specific">
<title>Using Specific Parallel Components</title>
<para>When it is not feasible to recompile your entire application, or
only specific algorithms need to be parallel-aware, individual
parallel algorithms can be made available explicitly. These
parallel algorithms are functionally equivalent to the standard
drop-in algorithms used in parallel mode, but they are available in
a separate namespace as GNU extensions and may be used in programs
compiled with either release mode or with parallel mode. The
following table provides the names and headers of the parallel
algorithms:
</para>
<table frame='all'>
<title>Parallel Algorithms</title>
<tgroup cols='4' align='left' colsep='1' rowsep='1'>
<colspec colname='c1'></colspec>
<colspec colname='c2'></colspec>
<colspec colname='c3'></colspec>
<colspec colname='c4'></colspec>
<thead>
<row>
<entry>Algorithm</entry>
<entry>Header</entry>
<entry>Parallel algorithm</entry>
<entry>Parallel header</entry>
</row>
</thead>
<tbody>
<row>
<entry><function>std::accumulate</function></entry>
<entry><filename class="headerfile">numeric</filename></entry>
<entry><function>__gnu_parallel::accumulate</function></entry>
<entry><filename class="headerfile">parallel/numeric</filename></entry>
</row>
<row>
<entry><function>std::adjacent_difference</function></entry>
<entry><filename class="headerfile">numeric</filename></entry>
<entry><function>__gnu_parallel::adjacent_difference</function></entry>
<entry><filename class="headerfile">parallel/numeric</filename></entry>
</row>
<row>
<entry><function>std::inner_product</function></entry>
<entry><filename class="headerfile">numeric</filename></entry>
<entry><function>__gnu_parallel::inner_product</function></entry>
<entry><filename class="headerfile">parallel/numeric</filename></entry>
</row>
<row>
<entry><function>std::partial_sum</function></entry>
<entry><filename class="headerfile">numeric</filename></entry>
<entry><function>__gnu_parallel::partial_sum</function></entry>
<entry><filename class="headerfile">parallel/numeric</filename></entry>
</row>
<row>
<entry><function>std::adjacent_find</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::adjacent_find</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::count</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::count</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::count_if</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::count_if</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::equal</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::equal</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::find</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::find</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::find_if</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::find_if</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::find_first_of</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::find_first_of</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::for_each</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::for_each</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::generate</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::generate</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::generate_n</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::generate_n</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::lexicographical_compare</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::lexicographical_compare</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::mismatch</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::mismatch</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::search</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::search</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::search_n</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::search_n</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::transform</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::transform</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::replace</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::replace</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::replace_if</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::replace_if</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::max_element</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::max_element</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::merge</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::merge</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::min_element</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::min_element</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::nth_element</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::nth_element</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::partial_sort</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::partial_sort</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::partition</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::partition</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::random_shuffle</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::random_shuffle</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::set_union</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::set_union</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::set_intersection</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::set_intersection</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::set_symmetric_difference</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::set_symmetric_difference</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::set_difference</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::set_difference</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::sort</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::sort</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::stable_sort</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::stable_sort</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
<row>
<entry><function>std::unique_copy</function></entry>
<entry><filename class="headerfile">algorithm</filename></entry>
<entry><function>__gnu_parallel::unique_copy</function></entry>
<entry><filename class="headerfile">parallel/algorithm</filename></entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
</sect1>
<sect1 id="manual.ext.parallel_mode.design" xreflabel="Design">
<title>Design</title>
<para>
</para>
<sect2 id="manual.ext.parallel_mode.design.intro" xreflabel="Intro">
<title>Interface Basics</title>
<para>All parallel algorithms are intended to have signatures that are
equivalent to the ISO C++ algorithms replaced. For instance, the
<code>std::adjacent_find</code> function is declared as:
</para>
<programlisting>
namespace std
{
template&lt;typename _FIter&gt;
_FIter
adjacent_find(_FIter, _FIter);
}
</programlisting>
<para>
Which means that there should be something equivalent for the parallel
version. Indeed, this is the case:
</para>
<programlisting>
namespace std
{
namespace __parallel
{
template&lt;typename _FIter&gt;
_FIter
adjacent_find(_FIter, _FIter);
...
}
}
</programlisting>
<para>But.... why the elipses?
</para>
<para> The elipses in the example above represent additional overloads
required for the parallel version of the function. These additional
overloads are used to dispatch calls from the ISO C++ function
signature to the appropriate parallel function (or sequential
function, if no parallel functions are deemed worthy), based on either
compile-time or run-time conditions.
</para>
<para> Compile-time conditions are referred to as "embarrassingly
parallel," and are denoted with the appropriate dispatch object, ie
one of <code>__gnu_parallel::sequential_tag</code>,
<code>__gnu_parallel::parallel_tag</code>,
<code>__gnu_parallel::balanced_tag</code>,
<code>__gnu_parallel::unbalanced_tag</code>,
<code>__gnu_parallel::omp_loop_tag</code>, or
<code>__gnu_parallel::omp_loop_static_tag</code>.
</para>
<para> Run-time conditions depend on the hardware being used, the number
of threads available, etc., and are denoted by the use of the enum
<code>__gnu_parallel::parallelism</code>. Values of this enum include
<code>__gnu_parallel::sequential</code>,
<code>__gnu_parallel::parallel_unbalanced</code>,
<code>__gnu_parallel::parallel_balanced</code>,
<code>__gnu_parallel::parallel_omp_loop</code>,
<code>__gnu_parallel::parallel_omp_loop_static</code>, or
<code>__gnu_parallel::parallel_taskqueue</code>.
</para>
<para> Putting all this together, the general view of overloads for the
parallel algorithms look like this:
</para>
<itemizedlist>
<listitem><para>ISO C++ signature</para></listitem>
<listitem><para>ISO C++ signature + sequential_tag argument</para></listitem>
<listitem><para>ISO C++ signature + parallelism argument</para></listitem>
</itemizedlist>
<para> Please note that the implementation may use additional functions
(designated with the <code>_switch</code> suffix) to dispatch from the
ISO C++ signature to the correct parallel version. Also, some of the
algorithms do not have support for run-time conditions, so the last
overload is therefore missing.
</para>
</sect2>
<sect2 id="manual.ext.parallel_mode.design.tuning" xreflabel="Tuning">
<title>Configuration and Tuning</title>
<para> Some algorithm variants can be enabled/disabled/selected at compile-time.
See <ulink url="latest-doxygen/compiletime__settings_8h.html">
<code>&lt;compiletime_settings.h&gt;</code></ulink> and
See <ulink url="latest-doxygen/compiletime__settings_8h.html">
<code>&lt;features.h&gt;</code></ulink> for details.
</para>
<para>
To specify the number of threads to be used for an algorithm,
use <code>omp_set_num_threads</code>.
To force a function to execute sequentially,
even though parallelism is switched on in general,
add <code>__gnu_parallel::sequential_tag()</code>
to the end of the argument list.
</para>
<para>
Parallelism always incurs some overhead. Thus, it is not
helpful to parallelize operations on very small sets of data.
There are measures to avoid parallelizing stuff that is not worth it.
For each algorithm, a minimum problem size can be stated,
usually using the variable
<code>__gnu_parallel::Settings::[algorithm]_minimal_n</code>.
Please see <ulink url="latest-doxygen/settings_8h.html">
<code>&lt;settings.h&gt;</code></ulink> for details.</para>
</sect2>
<sect2 id="manual.ext.parallel_mode.design.impl" xreflabel="Impl">
<title>Implementation Namespaces</title>
<para> One namespace contain versions of code that are explicitly sequential:
<code>__gnu_serial</code>.
</para>
<para> Two namespaces contain the parallel mode:
<code>std::__parallel</code> and <code>__gnu_parallel</code>.
</para>
<para> Parallel implementations of standard components, including
template helpers to select parallelism, are defined in <code>namespace
std::__parallel</code>. For instance, <code>std::transform</code> from
&lt;algorithm&gt; has a parallel counterpart in
<code>std::__parallel::transform</code> from
&lt;parallel/algorithm&gt;. In addition, these parallel
implementations are injected into <code>namespace
__gnu_parallel</code> with using declarations.
</para>
<para> Support and general infrastructure is in <code>namespace
__gnu_parallel</code>.
</para>
<para> More information, and an organized index of types and functions
related to the parallel mode on a per-namespace basis, can be found in
the generated source documentation.
</para>
</sect2>
</sect1>
<sect1 id="manual.ext.parallel_mode.test" xreflabel="Testing">
<title>Testing</title>
<para>
Both the normal conformance and regression tests and the
supplemental performance tests work.
</para>
<para>
To run the conformance and regression tests with the parallel mode
active,
</para>
<screen>
<userinput>make check-parallel</userinput>
</screen>
<para>
The log and summary files for conformance testing are in the
<code>testsuite/parallel</code> directory.
</para>
<para>
To run the performance tests with the parallel mode active,
</para>
<screen>
<userinput>check-performance-parallel</userinput>
</screen>
<para>
The result file for performance testing are in the
<code>testsuite</code> directory, in the file
<code>libstdc++_performance.sum</code>. In addition, the
policy-based containers have their own visualizations, which have
additional software dependencies than the usual bare-boned text
file, and can be generated by using the <code>make
doc-performance</code> rule in the testsuite's Makefile.
</para>
</sect1>
<bibliography id="parallel_mode.biblio" xreflabel="parallel_mode.biblio">
<title>Bibliography</title>
<biblioentry>
<title>
Parallelization of Bulk Operations for STL Dictionaries
</title>
<author>
<firstname>Johannes</firstname>
<surname>Singler</surname>
</author>
<author>
<firstname>Leonor</firstname>
<surname>Frias</surname>
</author>
<copyright>
<year>2007</year>
<holder></holder>
</copyright>
<publisher>
<publishername>
Workshop on Highly Parallel Processing on a Chip (HPPC) 2007. (LNCS)
</publishername>
</publisher>
</biblioentry>
<biblioentry>
<title>
The Multi-Core Standard Template Library
</title>
<author>
<firstname>Johannes</firstname>
<surname>Singler</surname>
</author>
<author>
<firstname>Peter</firstname>
<surname>Sanders</surname>
</author>
<author>
<firstname>Felix</firstname>
<surname>Putze</surname>
</author>
<copyright>
<year>2007</year>
<holder></holder>
</copyright>
<publisher>
<publishername>
Euro-Par 2007: Parallel Processing. (LNCS 4641)
</publishername>
</publisher>
</biblioentry>
</bibliography>
</chapter>

View file

@ -0,0 +1,580 @@
<sect1 id="manual.util.memory.shared_ptr" xreflabel="shared_ptr">
<?dbhtml filename="shared_ptr.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
shared_ptr
</keyword>
</keywordset>
</sect1info>
<title>shared_ptr</title>
<para>
The shared_ptr class template stores a pointer, usually obtained via new,
and implements shared ownership semantics.
</para>
<sect2 id="shared_ptr.req" xreflabel="shared_ptr.req">
<title>Requirements</title>
<para>
</para>
<para>
The standard deliberately doesn't require a reference-counted
implementation, allowing other techniques such as a
circular-linked-list.
</para>
<para>
At the time of writing the C++0x working paper doesn't mention how
threads affect shared_ptr, but it is likely to follow the existing
practice set by <classname>boost::shared_ptr</classname>. The
shared_ptr in libstdc++ is derived from Boost's, so the same rules
apply.
</para>
<para>
</para>
</sect2>
<sect2 id="shared_ptr.design_issues" xreflabel="shared_ptr.design_issues">
<title>Design Issues</title>
<para>
The <classname>shared_ptr</classname> code is kindly donated to GCC by the Boost
project and the original authors of the code. The basic design and
algorithms are from Boost, the notes below describe details specific to
the GCC implementation. Names have been uglified in this implementation,
but the design should be recognisable to anyone familiar with the Boost
1.32 shared_ptr.
</para>
<para>
The basic design is an abstract base class, <code>_Sp_counted_base</code> that
does the reference-counting and calls virtual functions when the count
drops to zero.
Derived classes override those functions to destroy resources in a context
where the correct dynamic type is known. This is an application of the
technique known as type erasure.
</para>
</sect2>
<sect2 id="shared_ptr.impl" xreflabel="shared_ptr.impl">
<title>Implementation</title>
<sect3>
<title>Class Hierarchy</title>
<para>
A <classname>shared_ptr&lt;T&gt;</classname> contains a pointer of
type <type>T*</type> and an object of type
<classname>__shared_count</classname>. The shared_count contains a
pointer of type <type>_Sp_counted_base*</type> which points to the
object that maintains the reference-counts and destroys the managed
resource.
</para>
<variablelist>
<varlistentry>
<term><classname>_Sp_counted_base&lt;Lp&gt;</classname></term>
<listitem>
<para>
The base of the hierarchy is parameterized on the lock policy alone.
_Sp_counted_base doesn't depend on the type of pointer being managed,
it only maintains the reference counts and calls virtual functions when
the counts drop to zero. The managed object is destroyed when the last
strong reference is dropped, but the _Sp_counted_base itself must exist
until the last weak reference is dropped.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><classname>_Sp_counted_base_impl&lt;Ptr, Deleter, Lp&gt;</classname></term>
<listitem>
<para>
Inherits from _Sp_counted_base and stores a pointer of type <type>Ptr</type>
and a deleter of type <code>Deleter</code>. <code>_Sp_deleter</code> is
used when the user doesn't supply a custom deleter. Unlike Boost's, this
default deleter is not "checked" because GCC already issues a warning if
<function>delete</function> is used with an incomplete type.
This is the only derived type used by <classname>shared_ptr&lt;Ptr&gt;</classname>
and it is never used by <classname>shared_ptr</classname>, which uses one of
the following types, depending on how the shared_ptr is constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><classname>_Sp_counted_ptr&lt;Ptr, Lp&gt;</classname></term>
<listitem>
<para>
Inherits from _Sp_counted_base and stores a pointer of type <type>Ptr</type>,
which is passed to <function>delete</function> when the last reference is dropped.
This is the simplest form and is used when there is no custom deleter or
allocator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><classname>_Sp_counted_deleter&lt;Ptr, Deleter, Alloc&gt;</classname></term>
<listitem>
<para>
Inherits from _Sp_counted_ptr and adds support for custom deleter and
allocator. Empty Base Optimization is used for the allocator. This class
is used even when the user only provides a custom deleter, in which case
<classname>allocator</classname> is used as the allocator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><classname>_Sp_counted_ptr_inplace&lt;Tp, Alloc, Lp&gt;</classname></term>
<listitem>
<para>
Used by <code>allocate_shared</code> and <code>make_shared</code>.
Contains aligned storage to hold an object of type <type>Tp</type>,
which is constructed in-place with placement <function>new</function>.
Has a variadic template constructor allowing any number of arguments to
be forwarded to <type>Tp</type>'s constructor.
Unlike the other <classname>_Sp_counted_*</classname> classes, this one is parameterized on the
type of object, not the type of pointer; this is purely a convenience
that simplifies the implementation slightly.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect3>
<sect3>
<title>Thread Safety</title>
<para>
The interface of <classname>tr1::shared_ptr</classname> was extended for C++0x
with support for rvalue-references and the other features from
N2351. As with other libstdc++ headers shared by TR1 and C++0x,
boost_shared_ptr.h uses conditional compilation, based on the macros
<constant>_GLIBCXX_INCLUDE_AS_CXX0X</constant> and
<constant>_GLIBCXX_INCLUDE_AS_TR1</constant>, to enable and disable
features.
</para>
<para>
C++0x-only features are: rvalue-ref/move support, allocator support,
aliasing constructor, make_shared &amp; allocate_shared. Additionally,
the constructors taking <classname>auto_ptr</classname> parameters are
deprecated in C++0x mode.
</para>
<para>
The
<ulink url="http://boost.org/libs/smart_ptr/shared_ptr.htm#ThreadSafety">Thread
Safety</ulink> section of the Boost shared_ptr documentation says "shared_ptr
objects offer the same level of thread safety as built-in types."
The implementation must ensure that concurrent updates to separate shared_ptr
instances are correct even when those instances share a reference count e.g.
</para>
<programlisting>
shared_ptr&lt;A&gt; a(new A);
shared_ptr&lt;A&gt; b(a);
// Thread 1 // Thread 2
a.reset(); b.reset();
</programlisting>
<para>
The dynamically-allocated object must be destroyed by exactly one of the
threads. Weak references make things even more interesting.
The shared state used to implement shared_ptr must be transparent to the
user and invariants must be preserved at all times.
The key pieces of shared state are the strong and weak reference counts.
Updates to these need to be atomic and visible to all threads to ensure
correct cleanup of the managed resource (which is, after all, shared_ptr's
job!)
On multi-processor systems memory synchronisation may be needed so that
reference-count updates and the destruction of the managed resource are
race-free.
</para>
<para>
The function <function>_Sp_counted_base::_M_add_ref_lock()</function>, called when
obtaining a shared_ptr from a weak_ptr, has to test if the managed
resource still exists and either increment the reference count or throw
<classname>bad_weak_ptr</classname>.
In a multi-threaded program there is a potential race condition if the last
reference is dropped (and the managed resource destroyed) between testing
the reference count and incrementing it, which could result in a shared_ptr
pointing to invalid memory.
</para>
<para>
The Boost shared_ptr (as used in GCC) features a clever lock-free
algorithm to avoid the race condition, but this relies on the
processor supporting an atomic <emphasis>Compare-And-Swap</emphasis>
instruction. For other platforms there are fall-backs using mutex
locks. Boost (as of version 1.35) includes several different
implementations and the preprocessor selects one based on the
compiler, standard library, platform etc. For the version of
shared_ptr in libstdc++ the compiler and library are fixed, which
makes things much simpler: we have an atomic CAS or we don't, see Lock
Policy below for details.
</para>
</sect3>
<sect3>
<title>Selecting Lock Policy</title>
<para>
</para>
<para>
There is a single <classname>_Sp_counted_base</classname> class,
which is a template parameterized on the enum
<type>__gnu_cxx::_Lock_policy</type>. The entire family of classes is
parameterized on the lock policy, right up to
<classname>__shared_ptr</classname>, <classname>__weak_ptr</classname> and
<classname>__enable_shared_from_this</classname>. The actual
<classname>std::shared_ptr</classname> class inherits from
<classname>__shared_ptr</classname> with the lock policy parameter
selected automatically based on the thread model and platform that
libstdc++ is configured for, so that the best available template
specialization will be used. This design is necessary because it would
not be conforming for <classname>shared_ptr</classname> to have an
extra template parameter, even if it had a default value. The
available policies are:
</para>
<orderedlist>
<listitem>
<para>
<type>_S_Atomic</type>
</para>
<para>
Selected when GCC supports a builtin atomic compare-and-swap operation
on the target processor (see <ulink url="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html">Atomic
Builtins</ulink>.) The reference counts are maintained using a lock-free
algorithm and GCC's atomic builtins, which provide the required memory
synchronisation.
</para>
</listitem>
<listitem>
<para>
<type>_S_Mutex</type>
</para>
<para>
The _Sp_counted_base specialization for this policy contains a mutex,
which is locked in add_ref_lock(). This policy is used when GCC's atomic
builtins aren't available so explicit memory barriers are needed in places.
</para>
</listitem>
<listitem>
<para>
<type>_S_Single</type>
</para>
<para>
This policy uses a non-reentrant add_ref_lock() with no locking. It is
used when libstdc++ is built without <literal>--enable-threads</literal>.
</para>
</listitem>
</orderedlist>
<para>
For all three policies, reference count increments and
decrements are done via the functions in
<filename>ext/atomicity.h</filename>, which detect if the program
is multi-threaded. If only one thread of execution exists in
the program then less expensive non-atomic operations are used.
</para>
</sect3>
<sect3>
<title>Dual C++0x and TR1 Implementation</title>
<para>
The classes derived from <classname>_Sp_counted_base</classname> (see Class Hierarchy
below) and <classname>__shared_count</classname> are implemented separately for C++0x
and TR1, in <filename>bits/boost_sp_shared_count.h</filename> and
<filename>tr1/boost_sp_shared_count.h</filename> respectively. All other classes
including <classname>_Sp_counted_base</classname> are shared by both implementations.
</para>
<para>
The TR1 implementation is considered relatively stable, so is unlikely to
change unless bug fixes require it. If the code that is common to both
C++0x and TR1 modes needs to diverge further then it might be necessary to
duplicate additional classes and only make changes to the C++0x versions.
</para>
</sect3>
<sect3>
<title>Related functions and classes</title>
<variablelist>
<varlistentry>
<term><code>dynamic_pointer_cast</code>, <code>static_pointer_cast</code>,
<code>const_pointer_cast</code></term>
<listitem>
<para>
As noted in N2351, these functions can be implemented non-intrusively using
the alias constructor. However the aliasing constructor is only available
in C++0x mode, so in TR1 mode these casts rely on three non-standard
constructors in shared_ptr and __shared_ptr.
In C++0x mode these constructors and the related tag types are not needed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>enable_shared_from_this</code></term>
<listitem>
<para>
The clever overload to detect a base class of type
<code>enable_shared_from_this</code> comes straight from Boost.
There is an extra overload for <code>__enable_shared_from_this</code> to
work smoothly with <code>__shared_ptr&lt;Tp, Lp&gt;</code> using any lock
policy.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>make_shared</code>, <code>allocate_shared</code></term>
<listitem>
<para>
<code>make_shared</code> simply forwards to <code>allocate_shared</code>
with <code>std::allocator</code> as the allocator.
Although these functions can be implemented non-intrusively using the
alias constructor, if they have access to the implementation then it is
possible to save storage and reduce the number of heap allocations. The
newly constructed object and the _Sp_counted_* can be allocated in a single
block and the standard says implementations are "encouraged, but not required,"
to do so. This implementation provides additional non-standard constructors
(selected with the type <code>_Sp_make_shared_tag</code>) which create an
object of type <code>_Sp_counted_ptr_inplace</code> to hold the new object.
The returned <code>shared_ptr&lt;A&gt;</code> needs to know the address of the
new <code>A</code> object embedded in the <code>_Sp_counted_ptr_inplace</code>,
but it has no way to access it.
This implementation uses a "covert channel" to return the address of the
embedded object when <code>get_deleter&lt;_Sp_make_shared_tag&gt;()</code>
is called. Users should not try to use this.
As well as the extra constructors, this implementation also needs some
members of _Sp_counted_deleter to be protected where they could otherwise
be private.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect3>
</sect2>
<!--- XXX
<listitem>
<type>_Sp_counted_base&lt;Lp&gt;</type>
<para>
The base of the hierarchy is parameterized on the lock policy alone.
_Sp_counted_base doesn't depend on the type of pointer being managed,
it only maintains the reference counts and calls virtual functions when
the counts drop to zero. The managed object is destroyed when the last
strong reference is dropped, but the _Sp_counted_base itself must exist
until the last weak reference is dropped.
</para>
</listitem>
<listitem>
<type>_Sp_counted_base_impl&lt;Ptr, Deleter, Lp&gt;</type>
<para>
Inherits from _Sp_counted_base and stores a pointer of type <code>Ptr</code>
and a deleter of type <code>Deleter</code>. <code>_Sp_deleter</code> is
used when the user doesn't supply a custom deleter. Unlike Boost's, this
default deleter is not "checked" because GCC already issues a warning if
<code>delete</code> is used with an incomplete type.
This is the only derived type used by <code>tr1::shared_ptr&lt;Ptr&gt;</code>
and it is never used by <code>std::shared_ptr</code>, which uses one of
the following types, depending on how the shared_ptr is constructed.
</para>
</listitem>
-->
<sect2 id="shared_ptr.using" xreflabel="shared_ptr.using">
<title>Use</title>
<sect3>
<title>Examples</title>
<para>
Examples of use can be found in the testsuite, under
<filename class="directory">testsuite/tr1/2_general_utilities/shared_ptr</filename>.
</para>
</sect3>
<sect3>
<title>Unresolved Issues</title>
<para>
The resolution to C++ Standard Library issue <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#674">674</ulink>,
"shared_ptr interface changes for consistency with N1856" will
need to be implemented after it is accepted into the working
paper. Issue <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#743">743</ulink>
might also require changes.
</para>
<para>
The <type>_S_single</type> policy uses atomics when used in MT
code, because it uses the same dispatcher functions that check
<function>__gthread_active_p()</function>. This could be
addressed by providing template specialisations for some members
of <classname>_Sp_counted_base&lt;_S_single&gt;</classname>.
</para>
<para>
Unlike Boost, this implementation does not use separate classes
for the pointer+deleter and pointer+deleter+allocator cases in
C++0x mode, combining both into _Sp_counted_deleter and using
<classname>allocator</classname> when the user doesn't specify
an allocator. If it was found to be beneficial an additional
class could easily be added. With the current implementation,
the _Sp_counted_deleter and __shared_count constructors taking a
custom deleter but no allocator are technically redundant and
could be removed, changing callers to always specify an
allocator. If a separate pointer+deleter class was added the
__shared_count constructor would be needed, so it has been kept
for now.
</para>
<para>
The hack used to get the address of the managed object from
<function>_Sp_counted_ptr_inplace::_M_get_deleter()</function>
is accessible to users. This could be prevented if
<function>get_deleter&lt;_Sp_make_shared_tag&gt;()</function>
always returned NULL, since the hack only needs to work at a
lower level, not in the public API. This wouldn't be difficult,
but hasn't been done since there is no danger of accidental
misuse: users already know they are relying on unsupported
features if they refer to implementation details such as
_Sp_make_shared_tag.
</para>
<para>
tr1::_Sp_deleter could be a private member of tr1::__shared_count but it
would alter the ABI.
</para>
<para>
Exposing the alias constructor in TR1 mode could simplify the
*_pointer_cast functions. Constructor could be private in TR1
mode, with the cast functions as friends.
</para>
</sect3>
</sect2>
<sect2 id="shared_ptr.ack" xreflabel="shared_ptr.ack">
<title>Acknowledgments</title>
<para>
The original authors of the Boost shared_ptr, which is really nice
code to work with, Peter Dimov in particular for his help and
invaluable advice on thread safety. Phillip Jordan and Paolo
Carlini for the lock policy implementation.
</para>
</sect2>
<bibliography id="shared_ptr.biblio" xreflabel="shared_ptr.biblio">
<title>Bibliography</title>
<biblioentry>
<abbrev>
n2351
</abbrev>
<title>
Improving shared_ptr for C++0x, Revision 2
</title>
<subtitle>
N2351
</subtitle>
<biblioid>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<abbrev>
n2456
</abbrev>
<title>
C++ Standard Library Active Issues List (Revision R52)
</title>
<subtitle>
N2456
</subtitle>
<biblioid>
<ulink url="http://open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2456.html">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<abbrev>
n2461
</abbrev>
<title>
Working Draft, Standard for Programming Language C++
</title>
<subtitle>
N2461
</subtitle>
<biblioid>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">
</ulink>
</biblioid>
</biblioentry>
<biblioentry>
<abbrev>
boostshared_ptr
</abbrev>
<title>
Boost C++ Libraries documentation - shared_ptr class template
</title>
<subtitle>
N2461
</subtitle>
<biblioid>
<ulink url="http://boost.org/libs/smart_ptr/shared_ptr.htm">shared_ptr
</ulink>
</biblioid>
</biblioentry>
</bibliography>
</sect1>

View file

@ -0,0 +1,111 @@
<?xml version='1.0'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<book id="manual-index" xreflabel="manual-index">
<?dbhtml dir="manual"?>
<?dbhtml filename="spine.html"?>
<title>The GNU C++ Library</title>
<bookinfo>
<copyright>
<year>2008</year>
<holder>
<ulink url="http://fsf.org">FSF</ulink>
</holder>
</copyright>
<legalnotice>
<para>
<ulink url="17_intro/license.html">License</ulink>
</para>
</legalnotice>
</bookinfo>
<!-- Part 01 : Intro -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="intro.xml">
</xi:include>
<!-- Part 02 : Support -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="support.xml">
</xi:include>
<!-- Part 03 : Diagnostics -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="diagnostics.xml">
</xi:include>
<!-- Part 04 : Utilities -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="utilities.xml">
</xi:include>
<!-- Part 05 : Strings -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="strings.xml">
</xi:include>
<!-- Part 06 : Localization -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="localization.xml">
</xi:include>
<!-- Part 07 : Containers -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="containers.xml">
</xi:include>
<!-- Part 08 : Iterators -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="iterators.xml">
</xi:include>
<!-- Part 09 : Algorithms -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="algorithms.xml">
</xi:include>
<!-- Part 10 : Numerics -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="numerics.xml">
</xi:include>
<!-- Part 11 : Input Output -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="io.xml">
</xi:include>
<!-- Part 12 : Extensions -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="extensions.xml">
</xi:include>
<!-- Appendix A -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="appendix_contributing.xml">
</xi:include>
<!-- Appendix B -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="appendix_porting.xml">
</xi:include>
<!-- Appendix C -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="appendix_free.xml">
</xi:include>
<!-- Appendix D -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="../gnu/gpl-2.0.xml">
</xi:include>
<!-- Appendix E -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="../gnu/fdl-1.2.xml">
</xi:include>
</book>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,495 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.strings" xreflabel="Strings">
<?dbhtml filename="strings.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Strings</title>
<!-- Chapter 01 : Character Traits -->
<!-- Chapter 02 : String Classes -->
<chapter id="manual.strings.string" xreflabel="string">
<title>String Classes</title>
<sect1 id="strings.string.simple" xreflabel="Simple Transformations">
<title>Simple Transformations</title>
<para>
Here are Standard, simple, and portable ways to perform common
transformations on a <code>string</code> instance, such as
&quot;convert to all upper case.&quot; The word transformations
is especially apt, because the standard template function
<code>transform&lt;&gt;</code> is used.
</para>
<para>
This code will go through some iterations. Here's a simiple
version:
</para>
<programlisting>
#include &lt;string&gt;
#include &lt;algorithm&gt;
#include &lt;cctype&gt; // old &lt;ctype.h&gt;
struct ToLower
{
char operator() (char c) const { return std::tolower(c); }
};
struct ToUpper
{
char operator() (char c) const { return std::toupper(c); }
};
int main()
{
std::string s ("Some Kind Of Initial Input Goes Here");
// Change everything into upper case
std::transform (s.begin(), s.end(), s.begin(), ToUpper());
// Change everything into lower case
std::transform (s.begin(), s.end(), s.begin(), ToLower());
// Change everything back into upper case, but store the
// result in a different string
std::string capital_s;
capital_s.resize(s.size());
std::transform (s.begin(), s.end(), capital_s.begin(), ToUpper());
}
</programlisting>
<para>
<emphasis>Note</emphasis> that these calls all
involve the global C locale through the use of the C functions
<code>toupper/tolower</code>. This is absolutely guaranteed to work --
but <emphasis>only</emphasis> if the string contains <emphasis>only</emphasis> characters
from the basic source character set, and there are <emphasis>only</emphasis>
96 of those. Which means that not even all English text can be
represented (certain British spellings, proper names, and so forth).
So, if all your input forevermore consists of only those 96
characters (hahahahahaha), then you're done.
</para>
<para><emphasis>Note</emphasis> that the
<code>ToUpper</code> and <code>ToLower</code> function objects
are needed because <code>toupper</code> and <code>tolower</code>
are overloaded names (declared in <code>&lt;cctype&gt;</code> and
<code>&lt;locale&gt;</code>) so the template-arguments for
<code>transform&lt;&gt;</code> cannot be deduced, as explained in
<ulink url="http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html">this
message</ulink>.
<!-- section 14.8.2.4 clause 16 in ISO 14882:1998 -->
At minimum, you can write short wrappers like
</para>
<programlisting>
char toLower (char c)
{
return std::tolower(c);
} </programlisting>
<para>The correct method is to use a facet for a particular locale
and call its conversion functions. These are discussed more in
Chapter 22; the specific part is
<ulink url="../22_locale/howto.html#7">Correct Transformations</ulink>,
which shows the final version of this code. (Thanks to James Kanze
for assistance and suggestions on all of this.)
</para>
<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>
std::string str (" \t blah blah blah \n ");
// trim leading whitespace
string::size_type notwhite = str.find_first_not_of(" \t\n");
str.erase(0,notwhite);
// trim trailing whitespace
notwhite = str.find_last_not_of(" \t\n");
str.erase(notwhite+1); </programlisting>
<para>Obviously, the calls to <code>find</code> could be inserted directly
into the calls to <code>erase</code>, in case your compiler does not
optimize named temporaries out of existence.
</para>
</sect1>
<sect1 id="strings.string.case" xreflabel="Case Sensitivity">
<title>Case Sensivitity</title>
<para>
</para>
<para>The well-known-and-if-it-isn't-well-known-it-ought-to-be
<ulink url="http://www.gotw.ca/gotw/">Guru of the Week</ulink>
discussions held on Usenet covered this topic in January of 1998.
Briefly, the challenge was, <quote>write a 'ci_string' class which
is identical to the standard 'string' class, but is
case-insensitive in the same way as the (common but nonstandard)
C function stricmp()</quote>.
</para>
<programlisting>
ci_string s( "AbCdE" );
// case insensitive
assert( s == "abcde" );
assert( s == "ABCDE" );
// still case-preserving, of course
assert( strcmp( s.c_str(), "AbCdE" ) == 0 );
assert( strcmp( s.c_str(), "abcde" ) != 0 ); </programlisting>
<para>The solution is surprisingly easy. The original answer was
posted on Usenet, and a revised version appears in Herb Sutter's
book <emphasis>Exceptional C++</emphasis> and on his website as <ulink url="http://www.gotw.ca/gotw/029.htm">GotW 29</ulink>.
</para>
<para>See? Told you it was easy!</para>
<para>
<emphasis>Added June 2000:</emphasis> The May 2000 issue of C++
Report contains a fascinating <ulink
url="http://lafstern.org/matt/col2_new.pdf"> article</ulink> by
Matt Austern (yes, <emphasis>the</emphasis> Matt Austern) on why
case-insensitive comparisons are not as easy as they seem, and
why creating a class is the <emphasis>wrong</emphasis> way to go
about it in production code. (The GotW answer mentions one of
the principle difficulties; his article mentions more.)
</para>
<para>Basically, this is &quot;easy&quot; only if you ignore some things,
things which may be too important to your program to ignore. (I chose
to ignore them when originally writing this entry, and am surprised
that nobody ever called me on it...) The GotW question and answer
remain useful instructional tools, however.
</para>
<para><emphasis>Added September 2000:</emphasis> James Kanze provided a link to a
<ulink url="http://www.unicode.org/unicode/reports/tr21/">Unicode
Technical Report discussing case handling</ulink>, which provides some
very good information.
</para>
</sect1>
<sect1 id="strings.string.character_types" xreflabel="Arbitrary Characters">
<title>Arbitrary Character Types</title>
<para>
</para>
<para>The <code>std::basic_string</code> is tantalizingly general, in that
it is parameterized on the type of the characters which it holds.
In theory, you could whip up a Unicode character class and instantiate
<code>std::basic_string&lt;my_unicode_char&gt;</code>, or assuming
that integers are wider than characters on your platform, maybe just
declare variables of type <code>std::basic_string&lt;int&gt;</code>.
</para>
<para>That's the theory. Remember however that basic_string has additional
type parameters, which take default arguments based on the character
type (called <code>CharT</code> here):
</para>
<programlisting>
template &lt;typename CharT,
typename Traits = char_traits&lt;CharT&gt;,
typename Alloc = allocator&lt;CharT&gt; &gt;
class basic_string { .... };</programlisting>
<para>Now, <code>allocator&lt;CharT&gt;</code> will probably Do The Right
Thing by default, unless you need to implement your own allocator
for your characters.
</para>
<para>But <code>char_traits</code> takes more work. The char_traits
template is <emphasis>declared</emphasis> but not <emphasis>defined</emphasis>.
That means there is only
</para>
<programlisting>
template &lt;typename CharT&gt;
struct char_traits
{
static void foo (type1 x, type2 y);
...
};</programlisting>
<para>and functions such as char_traits&lt;CharT&gt;::foo() are not
actually defined anywhere for the general case. The C++ standard
permits this, because writing such a definition to fit all possible
CharT's cannot be done.
</para>
<para>The C++ standard also requires that char_traits be specialized for
instantiations of <code>char</code> and <code>wchar_t</code>, and it
is these template specializations that permit entities like
<code>basic_string&lt;char,char_traits&lt;char&gt;&gt;</code> to work.
</para>
<para>If you want to use character types other than char and wchar_t,
such as <code>unsigned char</code> and <code>int</code>, you will
need suitable specializations for them. For a time, in earlier
versions of GCC, there was a mostly-correct implementation that
let programmers be lazy but it broke under many situations, so it
was removed. GCC 3.4 introduced a new implementation that mostly
works and can be specialized even for <code>int</code> and other
built-in types.
</para>
<para>If you want to use your own special character class, then you have
<ulink url="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00163.html">a lot
of work to do</ulink>, especially if you with to use i18n features
(facets require traits information but don't have a traits argument).
</para>
<para>Another example of how to specialize char_traits was given <ulink url="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00260.html">on the
mailing list</ulink> and at a later date was put into the file <code>
include/ext/pod_char_traits.h</code>. We agree
that the way it's used with basic_string (scroll down to main())
doesn't look nice, but that's because <ulink url="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00236.html">the
nice-looking first attempt</ulink> turned out to <ulink url="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00242.html">not
be conforming C++</ulink>, due to the rule that CharT must be a POD.
(See how tricky this is?)
</para>
</sect1>
<sect1 id="strings.string.token" xreflabel="Tokenizing">
<title>Tokenizing</title>
<para>
</para>
<para>The Standard C (and C++) function <code>strtok()</code> leaves a lot to
be desired in terms of user-friendliness. It's unintuitive, it
destroys the character string on which it operates, and it requires
you to handle all the memory problems. But it does let the client
code decide what to use to break the string into pieces; it allows
you to choose the &quot;whitespace,&quot; so to speak.
</para>
<para>A C++ implementation lets us keep the good things and fix those
annoyances. The implementation here is more intuitive (you only
call it once, not in a loop with varying argument), it does not
affect the original string at all, and all the memory allocation
is handled for you.
</para>
<para>It's called stringtok, and it's a template function. Sources are
as below, in a less-portable form than it could be, to keep this
example simple (for example, see the comments on what kind of
string it will accept).
</para>
<programlisting>
#include &lt;string&gt;
template &lt;typename Container&gt;
void
stringtok(Container &amp;container, string const &amp;in,
const char * const delimiters = " \t\n")
{
const string::size_type len = in.length();
string::size_type i = 0;
while (i &lt; len)
{
// Eat leading whitespace
i = in.find_first_not_of(delimiters, i);
if (i == string::npos)
return; // Nothing left but white space
// Find the end of the token
string::size_type j = in.find_first_of(delimiters, i);
// Push token
if (j == string::npos)
{
container.push_back(in.substr(i));
return;
}
else
container.push_back(in.substr(i, j-i));
// Set up for next loop
i = j + 1;
}
}
</programlisting>
<para>
The author uses a more general (but less readable) form of it for
parsing command strings and the like. If you compiled and ran this
code using it:
</para>
<programlisting>
std::list&lt;string&gt; ls;
stringtok (ls, " this \t is\t\n a test ");
for (std::list&lt;string&gt;const_iterator i = ls.begin();
i != ls.end(); ++i)
{
std::cerr &lt;&lt; ':' &lt;&lt; (*i) &lt;&lt; ":\n";
} </programlisting>
<para>You would see this as output:
</para>
<programlisting>
:this:
:is:
:a:
:test: </programlisting>
<para>with all the whitespace removed. The original <code>s</code> is still
available for use, <code>ls</code> will clean up after itself, and
<code>ls.size()</code> will return how many tokens there were.
</para>
<para>As always, there is a price paid here, in that stringtok is not
as fast as strtok. The other benefits usually outweigh that, however.
<ulink url="stringtok_std_h.txt">Another version of stringtok is given
here</ulink>, suggested by Chris King and tweaked by Petr Prikryl,
and this one uses the
transformation functions mentioned below. If you are comfortable
with reading the new function names, this version is recommended
as an example.
</para>
<para><emphasis>Added February 2001:</emphasis> Mark Wilden pointed out that the
standard <code>std::getline()</code> function can be used with standard
<ulink url="../27_io/howto.html">istringstreams</ulink> to perform
tokenizing as well. Build an istringstream from the input text,
and then use std::getline with varying delimiters (the three-argument
signature) to extract tokens into a string.
</para>
</sect1>
<sect1 id="strings.string.shrink" xreflabel="Shrink to Fit">
<title>Shrink to Fit</title>
<para>
</para>
<para>From GCC 3.4 calling <code>s.reserve(res)</code> on a
<code>string s</code> with <code>res &lt; s.capacity()</code> will
reduce the string's capacity to <code>std::max(s.size(), res)</code>.
</para>
<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>
std::string(str.data(), str.size()).swap(str);
</programlisting>
<para>This is similar to the idiom for reducing a <code>vector</code>'s
memory usage (see <ulink url='../faq/index.html#5_9'>FAQ 5.9</ulink>) but
the regular copy constructor cannot be used because libstdc++'s
<code>string</code> is Copy-On-Write.
</para>
</sect1>
<sect1 id="strings.string.Cstring" xreflabel="CString (MFC)">
<title>CString (MFC)</title>
<para>
</para>
<para>A common lament seen in various newsgroups deals with the Standard
string class as opposed to the Microsoft Foundation Class called
CString. Often programmers realize that a standard portable
answer is better than a proprietary nonportable one, but in porting
their application from a Win32 platform, they discover that they
are relying on special functions offered by the CString class.
</para>
<para>Things are not as bad as they seem. In
<ulink url="http://gcc.gnu.org/ml/gcc/1999-04n/msg00236.html">this
message</ulink>, Joe Buck points out a few very important things:
</para>
<itemizedlist>
<listitem><para>The Standard <code>string</code> supports all the operations
that CString does, with three exceptions.
</para></listitem>
<listitem><para>Two of those exceptions (whitespace trimming and case
conversion) are trivial to implement. In fact, we do so
on this page.
</para></listitem>
<listitem><para>The third is <code>CString::Format</code>, which allows formatting
in the style of <code>sprintf</code>. This deserves some mention:
</para></listitem>
</itemizedlist>
<para>
The old libg++ library had a function called form(), which did much
the same thing. But for a Standard solution, you should use the
stringstream classes. These are the bridge between the iostream
hierarchy and the string class, and they operate with regular
streams seamlessly because they inherit from the iostream
hierarchy. An quick example:
</para>
<programlisting>
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;
string f (string&amp; incoming) // incoming is "foo N"
{
istringstream incoming_stream(incoming);
string the_word;
int the_number;
incoming_stream &gt;&gt; the_word // extract "foo"
&gt;&gt; the_number; // extract N
ostringstream output_stream;
output_stream &lt;&lt; "The word was " &lt;&lt; the_word
&lt;&lt; " and 3*N was " &lt;&lt; (3*the_number);
return output_stream.str();
} </programlisting>
<para>A serious problem with CString is a design bug in its memory
allocation. Specifically, quoting from that same message:
</para>
<programlisting>
CString suffers from a common programming error that results in
poor performance. Consider the following code:
CString n_copies_of (const CString&amp; foo, unsigned n)
{
CString tmp;
for (unsigned i = 0; i &lt; n; i++)
tmp += foo;
return tmp;
}
This function is O(n^2), not O(n). The reason is that each +=
causes a reallocation and copy of the existing string. Microsoft
applications are full of this kind of thing (quadratic performance
on tasks that can be done in linear time) -- on the other hand,
we should be thankful, as it's created such a big market for high-end
ix86 hardware. :-)
If you replace CString with string in the above function, the
performance is O(n).
</programlisting>
<para>Joe Buck also pointed out some other things to keep in mind when
comparing CString and the Standard string class:
</para>
<itemizedlist>
<listitem><para>CString permits access to its internal representation; coders
who exploited that may have problems moving to <code>string</code>.
</para></listitem>
<listitem><para>Microsoft ships the source to CString (in the files
MFC\SRC\Str{core,ex}.cpp), so you could fix the allocation
bug and rebuild your MFC libraries.
<emphasis><emphasis>Note:</emphasis> It looks like the CString shipped
with VC++6.0 has fixed this, although it may in fact have been
one of the VC++ SPs that did it.</emphasis>
</para></listitem>
<listitem><para><code>string</code> operations like this have O(n) complexity
<emphasis>if the implementors do it correctly</emphasis>. The libstdc++
implementors did it correctly. Other vendors might not.
</para></listitem>
<listitem><para>While parts of the SGI STL are used in libstdc++, their
string class is not. The SGI <code>string</code> is essentially
<code>vector&lt;char&gt;</code> and does not do any reference
counting like libstdc++'s does. (It is O(n), though.)
So if you're thinking about SGI's string or rope classes,
you're now looking at four possibilities: CString, the
libstdc++ string, the SGI string, and the SGI rope, and this
is all before any allocator or traits customizations! (More
choices than you can shake a stick at -- want fries with that?)
</para></listitem>
</itemizedlist>
</sect1>
</chapter>
<!-- Chapter 03 : Interacting with C -->
</part>

View file

@ -0,0 +1,448 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.support" xreflabel="Support">
<?dbhtml filename="support.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Support</title>
<preface>
<title></title>
<para>
This part deals with the functions called and objects created
automatically during the course of a program's existence.
</para>
<para>
While we can't reproduce the contents of the Standard here (you
need to get your own copy from your nation's member body; see our
homepage for help), we can mention a couple of changes in what
kind of support a C++ program gets from the Standard Library.
</para>
</preface>
<chapter id="manual.support.types" xreflabel="Types">
<title>Types</title>
<sect1 id="manual.support.types.fundamental" xreflabel="Fundamental Types">
<title>Fundamental Types</title>
<para>
C++ has the following builtin types:
</para>
<itemizedlist>
<listitem><para>
char
</para></listitem>
<listitem><para>
signed char
</para></listitem>
<listitem><para>
unsigned char
</para></listitem>
<listitem><para>
signed short
</para></listitem>
<listitem><para>
signed int
</para></listitem>
<listitem><para>
signed long
</para></listitem>
<listitem><para>
unsigned short
</para></listitem>
<listitem><para>
unsigned int
</para></listitem>
<listitem><para>
unsigned long
</para></listitem>
<listitem><para>
bool
</para></listitem>
<listitem><para>
wchar_t
</para></listitem>
<listitem><para>
float
</para></listitem>
<listitem><para>
double
</para></listitem>
<listitem><para>
long double
</para></listitem>
</itemizedlist>
<para>
These fundamental types are always available, without having to
include a header file. These types are exactly the same in
either C++ or in C.
</para>
<para>
Specializing parts of the library on these types is prohibited:
instead, use a POD.
</para>
</sect1>
<sect1 id="manual.support.types.numeric_limits" xreflabel="Numeric Properites">
<title>Numeric Properties</title>
<para>
The header <filename class="headerfile">limits</filename> defines
traits classes to give access to various implementation
defined-aspects of the fundamental types. The traits classes --
fourteen in total -- are all specializations of the template class
<classname>numeric_limits</classname>, documented <ulink
url="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/structstd_1_1numeric__limits.html">here</ulink>
and defined as follows:
</para>
<programlisting>
template&lt;typename T&gt;
struct class
{
static const bool is_specialized;
static T max() throw();
static T min() throw();
static const int digits;
static const int digits10;
static const bool is_signed;
static const bool is_integer;
static const bool is_exact;
static const int radix;
static T epsilon() throw();
static T round_error() throw();
static const int min_exponent;
static const int min_exponent10;
static const int max_exponent;
static const int max_exponent10;
static const bool has_infinity;
static const bool has_quiet_NaN;
static const bool has_signaling_NaN;
static const float_denorm_style has_denorm;
static const bool has_denorm_loss;
static T infinity() throw();
static T quiet_NaN() throw();
static T denorm_min() throw();
static const bool is_iec559;
static const bool is_bounded;
static const bool is_modulo;
static const bool traps;
static const bool tinyness_before;
static const float_round_style round_style;
};
</programlisting>
</sect1>
<sect1 id="manual.support.types.null" xreflabel="NULL">
<title>NULL</title>
<para>
The only change that might affect people is the type of
<constant>NULL</constant>: while it is required to be a macro,
the definition of that macro is <emphasis>not</emphasis> allowed
to be <constant>(void*)0</constant>, which is often used in C.
</para>
<para>
For <command>g++</command>, <constant>NULL</constant> is
<programlisting>#define</programlisting>'d to be
<constant>__null</constant>, a magic keyword extension of
<command>g++</command>.
</para>
<para>
The biggest problem of #defining <constant>NULL</constant> to be
something like <quote>0L</quote> is that the compiler will view
that as a long integer before it views it as a pointer, so
overloading won't do what you expect. (This is why
<command>g++</command> has a magic extension, so that
<constant>NULL</constant> is always a pointer.)
</para>
<para>In his book <ulink
url="http://www.awprofessional.com/titles/0-201-92488-9/"><emphasis>Effective
C++</emphasis></ulink>, Scott Meyers points out that the best way
to solve this problem is to not overload on pointer-vs-integer
types to begin with. He also offers a way to make your own magic
<constant>NULL</constant> that will match pointers before it
matches integers.
</para>
<para>See
<ulink url="http://www.awprofessional.com/titles/0-201-31015-5/">the
Effective C++ CD example</ulink>
</para>
</sect1>
</chapter>
<chapter id="manual.support.memory" xreflabel="Dynamic Memory">
<title>Dynamic Memory</title>
<para>
There are six flavors each of <function>new</function> and
<function>delete</function>, so make certain that you're using the right
ones. Here are quickie descriptions of <function>new</function>:
</para>
<itemizedlist>
<listitem><para>
single object form, throwing a
<classname>bad_alloc</classname> on errors; this is what most
people are used to using
</para></listitem>
<listitem><para>
Single object &quot;nothrow&quot; form, returning NULL on errors
</para></listitem>
<listitem><para>
Array <function>new</function>, throwing
<classname>bad_alloc</classname> on errors
</para></listitem>
<listitem><para>
Array nothrow <function>new</function>, returning
<constant>NULL</constant> on errors
</para></listitem>
<listitem><para>
Placement <function>new</function>, which does nothing (like
it's supposed to)
</para></listitem>
<listitem><para>
Placement array <function>new</function>, which also does
nothing
</para></listitem>
</itemizedlist>
<para>
They are distinguished by the parameters that you pass to them, like
any other overloaded function. The six flavors of <function>delete</function>
are distinguished the same way, but none of them are allowed to throw
an exception under any circumstances anyhow. (They match up for
completeness' sake.)
</para>
<para>
Remember that it is perfectly okay to call <function>delete</function> on a
NULL pointer! Nothing happens, by definition. That is not the
same thing as deleting a pointer twice.
</para>
<para>
By default, if one of the <quote>throwing <function>new</function>s</quote> can't
allocate the memory requested, it tosses an instance of a
<classname>bad_alloc</classname> exception (or, technically, some class derived
from it). You can change this by writing your own function (called a
new-handler) and then registering it with <function>set_new_handler()</function>:
</para>
<programlisting>
typedef void (*PFV)(void);
static char* safety;
static PFV old_handler;
void my_new_handler ()
{
delete[] safety;
popup_window ("Dude, you are running low on heap memory. You
should, like, close some windows, or something.
The next time you run out, we're gonna burn!");
set_new_handler (old_handler);
return;
}
int main ()
{
safety = new char[500000];
old_handler = set_new_handler (&amp;my_new_handler);
...
}
</programlisting>
<para>
<classname>bad_alloc</classname> is derived from the base <classname>exception</classname>
class defined in Chapter 19.
</para>
</chapter>
<chapter id="manual.support.termination" xreflabel="Termination">
<title>Termination</title>
<sect1 id="support.termination.handlers" xreflabel="Termination Handlers">
<title>Termination Handlers</title>
<para>
Not many changes here to <filename
class="headerfile">cstdlib</filename>. You should note that the
<function>abort()</function> function does not call the
destructors of automatic nor static objects, so if you're
depending on those to do cleanup, it isn't going to happen.
(The functions registered with <function>atexit()</function>
don't get called either, so you can forget about that
possibility, too.)
</para>
<para>
The good old <function>exit()</function> function can be a bit
funky, too, until you look closer. Basically, three points to
remember are:
</para>
<orderedlist>
<listitem>
<para>
Static objects are destroyed in reverse order of their creation.
</para>
</listitem>
<listitem>
<para>
Functions registered with <function>atexit()</function> are called in
reverse order of registration, once per registration call.
(This isn't actually new.)
</para>
</listitem>
<listitem>
<para>
The previous two actions are <quote>interleaved,</quote> that is,
given this pseudocode:
</para>
<programlisting>
extern "C or C++" void f1 (void);
extern "C or C++" void f2 (void);
static Thing obj1;
atexit(f1);
static Thing obj2;
atexit(f2);
</programlisting>
<para>
then at a call of <function>exit()</function>,
<varname>f2</varname> will be called, then
<varname>obj2</varname> will be destroyed, then
<varname>f1</varname> will be called, and finally
<varname>obj1</varname> will be destroyed. If
<varname>f1</varname> or <varname>f2</varname> allow an
exception to propagate out of them, Bad Things happen.
</para>
</listitem>
</orderedlist>
<para>
Note also that <function>atexit()</function> is only required to store 32
functions, and the compiler/library might already be using some of
those slots. If you think you may run out, we recommend using
the <function>xatexit</function>/<function>xexit</function> combination from <literal>libiberty</literal>, which has no such limit.
</para>
</sect1>
<sect1 id="support.termination.verbose" xreflabel="Verbose Terminate Handler">
<title>Verbose Terminate Handler</title>
<para>
If you are having difficulty with uncaught exceptions and want a
little bit of help debugging the causes of the core dumps, you can
make use of a GNU extension, the verbose terminate handler.
</para>
<programlisting>
#include &lt;exception&gt;
int main()
{
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
...
throw <replaceable>anything</replaceable>;
}
</programlisting>
<para>
The <function>__verbose_terminate_handler</function> function
obtains the name of the current exception, attempts to demangle
it, and prints it to stderr. If the exception is derived from
<classname>exception</classname> then the output from
<function>what()</function> will be included.
</para>
<para>
Any replacement termination function is required to kill the
program without returning; this one calls abort.
</para>
<para>
For example:
</para>
<programlisting>
#include &lt;exception&gt;
#include &lt;stdexcept&gt;
struct argument_error : public std::runtime_error
{
argument_error(const std::string&amp; s): std::runtime_error(s) { }
};
int main(int argc)
{
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
if (argc &gt; 5)
throw argument_error(<quote>argc is greater than 5!</quote>);
else
throw argc;
}
</programlisting>
<para>
With the verbose terminate handler active, this gives:
</para>
<screen>
<computeroutput>
% ./a.out
terminate called after throwing a `int'
Aborted
% ./a.out f f f f f f f f f f f
terminate called after throwing an instance of `argument_error'
what(): argc is greater than 5!
Aborted
</computeroutput>
</screen>
<para>
The 'Aborted' line comes from the call to
<function>abort()</function>, of course.
</para>
<para>
This is the default termination handler; nothing need be done to
use it. To go back to the previous <quote>silent death</quote>
method, simply include <filename>exception</filename> and
<filename>cstdlib</filename>, and call
</para>
<programlisting>
std::set_terminate(std::abort);
</programlisting>
<para>
After this, all calls to <function>terminate</function> will use
<function>abort</function> as the terminate handler.
</para>
<para>
Note: the verbose terminate handler will attempt to write to
stderr. If your application closes stderr or redirects it to an
inappropriate location,
<function>__verbose_terminate_handler</function> will behave in
an unspecified manner.
</para>
</sect1>
</chapter>
</part>

View file

@ -0,0 +1,823 @@
<sect1 id="manual.intro.setup.test" xreflabel="Testing">
<?dbhtml filename="test.html"?>
<sect1info>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
test
</keyword>
<keyword>
testsuite
</keyword>
</keywordset>
</sect1info>
<title>Test</title>
<sect2 id="test.organization" xreflabel="test.organization">
<title>Organization</title>
<para>
The directory <emphasis>libsrcdir/testsuite</emphasis> contains the
individual test cases organized in sub-directories corresponding to
chapters of the C++ standard (detailed below), the dejagnu test
harness support files, and sources to various testsuite utilities
that are packaged in a separate testing library.
</para>
<para>
All test cases for functionality required by the runtime components
of the C++ standard (ISO 14882) are files within the following
directories.
</para>
<programlisting>
17_intro
18_support
19_diagnostics
20_util
21_strings
22_locale
23_containers
25_algorithms
26_numerics
27_io
</programlisting>
<para>
In addition, the following directories include test files:
</para>
<programlisting>
tr1 Tests for components as described by the Technical Report on Standard Library Extensions (TR1).
backward Tests for backwards compatibility and deprecated features.
demangle Tests for __cxa_demangle, the IA 64 C++ ABI demangler
ext Tests for extensions.
performance Tests for performance analysis, and performance regressions.
thread Tests for threads.
</programlisting>
<para>
Some directories don't have test files, but instead contain
auxiliary information (<ulink url="#internals">more information</ulink>):
</para>
<programlisting>
config Files for the dejagnu test harness.
lib Files for the dejagnu test harness.
libstdc++* Files for the dejagnu test harness.
data Sample text files for testing input and output.
util Files for libtestc++, utilities and testing routines.
</programlisting>
<para>
Within a directory that includes test files, there may be
additional subdirectories, or files. Originally, test cases
were appended to one file that represented a particular section
of the chapter under test, and was named accordingly. For
instance, to test items related to <code> 21.3.6.1 -
basic_string::find [lib.string::find]</code> in the standard,
the following was used:
</para>
<programlisting>
21_strings/find.cc
</programlisting>
<para>
However, that practice soon became a liability as the test cases
became huge and unwieldy, and testing new or extended
functionality (like wide characters or named locales) became
frustrating, leading to aggressive pruning of test cases on some
platforms that covered up implementation errors. Now, the test
suite has a policy of one file, one test case, which solves the
above issues and gives finer grained results and more manageable
error debugging. As an example, the test case quoted above
becomes:
</para>
<programlisting>
21_strings/basic_string/find/char/1.cc
21_strings/basic_string/find/char/2.cc
21_strings/basic_string/find/char/3.cc
21_strings/basic_string/find/wchar_t/1.cc
21_strings/basic_string/find/wchar_t/2.cc
21_strings/basic_string/find/wchar_t/3.cc
</programlisting>
<para>
All new tests should be written with the policy of one test
case, one file in mind.
</para>
</sect2>
<sect2 id="test.naming" xreflabel="test.naming">
<title>Naming Conventions</title>
<para>
</para>
<para>
In addition, there are some special names and suffixes that are
used within the testsuite to designate particular kinds of
tests.
</para>
<itemizedlist>
<listitem>
<para>
<emphasis>_xin.cc</emphasis>
</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:
</para>
<programlisting>
g++ 27_io/objects/char/3_xin.cc
cat 27_io/objects/char/3_xin.in | a.out
</programlisting>
</listitem>
<listitem>
<para>
<emphasis>.in</emphasis>
</para>
<para>
This file contains the expected input for the corresponding <emphasis>
_xin.cc</emphasis> test case.
</para>
</listitem>
<listitem>
<para>
<emphasis>_neg.cc</emphasis>
</para>
<para>
This test case is expected to fail: it's a negative test. At the
moment, these are almost always compile time errors.
</para>
</listitem>
<listitem>
<para>
<emphasis>char</emphasis>
</para>
<para>
This can either be a directory name or part of a longer file
name, and indicates that this file, or the files within this
directory are testing the <code>char</code> instantiation of a
template.
</para>
</listitem>
<listitem>
<para>
<emphasis>wchar_t</emphasis>
</para>
<para>
This can either be a directory name or part of a longer file
name, and indicates that this file, or the files within this
directory are testing the <code>wchar_t</code> instantiation of
a template. Some hosts do not support <code>wchar_t</code>
functionality, so for these targets, all of these tests will not
be run.
</para>
</listitem>
<listitem>
<para>
<emphasis>thread</emphasis>
</para>
<para>
This can either be a directory name or part of a longer file
name, and indicates that this file, or the files within this
directory are testing situations where multiple threads are
being used.
</para>
</listitem>
<listitem>
<para>
<emphasis>performance</emphasis>
</para>
<para>
This can either be an enclosing directory name or part of a
specific file name. This indicates a test that is used to
analyze runtime performance, for performance regression testing,
or for other optimization related analysis. At the moment, these
test cases are not run by default.
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="test.utils" xreflabel="test.utils">
<title>Utilities</title>
<para>
</para>
<para>
The testsuite directory also contains some files that implement
functionality that is intended to make writing test cases easier,
or to avoid duplication, or to provide error checking in a way that
is consistent across platforms and test harnesses. A stand-alone
executable, called <emphasis>abi_check</emphasis>, and a static
library called <emphasis>libtestc++</emphasis> are
constructed. Both of these items are not installed, and only used
during testing.
</para>
<para>
These files include the following functionality:
</para>
<itemizedlist>
<listitem>
<para>
<emphasis>testsuite_abi.h</emphasis>,
<emphasis>testsuite_abi.cc</emphasis>,
<emphasis>testsuite_abi_check.cc</emphasis>
</para>
<para>
Creates the executable <emphasis>abi_check</emphasis>.
Used to check correctness of symbol versioning, visibility of
exported symbols, and compatibility on symbols in the shared
library, for hosts that support this feature. More information
can be found in the ABI documentation <ulink url="abi.html">here</ulink>
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_allocator.h</emphasis>,
<emphasis>testsuite_allocator.cc</emphasis>
</para>
<para>
Contains specialized allocators that keep track of construction
and destruction. Also, support for overriding global new and
delete operators, including verification that new and delete
are called during execution, and that allocation over max_size
fails.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_character.h</emphasis>
</para>
<para>
Contains <code>std::char_traits</code> and
<code>std::codecvt</code> specializations for a user-defined
POD.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_hooks.h</emphasis>,
<emphasis>testsuite_hooks.cc</emphasis>
</para>
<para>
A large number of utilities, including:
</para>
<itemizedlist>
<listitem><para>VERIFY</para></listitem>
<listitem><para>set_memory_limits</para></listitem>
<listitem><para>verify_demangle</para></listitem>
<listitem><para>run_tests_wrapped_locale</para></listitem>
<listitem><para>run_tests_wrapped_env</para></listitem>
<listitem><para>try_named_locale</para></listitem>
<listitem><para>try_mkfifo</para></listitem>
<listitem><para>func_callback</para></listitem>
<listitem><para>counter</para></listitem>
<listitem><para>copy_tracker</para></listitem>
<listitem><para>copy_constructor</para></listitem>
<listitem><para>assignment_operator</para></listitem>
<listitem><para>destructor</para></listitem>
<listitem>
<para>pod_char, pod_int and associated char_traits specializations</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
<emphasis>testsuite_io.h</emphasis>
</para>
<para>
Error, exception, and constraint checking for
<code>std::streambuf, std::basic_stringbuf, std::basic_filebuf</code>.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_iterators.h</emphasis>
</para>
<para>
Wrappers for various iterators.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_performance.h</emphasis>
</para>
<para>
A number of class abstractions for performance counters, and
reporting functions including:
</para>
<itemizedlist>
<listitem><para>time_counter</para></listitem>
<listitem><para>resource_counter</para></listitem>
<listitem><para>report_performance</para></listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="test.run" xreflabel="test.run">
<title>Running the Testsuite</title>
<sect3 id="test.run.basic" xreflabel="test.run.basic">
<title>Basic Results</title>
<para>
There are several options for running tests, including testing
the regression tests, testing a subset of the regression tests,
testing the performance tests, testing just compilation, testing
installed tools, etc. In addition, there is a special rule for
checking the exported symbols of the shared library.
</para>
<para>
You can check the status of the build without installing it
using the dejagnu harness, much like the rest of the gcc
tools.</para>
<programlisting> make check</programlisting>
<para>in the <emphasis>libbuilddir</emphasis> directory.</para>
<para>or</para>
<programlisting> make check-target-libstdc++-v3</programlisting>
<para>in the <emphasis>gccbuilddir</emphasis> directory.
</para>
<para>
These commands are functionally equivalent and will create a
'testsuite' directory underneath
<emphasis>libbuilddir</emphasis> containing the results of the
tests. Two results files will be generated: <emphasis>
libstdc++.sum</emphasis>, which is a PASS/FAIL summary for each
test, and <emphasis>libstdc++.log</emphasis> which is a log of
the exact command line passed to the compiler, the compiler
output, and the executable output (if any).
</para>
<para>
Archives of test results for various versions and platforms are
available on the GCC website in the <ulink
url="http://gcc.gnu.org/gcc-4.1/buildstat.html">build
status</ulink> section of each individual release, and are also
archived on a daily basis on the <ulink
url="http://gcc.gnu.org/ml/gcc-testresults/current">gcc-testresults</ulink>
mailing list. Please check either of these places for a similar
combination of source version, operating system, and host CPU.
</para>
</sect3>
<sect3 id="test.run.options" xreflabel="test.run.options">
<title>Options</title>
<para>
To debug the dejagnu test harness during runs, try invoking with a
specific argument to the variable RUNTESTFLAGS, as below.
</para>
<programlisting>
make check-target-libstdc++-v3 RUNTESTFLAGS="-v"
</programlisting>
<para>
or
</para>
<programlisting>
make check-target-libstdc++-v3 RUNTESTFLAGS="-v -v"
</programlisting>
<para>
To run a subset of the library tests, you will need to generate
the <emphasis>testsuite_files</emphasis> file by running
<command>make testsuite_files</command> in the
<emphasis>libbuilddir/testsuite</emphasis> directory, described
below. Edit the file to remove the tests you don't want and
then run the testsuite as normal.
</para>
<para>
There are two ways to run on a simulator: set up DEJAGNU to point to a
specially crafted site.exp, or pass down --target_board flags.
</para>
<para>
Example flags to pass down for various embedded builds are as follows:
</para>
<programlisting>
--target=powerpc-eabism (libgloss/sim)
make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=powerpc-sim"
--target=calmrisc32 (libgloss/sid)
make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=calmrisc32-sid"
--target=xscale-elf (newlib/sim)
make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=arm-sim"
</programlisting>
<para>
Also, here is an example of how to run the libstdc++ testsuite
for a multilibed build directory with different ABI settings:
</para>
<programlisting>
make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board \"unix{-mabi=32,,-mabi=64}\"'
</programlisting>
<para>
You can run the tests with a compiler and library that have
already been installed. Make sure that the compiler (e.g.,
<code>g++</code>) is in your <code>PATH</code>. If you are
using shared libraries, then you must also ensure that the
directory containing the shared version of libstdc++ is in your
<code>LD_LIBRARY_PATH</code>, or equivalent. If your GCC source
tree is at <code>/path/to/gcc</code>, then you can run the tests
as follows:
</para>
<programlisting>
runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite
</programlisting>
<para>
The testsuite will create a number of files in the directory in
which you run this command,. Some of those files might use the
same name as files created by other testsuites (like the ones
for GCC and G++), so you should not try to run all the
testsuites in parallel from the same directory.
</para>
<para>
In addition, there are some testing options that are mostly of
interest to library maintainers and system integrators. As such,
these tests may not work on all cpu and host combinations, and
may need to be executed in the
<emphasis>libbuilddir/testsuite</emphasis> directory. These
options include, but are not necessarily limited to, the
following:
</para>
<programlisting>
make testsuite_files
</programlisting>
<para>
Five files are generated that determine what test files
are run. These files are:
</para>
<itemizedlist>
<listitem>
<para>
<emphasis>testsuite_files</emphasis>
</para>
<para>
This is a list of all the test cases that will be run. Each
test case is on a separate line, given with an absolute path
from the <emphasis>libsrcdir/testsuite</emphasis> directory.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_files_interactive</emphasis>
</para>
<para>
This is a list of all the interactive test cases, using the
same format as the file list above. These tests are not run
by default.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_files_performance</emphasis>
</para>
<para>
This is a list of all the performance test cases, using the
same format as the file list above. These tests are not run
by default.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_thread</emphasis>
</para>
<para>
This file indicates that the host system can run tests which
incolved multiple threads.
</para>
</listitem>
<listitem>
<para>
<emphasis>testsuite_wchar_t</emphasis>
</para>
<para>
This file indicates that the host system can run the wchar_t
tests, and corresponds to the macro definition <code>
_GLIBCXX_USE_WCHAR_T</code> in the file c++config.h.
</para>
</listitem>
</itemizedlist>
<programlisting>
make check-abi
</programlisting>
<para>
The library ABI can be tested. This involves testing the shared
library against an ABI-defining previous version of symbol
exports.
</para>
<programlisting>
make check-compile
</programlisting>
<para>
This rule compiles, but does not link or execute, the
<emphasis>testsuite_files</emphasis> test cases and displays the
output on stdout.
</para>
<programlisting>
make check-performance
</programlisting>
<para>
This rule runs through the
<emphasis>testsuite_files_performance</emphasis> test cases and
collects information for performance analysis and can be used to
spot performance regressions. Various timing information is
collected, as well as number of hard page faults, and memory
used. This is not run by default, and the implementation is in
flux.
</para>
<para>
We are interested in any strange failures of the testsuite;
please email the main libstdc++ mainling list if you see
something odd or have questions.
</para>
</sect3>
<sect3 id="test.run.permutations" xreflabel="test.run.permutations">
<title>Test Permutations</title>
<para>
To run the libstdc++ test suite under the <link
linkend="manual.ext.debug_mode">debug mode</link>, edit
<filename>libstdc++-v3/scripts/testsuite_flags</filename> to add the
compile-time flag <constant>-D_GLIBCXX_DEBUG</constant> to the
result printed by the <literal>--build-cxx</literal>
option. Additionally, add the
<constant>-D_GLIBCXX_DEBUG_PEDANTIC</constant> flag to turn on
pedantic checking. The libstdc++ test suite should produce
precisely the same results under debug mode that it does under
release mode: any deviation indicates an error in either the
library or the test suite.
</para>
<para>
Or, just run the testsuites with <constant>CXXFLAGS</constant>
set to <constant>-D_GLIBCXX_DEBUG</constant>.
</para>
</sect3>
</sect2>
<sect2 id="test.new_tests" xreflabel="test.new_tests">
<title>New Test Cases</title>
<para>
The first step in making a new test case is to choose the correct
directory and file name, given the organization as previously
described.
</para>
<para>
All files are copyright the FSF, and GPL'd: this is very
important. The first copyright year should correspond to the date
the file was checked in to SVN.
</para>
<para>
As per the dejagnu instructions, always return 0 from main to
indicate success.
</para>
<para>
A bunch of utility functions and classes have already been
abstracted out into the testsuite utility library, <code>
libtestc++</code>. To use this functionality, just include the
appropriate header file: the library or specific object files will
automatically be linked in as part of the testsuite run.
</para>
<para>
For a test that needs to take advantage of the dejagnu test
harness, what follows below is a list of special keyword that
harness uses. Basically, a test case contains dg-keywords (see
dg.exp) indicating what to do and what kinds of behavior are to be
expected. New test cases should be written with the new style
DejaGnu framework in mind.
</para>
<para>
To ease transition, here is the list of dg-keyword documentation
lifted from dg.exp.
</para>
<programlisting>
# The currently supported options are:
#
# dg-prms-id N
# set prms_id to N
#
# dg-options "options ..." [{ target selector }]
# specify special options to pass to the tool (eg: compiler)
#
# dg-do do-what-keyword [{ target/xfail selector }]
# `do-what-keyword' is tool specific and is passed unchanged to
# ${tool}-dg-test. An example is gcc where `keyword' can be any of:
# preprocess|compile|assemble|link|run
# and will do one of: produce a .i, produce a .s, produce a .o,
# produce an a.out, or produce an a.out and run it (the default is
# compile).
#
# dg-error regexp comment [{ target/xfail selector } [{.|0|linenum}]]
# indicate an error message &lt;regexp&gt; is expected on this line
# (the test fails if it doesn't occur)
# Linenum=0 for general tool messages (eg: -V arg missing).
# "." means the current line.
#
# dg-warning regexp comment [{ target/xfail selector } [{.|0|linenum}]]
# indicate a warning message &lt;regexp&gt; is expected on this line
# (the test fails if it doesn't occur)
#
# dg-bogus regexp comment [{ target/xfail selector } [{.|0|linenum}]]
# indicate a bogus error message &lt;regexp&gt; use to occur here
# (the test fails if it does occur)
#
# dg-build regexp comment [{ target/xfail selector }]
# indicate the build use to fail for some reason
# (errors covered here include bad assembler generated, tool crashes,
# and link failures)
# (the test fails if it does occur)
#
# dg-excess-errors comment [{ target/xfail selector }]
# indicate excess errors are expected (any line)
# (this should only be used sparingly and temporarily)
#
# dg-output regexp [{ target selector }]
# indicate the expected output of the program is &lt;regexp&gt;
# (there may be multiple occurrences of this, they are concatenated)
#
# dg-final { tcl code }
# add some tcl code to be run at the end
# (there may be multiple occurrences of this, they are concatenated)
# (unbalanced braces must be \-escaped)
#
# "{ target selector }" is a list of expressions that determine whether the
# test succeeds or fails for a particular target, or in some cases whether the
# option applies for a particular target. If the case of `dg-do' it specifies
# whether the test case is even attempted on the specified target.
#
# The target selector is always optional. The format is one of:
#
# { xfail *-*-* ... } - the test is expected to fail for the given targets
# { target *-*-* ... } - the option only applies to the given targets
#
# At least one target must be specified, use *-*-* for "all targets".
# At present it is not possible to specify both `xfail' and `target'.
# "native" may be used in place of "*-*-*".
Example 1: Testing compilation only
// { dg-do compile }
Example 2: Testing for expected warnings on line 36, which all targets fail
// { dg-warning "string literals" "" { xfail *-*-* } 36
Example 3: Testing for expected warnings on line 36
// { dg-warning "string literals" "" { target *-*-* } 36
Example 4: Testing for compilation errors on line 41
// { dg-do compile }
// { dg-error "no match for" "" { target *-*-* } 41 }
Example 5: Testing with special command line settings, or without the
use of pre-compiled headers, in particular the stdc++.h.gch file. Any
options here will override the DEFAULT_CXXFLAGS and PCH_CXXFLAGS set
up in the normal.exp file.
// { dg-options "-O0" { target *-*-* } }
</programlisting>
<para>
More examples can be found in the libstdc++-v3/testsuite/*/*.cc files.
</para>
</sect2>
<sect2 id="test.dejagnu" xreflabel="test.dejagnu">
<title>Test Harness Details</title>
<para>
Underlying details of testing are abstracted via the GNU Dejagnu package.
</para>
<para>This is information for those looking at making changes to the testsuite
structure, and/or needing to trace dejagnu's actions with --verbose. This
will not be useful to people who are "merely" adding new tests to the existing
structure.
</para>
<para>The first key point when working with dejagnu is the idea of a "tool".
Files, directories, and functions are all implicitly used when they are
named after the tool in use. Here, the tool will always be "libstdc++".
</para>
<para>The <code>lib</code> subdir contains support routines. The
<code>lib/libstdc++.exp</code> file ("support library") is loaded
automagically, and must explicitly load the others. For example, files can
be copied from the core compiler's support directory into <code>lib</code>.
</para>
<para>Some routines in <code>lib/libstdc++.exp</code> are callbacks, some are
our own. Callbacks must be prefixed with the name of the tool. To easily
distinguish the others, by convention our own routines are named "v3-*".
</para>
<para>The next key point when working with dejagnu is "test files". Any
directory whose name starts with the tool name will be searched for test files.
(We have only one.) In those directories, any <code>.exp</code> file is
considered a test file, and will be run in turn. Our main test file is called
<code>normal.exp</code>; it runs all the tests in testsuite_files using the
callbacks loaded from the support library.
</para>
<para>The <code>config</code> directory is searched for any particular "target
board" information unique to this library. This is currently unused and sets
only default variables.
</para>
</sect2>
<sect2 id="test.future" xreflabel="test.future">
<title>Future</title>
<para>
</para>
<para>
Shared runs need to be implemented, for targets that support shared libraries.
</para>
<para>
Diffing of expected output to standard streams needs to be finished off.
</para>
<para>
The V3 testing framework supports, or will eventually support,
additional keywords for the purpose of easing the job of writing
test cases. All V3-keywords are of the form <code>@xxx@</code>.
Currently plans for supported keywords include:
</para>
<variablelist>
<varlistentry><term> <code> @require@ &lt;files&gt; </code> </term>
<listitem>
<para>
The existence of &lt;files&gt; is essential for the test to complete
successfully. For example, a test case foo.C using bar.baz as
input file could say
</para>
<programlisting>
// @require@ bar.baz</programlisting>
<para>
The special variable % stands for the rootname, e.g. the
file-name without its `.C' extension. Example of use (taken
verbatim from 27_io/filebuf.cc)
</para>
<programlisting>
// @require@ %-*.tst %-*.txt</programlisting>
</listitem></varlistentry>
<varlistentry><term> <code> @diff@ &lt;first-list&gt; &lt;second-list&gt; </code> </term>
<listitem>
<para>
After the test case compiles and ran successfully, diff
&lt;first-list&gt; against &lt;second-list&gt;, these lists should
have the same length. The test fails if diff returns non-zero a
pair of files.
</para>
</listitem></varlistentry>
</variablelist>
</sect2>
</sect1>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,125 @@
<?xml version='1.0'?>
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[ ]>
<part id="manual.util" xreflabel="Utilities">
<?dbhtml filename="utilities.html"?>
<partinfo>
<keywordset>
<keyword>
ISO C++
</keyword>
<keyword>
library
</keyword>
</keywordset>
</partinfo>
<title>Utilities</title>
<!-- Chapter 01 : Functors -->
<chapter id="manual.util.functors" xreflabel="Functors">
<title>Functors</title>
<para>If you don't know what functors are, you're not alone. Many people
get slightly the wrong idea. In the interest of not reinventing
the wheel, we will refer you to the introduction to the functor
concept written by SGI as part of their STL, in
<ulink url="http://www.sgi.com/tech/stl/functors.html">their
http://www.sgi.com/tech/stl/functors.html</ulink>.
</para>
</chapter>
<!-- Chapter 02 : Pairs -->
<chapter id="manual.util.pairs" xreflabel="Pairs">
<title>Pairs</title>
<para>The <code>pair&lt;T1,T2&gt;</code> is a simple and handy way to
carry around a pair of objects. One is of type T1, and another of
type T2; they may be the same type, but you don't get anything
extra if they are. The two members can be accessed directly, as
<code>.first</code> and <code>.second</code>.
</para>
<para>Construction is simple. The default ctor initializes each member
with its respective default ctor. The other simple ctor,
</para>
<programlisting>
pair (const T1&amp; x, const T2&amp; y);
</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 copy constructor, but it requires that your compiler
handle member function templates:
</para>
<programlisting>
template &lt;class U, class V&gt; pair (const pair&lt;U,V&gt;&amp; p);
</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>
<para>The comparison operators are done for you. Equality
of two <code>pair&lt;T1,T2&gt;</code>s is defined as both <code>first</code>
members comparing equal and both <code>second</code> members comparing
equal; this simply delegates responsibility to the respective
<code>operator==</code> functions (for types like MyClass) or builtin
comparisons (for types like int, char, etc).
</para>
<para>
The less-than operator is a bit odd the first time you see it. It
is defined as evaluating to:
</para>
<programlisting>
x.first &lt; y.first ||
( !(y.first &lt; x.first) &amp;&amp; x.second &lt; y.second )
</programlisting>
<para>The other operators are not defined using the <code>rel_ops</code>
functions above, but their semantics are the same.
</para>
<para>Finally, there is a template function called <function>make_pair</function>
that takes two references-to-const objects and returns an
instance of a pair instantiated on their respective types:
</para>
<programlisting>
pair&lt;int,MyClass&gt; p = make_pair(4,myobject);
</programlisting>
</chapter>
<!-- Chapter 03 : Memory -->
<chapter id="manual.util.memory" xreflabel="Memory">
<title>Memory</title>
<para>
Memory contains three general areas. First, function and operator
calls via <function>new</function> and <function>delete</function>
operator or member function calls. Second, allocation via
<classname>allocator</classname>. And finally, smart pointer and
intelligent pointer abstractions.
</para>
<!-- Section 01 : allocator -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="allocator.xml">
</xi:include>
<!-- Section 02 : auto_ptr -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="auto_ptr.xml">
</xi:include>
<!-- Section 03 : shared_ptr -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
parse="xml" href="shared_ptr.xml">
</xi:include>
</chapter>
<!-- Chapter 04 : Traits -->
<chapter id="manual.util.traits" xreflabel="Traits">
<title>Traits</title>
<para>
</para>
</chapter>
</part>

View file

@ -0,0 +1,47 @@
<?xml version='1.0'?>
<!DOCTYPE set PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
[
<!ENTITY authors SYSTEM "authors.xml">
<!ENTITY license SYSTEM "license.xml">
]>
<set id="set-index" xreflabel="set-index">
<?dbhtml filename="set-index.html"?>
<title>The GNU C++ Library Documentation</title>
<setinfo>
<copyright>
<year>2000</year>
<year>2001</year>
<year>2002</year>
<year>2003</year>
<year>2004</year>
<year>2005</year>
<year>2006</year>
<year>2007</year>
<year>2008</year>
<holder>
<ulink url="http://fsf.org">FSF</ulink>
</holder>
</copyright>
&authors;
</setinfo>
<!-- User Manual -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="manual/spine.xml" parse="xml">
</xi:include>
<!-- Source Level Documentation-->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="api.xml" parse="xml">
</xi:include>
<!-- FAQ -->
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="faq.xml" parse="xml">
</xi:include>
</set>

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -13,15 +13,11 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -110,42 +106,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -162,9 +129,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -190,13 +156,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -207,8 +173,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -228,29 +198,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -1126,10 +1103,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
tags: TAGS
TAGS:
@ -1138,23 +1111,21 @@ CTAGS:
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -1200,7 +1171,7 @@ clean-am: clean-generic clean-libtool clean-local mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool
distclean-am: clean-am distclean-generic
dvi: dvi-am
@ -1214,12 +1185,20 @@ info-am:
install-data-am: install-data-local
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -1238,18 +1217,21 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am all-local check check-am clean clean-generic \
clean-libtool clean-local distclean distclean-generic \
distclean-libtool distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-data-local install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
install-data-local install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
# Here are the rules for building the headers

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -14,15 +14,11 @@
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -63,17 +59,18 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
am__DEPENDENCIES_1 =
am_libmath_la_OBJECTS = stubs.lo
libmath_la_OBJECTS = $(am_libmath_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
depcomp =
am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libmath_la_SOURCES)
DIST_SOURCES = $(libmath_la_SOURCES)
ETAGS = etags
@ -125,42 +122,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -179,9 +147,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -207,13 +174,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -224,8 +191,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -245,29 +216,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -321,7 +299,7 @@ clean-noinstLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
libmath.la: $(libmath_la_OBJECTS) $(libmath_la_DEPENDENCIES)
$(LINK) $(libmath_la_LDFLAGS) $(libmath_la_OBJECTS) $(libmath_la_LIBADD) $(LIBS)
$(LINK) $(libmath_la_OBJECTS) $(libmath_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -344,10 +322,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@ -397,22 +371,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -459,7 +432,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
distclean-tags
dvi: dvi-am
@ -473,12 +446,20 @@ info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -498,19 +479,22 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-info-am
pdf pdf-am ps ps-am tags uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -15,15 +15,11 @@
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -115,14 +111,15 @@ am__libsupc__convenience_la_SOURCES_DIST = array_type_info.cc \
am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
libsupc__convenience_la_OBJECTS = \
$(am_libsupc__convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
depcomp =
am__depfiles_maybe =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
@ -180,42 +177,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -232,9 +200,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -260,13 +227,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -277,8 +244,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -298,29 +269,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -517,7 +495,7 @@ clean-noinstLTLIBRARIES:
done
install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(toolexeclibdir)" || $(mkdir_p) "$(DESTDIR)$(toolexeclibdir)"
test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
@ -528,7 +506,7 @@ install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
uninstall-toolexeclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@set -x; list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$p"; \
@ -543,9 +521,9 @@ clean-toolexeclibLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
libsupc++.la: $(libsupc___la_OBJECTS) $(libsupc___la_DEPENDENCIES)
$(CXXLINK) -rpath $(toolexeclibdir) $(libsupc___la_LDFLAGS) $(libsupc___la_OBJECTS) $(libsupc___la_LIBADD) $(LIBS)
$(CXXLINK) -rpath $(toolexeclibdir) $(libsupc___la_OBJECTS) $(libsupc___la_LIBADD) $(LIBS)
libsupc++convenience.la: $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_DEPENDENCIES)
$(CXXLINK) $(libsupc__convenience_la_LDFLAGS) $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_LIBADD) $(LIBS)
$(CXXLINK) $(libsupc__convenience_la_OBJECTS) $(libsupc__convenience_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -577,10 +555,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@ -630,23 +604,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -662,7 +634,7 @@ check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(glibcxxinstalldir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
@ -696,7 +668,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
distclean-tags
dvi: dvi-am
@ -710,12 +682,20 @@ info-am:
install-data-am: install-glibcxxinstallHEADERS
install-dvi: install-dvi-am
install-exec-am: install-toolexeclibLTLIBRARIES
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -735,22 +715,26 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-glibcxxinstallHEADERS uninstall-info-am \
uninstall-am: uninstall-glibcxxinstallHEADERS \
uninstall-toolexeclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES \
clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-glibcxxinstallHEADERS install-info install-info-am \
install-man install-strip install-toolexeclibLTLIBRARIES \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-glibcxxinstallHEADERS \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip install-toolexeclibLTLIBRARIES \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-glibcxxinstallHEADERS \
uninstall-info-am uninstall-toolexeclibLTLIBRARIES
uninstall-toolexeclibLTLIBRARIES
cp-demangle.c:

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -13,15 +13,11 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -110,42 +106,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -162,9 +129,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -190,13 +156,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -207,8 +173,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -228,29 +198,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -328,10 +305,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
tags: TAGS
TAGS:
@ -340,23 +313,21 @@ CTAGS:
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -402,7 +373,7 @@ clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool
distclean-am: clean-am distclean-generic
dvi: dvi-am
@ -416,12 +387,20 @@ info-am:
install-data-am: install-data-local
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -440,17 +419,21 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am all-local check check-am clean clean-generic \
clean-libtool distclean distclean-generic distclean-libtool \
distdir dvi dvi-am html html-am info info-am install \
install-am install-data install-data-am install-data-local \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am uninstall uninstall-am uninstall-info-am
ps ps-am uninstall uninstall-am
.po.mo:

View file

@ -3,7 +3,7 @@
# Runs doxygen and massages the output files.
# Copyright (C) 2001, 2002, 2003, 2004, 2008 Free Software Foundation, Inc.
#
# Synopsis: run_doxygen --mode=[html|man] --host_alias=<alias> \
# Synopsis: run_doxygen --mode=[html|man|xml] --host_alias=<alias> \
# v3srcdir v3builddir
#
# Originally hacked together by Phil Edwards <pme@gcc.gnu.org>
@ -49,6 +49,7 @@ Usage: run_doxygen --mode=MODE --host_alias=BUILD_ALIAS [<options>]
MODE is one of:
html Generate user-level HTML library documentation.
man Generate user-level man pages.
xml Generate user-level XML pages.
BUILD_ALIAS is the GCC build alias set at configure time.
@ -100,6 +101,7 @@ srcdir=unset
outdir=unset
do_html=false
do_man=false
do_xml=false
enabled_sections=
generate_tagfile=
DATEtext=`date '+%Y-%m-%d'`
@ -125,6 +127,10 @@ case x"$mode" in
xman)
do_man=true
;;
xxml)
do_xml=true
enabled_sections=maint
;;
*)
echo run_doxygen error: $mode is an invalid mode 1>&2
exit 1 ;;
@ -139,6 +145,10 @@ if $do_man; then
chmod -R u+w $outdir/man/man3/ext
fi
if $do_xml; then
mkdir -p $outdir/xml
fi
(
set -e
cd $builddir
@ -150,6 +160,7 @@ fi
-e "s=@enabled_sections@=${enabled_sections}=" \
-e "s=@do_html@=${do_html}=" \
-e "s=@do_man@=${do_man}=" \
-e "s=@do_xml@=${do_xml}=" \
-e "s=@generate_tagfile@=${generate_tagfile}=" \
${srcdir}/doc/doxygen/user.cfg.in > ${outdir}/${mode}.cfg
echo :: NOTE that this may take some time...
@ -179,7 +190,8 @@ if $do_html; then
mv annstrip.html annotated.html
# Work around a bug in doxygen 1.3.
for f in class*html struct*html; do
# for f in class*html struct*html; do
for f in class*html; do
sed '1,10s!^<title> Template!<title>Template !' $f > TEMP
mv TEMP $f
done

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -14,15 +14,11 @@
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -107,7 +103,10 @@ am__objects_5 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
$(am__objects_4)
am_libstdc___la_OBJECTS = $(am__objects_5)
libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
libstdc___la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libstdc___la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
depcomp =
am__depfiles_maybe =
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
@ -164,42 +163,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -216,9 +186,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -244,13 +213,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -261,8 +230,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -282,29 +255,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
# May be used by various substitution variables.
@ -509,7 +489,7 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(toolexeclibdir)" || $(mkdir_p) "$(DESTDIR)$(toolexeclibdir)"
test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
@ -520,7 +500,7 @@ install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
uninstall-toolexeclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@set -x; list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$p"; \
@ -535,7 +515,7 @@ clean-toolexeclibLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
libstdc++.la: $(libstdc___la_OBJECTS) $(libstdc___la_DEPENDENCIES)
$(CXXLINK) -rpath $(toolexeclibdir) $(libstdc___la_LDFLAGS) $(libstdc___la_OBJECTS) $(libstdc___la_LIBADD) $(LIBS)
$(libstdc___la_LINK) -rpath $(toolexeclibdir) $(libstdc___la_OBJECTS) $(libstdc___la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@ -558,10 +538,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@ -611,23 +587,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -643,7 +617,7 @@ check: check-am
all-am: Makefile $(LTLIBRARIES) all-local
installdirs:
for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
@ -677,7 +651,7 @@ clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
distclean-tags
dvi: dvi-am
@ -691,12 +665,20 @@ info-am:
install-data-am: install-data-local
install-dvi: install-dvi-am
install-exec-am: install-toolexeclibLTLIBRARIES
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -716,21 +698,24 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-toolexeclibLTLIBRARIES
uninstall-am: uninstall-toolexeclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
clean-generic clean-libtool clean-toolexeclibLTLIBRARIES ctags \
distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-data-local install-exec \
install-exec-am install-info install-info-am install-man \
install-strip install-toolexeclibLTLIBRARIES installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-toolexeclibLTLIBRARIES
install-data-am install-data-local install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
install-toolexeclibLTLIBRARIES installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-toolexeclibLTLIBRARIES
# Symbol versioning for shared libraries.

View file

@ -1,8 +1,8 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -13,15 +13,11 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@ -114,42 +110,13 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
EXEEXT = @EXEEXT@
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
FGREP = @FGREP@
GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@ -166,9 +133,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
OBJEXT = @OBJEXT@
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
@ -194,13 +160,13 @@ USE_NLS = @USE_NLS@
VERSION = @VERSION@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
ac_ct_AR = @ac_ct_AR@
ac_ct_AS = @ac_ct_AS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__leading_dot = @am__leading_dot@
am__tar = @am__tar@
am__untar = @am__untar@
@ -211,8 +177,12 @@ build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
check_msgfmt = @check_msgfmt@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
enable_shared = @enable_shared@
enable_static = @enable_static@
exec_prefix = @exec_prefix@
@ -232,29 +202,36 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
port_specific_symbol_files = @port_specific_symbol_files@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
AUTOMAKE_OPTIONS = dejagnu nostdinc
@ -354,10 +331,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
tags: TAGS
TAGS:
@ -370,11 +343,13 @@ check-DEJAGNU: site.exp
EXPECT=$(EXPECT); export EXPECT; \
runtest=$(RUNTEST); \
if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
l='$(DEJATOOL)'; for tool in $$l; do \
$$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
then :; else exit_status=1; fi; \
done; \
else echo "WARNING: could not find \`runtest'" 1>&2; :;\
fi
fi; \
exit $$exit_status
distclean-DEJAGNU:
-rm -f site.exp site.bak
@ -383,23 +358,21 @@ distclean-DEJAGNU:
done
distdir: $(DISTFILES)
$(mkdir_p) $(distdir)/..
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@ -446,8 +419,7 @@ clean-am: clean-generic clean-libtool clean-local mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-DEJAGNU distclean-generic \
distclean-libtool
distclean-am: clean-am distclean-DEJAGNU distclean-generic
dvi: dvi-am
@ -461,12 +433,20 @@ info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
@ -485,18 +465,21 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
clean-libtool clean-local distclean distclean-DEJAGNU \
distclean-generic distclean-libtool distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
# This rule generates all of the testsuite_files* lists at once.