+2006-06-06 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/util: New directory.
+ * testsuite/testsuite_hooks.cc: Move to util sub-directory.
+ * testsuite/testsuite_abi_check.cc: Same.
+ * testsuite/testsuite_abi.cc: Same.
+ * testsuite/testsuite_tr1.h: Same.
+ * testsuite/testsuite_io.h: Same.
+ * testsuite/testsuite_iterators.h: Same.
+ * testsuite/testsuite_allocator.cc: Same.
+ * testsuite/testsuite_allocator.h: Same.
+ * testsuite/testsuite_hooks.h: Same.
+ * testsuite/testsuite_character.cc: Same.
+ * testsuite/testsuite_abi.h: Same.
+ * testsuite/testsuite_character.h: Same.
+ * testsuite/testsuite_visualization.h: Same.
+ * testsuite/testsuite_performance.h: Same.
+ * testsuite/testsuite_shared.cc: Same.
+ * testsuite/testsuite_common_types.h: Same.
+
+ * testsuite/lib/libstdc++.exp (v3-build_support): Adjust paths.
+ * testsuite/libstdc++-abi/abi.exp: Same.
+ * testsuite/libstdc++-dg/conformance.exp: Remove any files in the
+ utilities subdirectory from the list of test cases.
+
+ * scripts/testsuite_flags.in (build-includes): Adjust path for
+ testsuite includes.
+ * scripts/create_testsuite_files (dlist): Don't let utility files
+ creep into the testsuite_files list.
+
2006-06-06 Paolo Carlini <pcarlini@suse.de>
* include/tr1/random (mersenne_twister<>::operator==,
# This is the ugly version of "everything but the current directory". It's
# what has to happen when find(1) doesn't support -mindepth, or -xtype.
dlist=`echo [0-9][0-9]*`
-for d in [a-z]*; do
- test -d $d && dlist="$dlist $d"
-done
+dlist="$dlist backward demangle ext performance thread tr1"
find $dlist "(" -type f -o -type l ")" -name "*.cc" -print > $tmp.01
find $dlist "(" -type f -o -type l ")" -name "*.c" -print > $tmp.02
cat $tmp.01 $tmp.02 | sort > $tmp.1
;;
--build-includes)
INCLUDES="-nostdinc++ @GLIBCXX_INCLUDES@
- -I${SRC_DIR}/include/backward -I${SRC_DIR}/testsuite"
+ -I${SRC_DIR}/include/backward -I${SRC_DIR}/testsuite/util"
echo ${INCLUDES}
;;
--install-cxx)
set object_file [file rootname $f].o
# Compile with "-w" so that warnings issued by the compiler
# do not prevent compilation.
- if { [v3_target_compile $srcdir/$f $object_file "object" \
+ if { [v3_target_compile $srcdir/util/$f $object_file "object" \
[list "incdir=$srcdir" "additional_flags=-w"]]
!= "" } {
error "could not compile $f"
set object_file [file rootname $f].so
# Compile with "-w" so that warnings issued by the compiler
# do not prevent compilation.
- if { [v3_target_compile $srcdir/$f $object_file "sharedlib" \
+ if { [v3_target_compile $srcdir/util/$f $object_file "sharedlib" \
[list "incdir=$srcdir" "additional_flags=-w -shared -fPIC -DPIC"]]
!= "" } {
error "could not compile $f"
[list "../src/.libs/libstdc++.so" "current_symbols.txt"]
# Build the abi_check program.
-if { [v3_target_compile "$srcdir/testsuite_abi_check.cc" "abi_check" \
+if { [v3_target_compile "$srcdir/util/testsuite_abi_check.cc" "abi_check" \
"executable" [list "additional_flags=-w"]] != "" } {
error "could not compile testsuite_abi_check.cc"
}
} else {
# Find directories that might have tests.
set subdirs [glob "$srcdir/\[0-9\]\[0-9\]*"]
- foreach d [glob "$srcdir/\[a-z\]*"] {
- if {[file isdirectory $d]} {
- lappend subdirs $d
- }
- }
+ lappend subdirs "$srcdir/backward"
+ lappend subdirs "$srcdir/demangle"
+ lappend subdirs "$srcdir/ext"
+ lappend subdirs "$srcdir/performance"
+ lappend subdirs "$srcdir/tr1"
+ lappend subdirs "$srcdir/thread"
+ verbose "subdirs are $subdirs"
+
# Find all the tests.
foreach s $subdirs {
set subdir_tests [find $s *.cc]
continue
}
# Filter out:
+ # 0. utilities, other parts of the testing infrastructure.
# 1. interactive tests.
# 2. performance tests.
# 3. wchar_t tests, if not supported.
+++ /dev/null
-// -*- C++ -*-
-
-// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
-
-// This library 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, or (at
-// your option) any later version.
-
-// This library 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.
-
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301, USA.
-
-// 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.
-
-// Benjamin Kosnik <bkoz@redhat.com>
-
-#include "testsuite_abi.h"
-#include <sstream>
-#include <fstream>
-#include <iostream>
-
-using namespace std;
-
-void
-symbol::init(string& data)
-{
- const char delim = ':';
- const char version_delim = '@';
- const string::size_type npos = string::npos;
- string::size_type n = 0;
-
- // Set the type.
- if (data.find("FUNC") == 0)
- type = symbol::function;
- else if (data.find("OBJECT") == 0)
- type = symbol::object;
-
- n = data.find_first_of(delim);
- if (n != npos)
- data.erase(data.begin(), data.begin() + n + 1);
-
- // Iff object, get size info.
- if (type == symbol::object)
- {
- n = data.find_first_of(delim);
- if (n != npos)
- {
- string size(data.begin(), data.begin() + n);
- istringstream iss(size);
- int x;
- iss >> x;
- if (!iss.fail())
- size = x;
- data.erase(data.begin(), data.begin() + n + 1);
- }
- }
-
- // Set the name and raw_name.
- raw_name = string(data.begin(), data.end());
- n = data.find_first_of(version_delim);
- if (n != npos)
- {
- // Found version string.
- name = string(data.begin(), data.begin() + n);
- n = data.find_last_of(version_delim);
- data.erase(data.begin(), data.begin() + n + 1);
-
- // Set version name.
- version_name = data;
- }
- else
- {
- // No versioning info.
- name = string(data.begin(), data.end());
- version_status = symbol::none;
- }
-
- // Set the demangled name.
- demangled_name = demangle(name);
-}
-
-void
-symbol::print() const
-{
- const char tab = '\t';
- cout << name << endl;
-
- if (demangled_name != name)
- cout << demangled_name << endl;
-
- string vers;
- switch (version_status)
- {
- case none:
- vers = "none";
- break;
- case compatible:
- vers = "compatible";
- break;
- case incompatible:
- vers = "incompatible";
- break;
- case unversioned:
- vers = "unversioned";
- break;
- default:
- vers = "<default>";
- }
- cout << "version status: " << vers << endl;
-
- if (version_name.size()
- && (version_status == compatible || version_status == incompatible))
- cout << version_name << endl;
-
- string type_string;
- switch (type)
- {
- case function:
- type_string = "function";
- break;
- case object:
- type_string = "object";
- break;
- case uncategorized:
- type_string = "uncategorized";
- break;
- default:
- type_string = "<default>";
- }
- cout << "type: " << type_string << endl;
-
- if (type == object)
- cout << "type size: " << size << endl;
-
- string status_string;
- switch (status)
- {
- case added:
- status_string = "added";
- break;
- case subtracted:
- status_string = "subtracted";
- break;
- case undesignated:
- status_string = "undesignated";
- break;
- default:
- status_string = "<default>";
- }
- cout << "status: " << status_string << endl;
-
- cout << endl;
-}
-
-
-bool
-check_version(symbol& test, bool added)
-{
- // Construct list of compatible versions.
- typedef std::vector<std::string> compat_list;
- static compat_list known_versions;
- if (known_versions.empty())
- {
- // NB: First version here must be the default version for this
- // version of DT_SONAME.
- known_versions.push_back("GLIBCXX_3.4");
- known_versions.push_back("GLIBCXX_3.4.1");
- known_versions.push_back("GLIBCXX_3.4.2");
- known_versions.push_back("GLIBCXX_3.4.3");
- known_versions.push_back("GLIBCXX_3.4.4");
- known_versions.push_back("GLIBCXX_3.4.5");
- known_versions.push_back("GLIBCXX_3.4.6");
- known_versions.push_back("GLIBCXX_3.4.7");
- known_versions.push_back("GLIBCXX_3.4.8");
- known_versions.push_back("GLIBCXX_3.4.9");
- known_versions.push_back("GLIBCXX_LDBL_3.4");
- known_versions.push_back("GLIBCXX_LDBL_3.4.7");
- known_versions.push_back("CXXABI_1.3");
- known_versions.push_back("CXXABI_1.3.1");
- known_versions.push_back("CXXABI_LDBL_1.3");
- }
- compat_list::iterator begin = known_versions.begin();
- compat_list::iterator end = known_versions.end();
-
- // Check for compatible version.
- if (test.version_name.size())
- {
- compat_list::iterator it1 = find(begin, end, test.version_name);
- compat_list::iterator it2 = find(begin, end, test.name);
- if (it1 != end)
- test.version_status = symbol::compatible;
- else
- test.version_status = symbol::incompatible;
-
- // Check that added symbols aren't added in the base version.
- if (added && test.version_name == known_versions[0])
- test.version_status = symbol::incompatible;
-
- // Check for weak label.
- if (it1 == end && it2 == end)
- test.version_status = symbol::incompatible;
-
- // Check that
- // GLIBCXX_3.4
- // GLIBCXX_3.4.5
- // version as compatible
- // XXX
- }
- else
- {
- if (added)
- {
- // New version labels are ok. The rest are not.
- compat_list::iterator it2 = find(begin, end, test.name);
- if (it2 != end)
- test.version_status = symbol::compatible;
- else
- test.version_status = symbol::incompatible;
- }
- }
- return test.version_status == symbol::compatible;
-}
-
-bool
-check_compatible(symbol& lhs, symbol& rhs, bool verbose)
-{
- bool ret = true;
- const char tab = '\t';
-
- // Check to see if symbol_objects are compatible.
- if (lhs.type != rhs.type)
- {
- ret = false;
- if (verbose)
- cout << tab << "incompatible types" << endl;
- }
-
- if (lhs.name != rhs.name)
- {
- ret = false;
- if (verbose)
- cout << tab << "incompatible names" << endl;
- }
-
- if (lhs.size != rhs.size)
- {
- ret = false;
- if (verbose)
- {
- cout << tab << "incompatible sizes" << endl;
- cout << tab << lhs.size << endl;
- cout << tab << rhs.size << endl;
- }
- }
-
- if (lhs.version_name != rhs.version_name
- && !check_version(lhs) && !check_version(rhs))
- {
- ret = false;
- if (verbose)
- {
- cout << tab << "incompatible versions" << endl;
- cout << tab << lhs.version_name << endl;
- cout << tab << rhs.version_name << endl;
- }
- }
-
- if (verbose)
- cout << endl;
-
- return ret;
-}
-
-
-bool
-has_symbol(const string& mangled, const symbols& s) throw()
-{
- const symbol_names& names = s.first;
- symbol_names::const_iterator i = find(names.begin(), names.end(), mangled);
- return i != names.end();
-}
-
-symbol&
-get_symbol(const string& mangled, const symbols& s)
-{
- const symbol_names& names = s.first;
- symbol_names::const_iterator i = find(names.begin(), names.end(), mangled);
- if (i != names.end())
- {
- symbol_objects objects = s.second;
- return objects[mangled];
- }
- else
- {
- ostringstream os;
- os << "get_symbol failed for symbol " << mangled;
- __throw_logic_error(os.str().c_str());
- }
-}
-
-void
-examine_symbol(const char* name, const char* file)
-{
- try
- {
- symbols s = create_symbols(file);
- symbol& sym = get_symbol(name, s);
- sym.print();
- }
- catch(...)
- { __throw_exception_again; }
-}
-
-int
-compare_symbols(const char* baseline_file, const char* test_file,
- bool verbose)
-{
- // Input both lists of symbols into container.
- symbols baseline = create_symbols(baseline_file);
- symbols test = create_symbols(test_file);
- symbol_names& baseline_names = baseline.first;
- symbol_objects& baseline_objects = baseline.second;
- symbol_names& test_names = test.first;
- symbol_objects& test_objects = test.second;
-
- // Sanity check results.
- const symbol_names::size_type baseline_size = baseline_names.size();
- const symbol_names::size_type test_size = test_names.size();
- if (!baseline_size || !test_size)
- {
- cerr << "Problems parsing the list of exported symbols." << endl;
- exit(2);
- }
-
- // Sort out names.
- // Assuming baseline_names, test_names are both unique w/ no duplicates.
- //
- // The names added to missing_names are baseline_names not found in
- // test_names
- // -> symbols that have been deleted.
- //
- // The names added to added_names are test_names not in
- // baseline_names
- // -> symbols that have been added.
- symbol_names shared_names;
- symbol_names missing_names;
- symbol_names added_names = test_names;
- for (size_t i = 0; i < baseline_size; ++i)
- {
- string what(baseline_names[i]);
- symbol_names::iterator end = added_names.end();
- symbol_names::iterator it = find(added_names.begin(), end, what);
- if (it != end)
- {
- // Found.
- shared_names.push_back(what);
- added_names.erase(it);
- }
- else
- missing_names.push_back(what);
- }
-
- // Check missing names for compatibility.
- typedef pair<symbol, symbol> symbol_pair;
- vector<symbol_pair> incompatible;
- const symbol_names::size_type missing_size = missing_names.size();
- for (size_t j = 0; j < missing_size; ++j)
- {
- symbol& base = baseline_objects[missing_names[j]];
- base.status = symbol::subtracted;
- incompatible.push_back(symbol_pair(base, base));
- }
-
- // Check shared names for compatibility.
- const symbol_names::size_type shared_size = shared_names.size();
- for (size_t k = 0; k < shared_size; ++k)
- {
- symbol& base = baseline_objects[shared_names[k]];
- symbol& test = test_objects[shared_names[k]];
- test.status = symbol::existing;
- if (!check_compatible(base, test))
- incompatible.push_back(symbol_pair(base, test));
- }
-
- // Check added names for compatibility.
- const symbol_names::size_type added_size = added_names.size();
- for (size_t l = 0; l < added_size; ++l)
- {
- symbol& test = test_objects[added_names[l]];
- test.status = symbol::added;
- if (!check_version(test, true))
- incompatible.push_back(symbol_pair(test, test));
- }
-
- // Report results.
- if (verbose && added_names.size())
- {
- cout << endl << added_names.size() << " added symbols " << endl;
- for (size_t j = 0; j < added_names.size() ; ++j)
- {
- cout << j << endl;
- test_objects[added_names[j]].print();
- }
- }
-
- if (verbose && missing_names.size())
- {
- cout << endl << missing_names.size() << " missing symbols " << endl;
- for (size_t j = 0; j < missing_names.size() ; ++j)
- {
- cout << j << endl;
- baseline_objects[missing_names[j]].print();
- }
- }
-
- if (verbose && incompatible.size())
- {
- cout << endl << incompatible.size() << " incompatible symbols " << endl;
- for (size_t j = 0; j < incompatible.size() ; ++j)
- {
- // First, print index.
- cout << j << endl;
-
- // Second, report name.
- symbol& base = incompatible[j].first;
- symbol& test = incompatible[j].second;
- test.print();
-
- // Second, report reason or reasons incompatible.
- check_compatible(base, test, true);
- }
- }
-
- cout << "\n\t\t=== libstdc++-v3 check-abi Summary ===" << endl;
- cout << endl;
- cout << "# of added symbols:\t\t " << added_names.size() << endl;
- cout << "# of missing symbols:\t\t " << missing_names.size() << endl;
- cout << "# of incompatible symbols:\t " << incompatible.size() << endl;
- cout << endl;
- cout << "using: " << baseline_file << endl;
-
- return !(missing_names.size() || incompatible.size());
-}
-
-
-symbols
-create_symbols(const char* file)
-{
- symbols s;
- ifstream ifs(file);
- if (ifs.is_open())
- {
- // Organize file data into container of symbol objects, and a
- // container of mangled names without versioning information.
- symbol_names& names = s.first;
- symbol_objects& objects = s.second;
- const string empty;
- string line = empty;
- while (getline(ifs, line).good())
- {
- symbol tmp;
- tmp.init(line);
- objects[tmp.name] = tmp;
- names.push_back(tmp.name);
- line = empty;
- }
- }
- else
- {
- ostringstream os;
- os << "create_symbols failed for file " << file;
- __throw_runtime_error(os.str().c_str());
- }
- return s;
-}
-
-
-const char*
-demangle(const std::string& mangled)
-{
- const char* name;
- if (mangled[0] != '_' || mangled[1] != 'Z')
- {
- // This is not a mangled symbol, thus has "C" linkage.
- name = mangled.c_str();
- }
- else
- {
- // Use __cxa_demangle to demangle.
- int status = 0;
- name = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
- if (!name)
- {
- switch (status)
- {
- case 0:
- name = "error code = 0: success";
- break;
- case -1:
- name = "error code = -1: memory allocation failure";
- break;
- case -2:
- name = "error code = -2: invalid mangled name";
- break;
- case -3:
- name = "error code = -3: invalid arguments";
- break;
- default:
- name = "error code unknown - who knows what happened";
- }
- }
- }
- return name;
-}
-
+++ /dev/null
-// -*- C++ -*-
-
-// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-
-// This library 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, or (at
-// your option) any later version.
-
-// This library 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.
-
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301, USA.
-
-// 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.
-
-// Benjamin Kosnik <bkoz@redhat.com>
-
-#include <string>
-#include <stdexcept>
-#include <deque>
-#include <ext/hash_map>
-#include <cxxabi.h>
-
-// Encapsulates symbol characteristics.
-struct symbol
-{
- enum category { function, object, uncategorized };
- enum designation { existing, added, subtracted, undesignated };
- enum version { none, compatible, incompatible, unversioned };
- enum compatibility
- {
- compat_type = 1,
- compat_name = 2,
- compat_size = 4,
- compat_version = 8
- };
-
- category type;
- std::string name;
- std::string raw_name; // Name with versioning info still attached.
- std::string demangled_name;
- int size;
- std::string version_name;
- version version_status;
- designation status;
-
- symbol()
- : type(uncategorized), size(0), version_status(unversioned),
- status(undesignated) { }
-
- symbol(const symbol& other)
- : type(other.type), name(other.name), demangled_name(other.demangled_name),
- size(other.size), version_name(other.version_name),
- version_status(other.version_status), status(other.status) { }
-
- void
- print() const;
-
- void
- init(std::string& data);
-};
-
-typedef __gnu_cxx::hash_map<std::string, symbol> symbol_objects;
-
-typedef std::deque<std::string> symbol_names;
-
-typedef std::pair<symbol_names, symbol_objects> symbols;
-
-
-// Check.
-bool
-check_version(symbol& test, bool added = false);
-
-bool
-check_compatible(symbol& lhs, symbol& rhs, bool verbose = false);
-
-
-// Examine.
-bool
-has_symbol(const std::string& mangled, const symbols& list) throw();
-
-symbol&
-get_symbol(const std::string& mangled, const symbols& list);
-
-extern "C" void
-examine_symbol(const char* name, const char* file);
-
-extern "C" int
-compare_symbols(const char* baseline_file, const char* test_file, bool verb);
-
-
-// Util.
-symbols
-create_symbols(const char* file);
-
-const char*
-demangle(const std::string& mangled);
-
-
-// Specialization.
-namespace __gnu_cxx
-{
- using namespace std;
-
- template<>
- struct hash<string>
- {
- size_t operator()(const string& s) const
- {
- const collate<char>& c = use_facet<collate<char> >(locale::classic());
- return c.hash(s.c_str(), s.c_str() + s.size());
- }
- };
-}
+++ /dev/null
-// -*- C++ -*-
-
-// Copyright (C) 2004 Free Software Foundation, Inc.
-
-// This library 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, or (at
-// your option) any later version.
-
-// This library 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.
-
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301, USA.
-
-// 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.
-
-// Benjamin Kosnik <bkoz@redhat.com>
-// Blame subsequent hacks on Loren J. Rittle <ljrittle@acm.org>, Phil
-// Edwards <pme@gcc.gnu.org>, and a cast of dozens at libstdc++@gcc.gnu.org.
-
-#include "testsuite_abi.h"
-#include <iostream>
-#include <unistd.h> // for access(2)
-
-int
-main(int argc, char** argv)
-{
- using namespace std;
-
- // Get arguments. (Heading towards getopt_long, I can feel it.)
- string argv1 = argc > 1 ? argv[1] : "";
- if (argv1 == "--help" || argc < 4)
- {
- cerr << "usage: abi_check --check current baseline\n"
- " --check-verbose current baseline\n"
- " --examine symbol current\n"
- " --help\n"
- "\n"
- "All arguments are string literals.\n"
- "CURRENT is a file generated byextract_symvers.\n"
- "BASELINE is a file from config/abi.\n"
- "SYMBOL is a mangled name.\n"
- << endl;
- exit(1);
- }
-
- if (argv1.find("--check") != string::npos)
- {
- bool verbose = false;
- if (argv1 == "--check-verbose")
- verbose = true;
-
- // Quick sanity/setup check for arguments.
- const char* test_file = argv[2];
- const char* baseline_file = argv[3];
- if (access(test_file, R_OK) != 0)
- {
- cerr << "Cannot read symbols file " << test_file
- << ", did you forget to build first?" << endl;
- exit(1);
- }
- if (access(baseline_file, R_OK) != 0)
- {
- cerr << "Cannot read baseline file " << baseline_file << endl;
- exit(1);
- }
- if (!compare_symbols(baseline_file, test_file, verbose))
- exit (1);
- }
-
- if (argv1 == "--examine")
- {
- const char* file = argv[3];
- if (access(file, R_OK) != 0)
- {
- cerr << "Cannot read symbol file " << file << endl;
- exit(1);
- }
- examine_symbol(argv[2], file);
- }
- return 0;
-}
+++ /dev/null
-// -*- C++ -*-
-// Testing allocator for the C++ library testsuite.
-//
-// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#include <iostream>
-#include <testsuite_allocator.h>
-
-namespace __gnu_test
-{
- allocation_tracker::size_type allocation_tracker::allocationTotal_ = 0;
- allocation_tracker::size_type allocation_tracker::deallocationTotal_ = 0;
- int allocation_tracker::constructCount_ = 0;
- int allocation_tracker::destructCount_ = 0;
-
- bool
- check_construct_destroy(const char* tag, int expected_c, int expected_d)
- {
- if (allocation_tracker::constructCount() == expected_c &&
- allocation_tracker::destructCount() == expected_d)
- return true;
-
- else {
- std::cerr << tag << ": "
- << " construct = " << allocation_tracker::constructCount()
- << " (should be " << expected_c << "),"
- << " destroy = " << allocation_tracker::destructCount()
- << " (should be " << expected_d << ")"
- << std::endl;
- return false;
- }
- }
-
-}; // namespace __cxx_test
-
+++ /dev/null
-// -*- C++ -*-
-// Testing allocator for the C++ library testsuite.
-//
-// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-// This file provides an test instrumentation allocator that can be
-// used to verify allocation functionality of standard library
-// containers. 2002.11.25 smw
-
-#ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H
-#define _GLIBCXX_TESTSUITE_ALLOCATOR_H
-
-#include <cstddef>
-#include <limits>
-#include <tr1/unordered_map>
-#include <cassert>
-
-namespace
-{
- bool new_called = false;
- bool delete_called = false;
-};
-
-namespace __gnu_test
-{
- class allocation_tracker
- {
- public:
- typedef std::size_t size_type;
-
- static void*
- allocate(size_type blocksize)
- {
- allocationTotal_ += blocksize;
- return ::operator new(blocksize);
- }
-
- static void
- construct() { constructCount_++; }
-
- static void
- destroy() { destructCount_++; }
-
- static void
- deallocate(void* p, size_type blocksize)
- {
- ::operator delete(p);
- deallocationTotal_ += blocksize;
- }
-
- static size_type
- allocationTotal() { return allocationTotal_; }
-
- static size_type
- deallocationTotal() { return deallocationTotal_; }
-
- static int
- constructCount() { return constructCount_; }
-
- static int
- destructCount() { return destructCount_; }
-
- static void
- resetCounts()
- {
- allocationTotal_ = 0;
- deallocationTotal_ = 0;
- constructCount_ = 0;
- destructCount_ = 0;
- }
-
- private:
- static size_type allocationTotal_;
- static size_type deallocationTotal_;
- static int constructCount_;
- static int destructCount_;
- };
-
- // A simple basic allocator that just forwards to the
- // allocation_tracker to fulfill memory requests. This class is
- // templated on the target object type, but tracker isn't.
- template<class T>
- class tracker_alloc
- {
- public:
- typedef T value_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- template<class U> struct rebind { typedef tracker_alloc<U> other; };
-
- pointer
- address(reference value) const
- { return &value; }
-
- const_pointer
- address(const_reference value) const
- { return &value; }
-
- tracker_alloc() throw()
- { }
-
- tracker_alloc(const tracker_alloc&) throw()
- { }
-
- template<class U>
- tracker_alloc(const tracker_alloc<U>&) throw()
- { }
-
- ~tracker_alloc() throw()
- { }
-
- size_type
- max_size() const throw()
- { return std::numeric_limits<std::size_t>::max() / sizeof(T); }
-
- pointer
- allocate(size_type n, const void* = 0)
- {
- return static_cast<pointer>(allocation_tracker::allocate(n * sizeof(T)));
- }
-
- void
- construct(pointer p, const T& value)
- {
- new (p) T(value);
- allocation_tracker::construct();
- }
-
- void
- destroy(pointer p)
- {
- p->~T();
- allocation_tracker::destroy();
- }
-
- void
- deallocate(pointer p, size_type num)
- { allocation_tracker::deallocate(p, num * sizeof(T)); }
- };
-
- template<class T1, class T2>
- bool
- operator==(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
- { return true; }
-
- template<class T1, class T2>
- bool
- operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
- { return false; }
-
- bool
- check_construct_destroy(const char* tag, int expected_c, int expected_d);
-
- template<typename Alloc, bool uses_global_new>
- bool
- check_new(Alloc a = Alloc())
- {
- bool test __attribute__((unused)) = true;
- a.allocate(10);
- test &= ( new_called == uses_global_new );
- return test;
- }
-
- template<typename Alloc, bool uses_global_delete>
- bool
- check_delete(Alloc a = Alloc())
- {
- bool test __attribute__((unused)) = true;
- typename Alloc::pointer p = a.allocate(10);
- a.deallocate(p, 10);
- test &= ( delete_called == uses_global_delete );
- return test;
- }
-
- template<typename Alloc>
- bool
- check_deallocate_null()
- {
- // Let's not core here...
- Alloc a;
- a.deallocate(NULL, 1);
- a.deallocate(NULL, 10);
- return true;
- }
-
- template<typename Alloc>
- bool
- check_allocate_max_size()
- {
- Alloc a;
- try
- {
- a.allocate(a.max_size() + 1);
- }
- catch(std::bad_alloc&)
- {
- return true;
- }
- catch(...)
- {
- throw;
- }
- throw;
- }
-
-
- // A simple allocator which can be constructed endowed of a given
- // "personality" (an integer), queried in operator== to simulate the
- // behavior of realworld "unequal" allocators (i.e., not exploiting
- // the provision in 20.1.5/4, first bullet). A global unordered_map,
- // filled at allocation time with (pointer, personality) pairs, is
- // then consulted to enforce the requirements in Table 32 about
- // deallocation vs allocator equality. Note that this allocator is
- // swappable, not assignable, consistently with Option 3 of DR 431
- // (see N1599).
- struct uneq_allocator_base
- {
- typedef std::tr1::unordered_map<void*, int> map_type;
-
- // Avoid static initialization troubles and/or bad interactions
- // with tests linking testsuite_allocator.o and playing globally
- // with operator new/delete.
- static map_type&
- get_map()
- {
- static map_type alloc_map;
- return alloc_map;
- }
- };
-
- template<typename Tp>
- class uneq_allocator
- : private uneq_allocator_base
- {
- public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef Tp* pointer;
- typedef const Tp* const_pointer;
- typedef Tp& reference;
- typedef const Tp& const_reference;
- typedef Tp value_type;
-
- template<typename Tp1>
- struct rebind
- { typedef uneq_allocator<Tp1> other; };
-
- uneq_allocator() throw()
- : personality(0) { }
-
- uneq_allocator(int person) throw()
- : personality(person) { }
-
- template<typename Tp1>
- uneq_allocator(const uneq_allocator<Tp1>& b) throw()
- : personality(b.get_personality()) { }
-
- int get_personality() const { return personality; }
-
- pointer
- address(reference x) const { return &x; }
-
- const_pointer
- address(const_reference x) const { return &x; }
-
- pointer
- allocate(size_type n, const void* = 0)
- {
- if (__builtin_expect(n > this->max_size(), false))
- std::__throw_bad_alloc();
-
- pointer p = static_cast<Tp*>(::operator new(n * sizeof(Tp)));
- try
- {
- get_map().insert(map_type::value_type(reinterpret_cast<void*>(p),
- personality));
- }
- catch(...)
- {
- ::operator delete(p);
- __throw_exception_again;
- }
- return p;
- }
-
- void
- deallocate(pointer p, size_type)
- {
- assert( p );
-
- map_type::iterator it = get_map().find(reinterpret_cast<void*>(p));
- assert( it != get_map().end() );
-
- // Enforce requirements in Table 32 about deallocation vs
- // allocator equality.
- assert( it->second == personality );
-
- get_map().erase(it);
- ::operator delete(p);
- }
-
- size_type
- max_size() const throw()
- { return size_t(-1) / sizeof(Tp); }
-
- void
- construct(pointer p, const Tp& val)
- { ::new(p) Tp(val); }
-
- void
- destroy(pointer p) { p->~Tp(); }
-
- private:
- // Not assignable...
- uneq_allocator&
- operator=(const uneq_allocator&);
-
- // ... yet swappable!
- friend inline void
- swap(uneq_allocator& a, uneq_allocator& b)
- { std::swap(a.personality, b.personality); }
-
- template<typename Tp1>
- friend inline bool
- operator==(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
- { return a.personality == b.personality; }
-
- template<typename Tp1>
- friend inline bool
- operator!=(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
- { return !(a == b); }
-
- int personality;
- };
-
-
- template<typename Tp>
- class throw_allocator
- {
- public:
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef Tp* pointer;
- typedef const Tp* const_pointer;
- typedef Tp& reference;
- typedef const Tp& const_reference;
- typedef Tp value_type;
-
- template<typename Tp1>
- struct rebind
- { typedef throw_allocator<Tp1> other; };
-
- throw_allocator() throw()
- : count(size_type(-1)) { }
-
- throw_allocator(size_type c) throw()
- : count(c) { }
-
- template<typename Tp1>
- throw_allocator(const throw_allocator<Tp1>& b) throw()
- : count(b.get_count()) { }
-
- size_type get_count() const { return count; }
-
- pointer
- address(reference x) const { return &x; }
-
- const_pointer
- address(const_reference x) const { return &x; }
-
- pointer
- allocate(size_type n, const void* = 0)
- {
- if (count == 0)
- throw std::bad_alloc();
-
- if (count != size_type(-1))
- --count;
-
- return static_cast<Tp*>(::operator new(n * sizeof(Tp)));
- }
-
- void
- deallocate(pointer p, size_type)
- { ::operator delete(p); }
-
- size_type
- max_size() const throw()
- { return size_type(-1) / sizeof(Tp); }
-
- void
- construct(pointer p, const Tp& val)
- { ::new(p) Tp(val); }
-
- void
- destroy(pointer p) { p->~Tp(); }
-
- private:
- template<typename Tp1>
- friend inline bool
- operator==(const throw_allocator&, const throw_allocator<Tp1>&)
- { return true; }
-
- template<typename Tp1>
- friend inline bool
- operator!=(const throw_allocator&, const throw_allocator<Tp1>&)
- { return false; }
-
- size_type count;
- };
-}; // namespace __gnu_test
-
-#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
+++ /dev/null
-// -*- C++ -*-
-
-// Utility subroutines for the C++ library testsuite.
-//
-// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#include <testsuite_character.h>
-
-namespace std
-{
- locale::id
- codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>::id;
-
- locale::id
- ctype<__gnu_test::pod_uchar>::id;
-
- locale::id
- numpunct<__gnu_test::pod_uint>::id;
-
- locale::id
- moneypunct<__gnu_test::pod_uint>::id;
-
- // Member specializations for the existing facet classes.
- // NB: This isn't especially portable. Perhaps a better way would be
- // to just specialize all of numpunct and ctype.
- using __gnu_test::pod_ushort;
- typedef pod_ushort::value_type value_type;
-
- template<>
- bool
- ctype<pod_ushort>::
- do_is(mask, char_type) const { return true; }
-
- template<>
- const pod_ushort*
- ctype<pod_ushort>::
- do_is(const char_type* __lo, const char_type*, mask*) const
- { return __lo; }
-
- template<>
- const pod_ushort*
- ctype<pod_ushort>::
- do_scan_is(mask, const char_type* __lo, const char_type*) const
- { return __lo; }
-
- template<>
- const pod_ushort*
- ctype<pod_ushort>::
- do_scan_not(mask, const char_type* __lo, const char_type*) const
- { return __lo; }
-
- template<>
- pod_ushort
- ctype<pod_ushort>::
- do_toupper(char_type __c) const
- { return __c; }
-
- template<>
- const pod_ushort*
- ctype<pod_ushort>::
- do_toupper(char_type*, const char_type* __hi) const
- { return __hi; }
-
- template<>
- pod_ushort
- ctype<pod_ushort>::
- do_tolower(char_type __c) const
- { return __c; }
-
- template<>
- const pod_ushort*
- ctype<pod_ushort>::
- do_tolower(char_type*, const char_type* __hi) const
- { return __hi; }
-
- template<>
- pod_ushort
- ctype<pod_ushort>::
- do_widen(char __c) const
- {
- char_type ret = { value_type(__c) };
- return ret;
- }
-
- template<>
- const char*
- ctype<pod_ushort>::
- do_widen(const char* __lo, const char* __hi, char_type* __dest) const
- {
- while (__lo < __hi)
- {
- *__dest = this->do_widen(*__lo);
- ++__lo;
- ++__dest;
- }
- return __hi;
- }
-
- template<>
- char
- ctype<pod_ushort>::
- do_narrow(char_type __wc, char) const
- { return static_cast<char>(__wc.value); }
-
- template<>
- const pod_ushort*
- ctype<pod_ushort>::
- do_narrow(const pod_ushort* __lo, const pod_ushort* __hi,
- char, char* __dest) const
- {
- while (__lo < __hi)
- {
- *__dest = this->do_narrow(*__lo, char());
- ++__lo;
- ++__dest;
- }
- return __hi;
- }
-
- template<>
- ctype<pod_ushort>::~ctype() { }
-
- template<>
- void
- numpunct<pod_ushort>::_M_initialize_numpunct(__c_locale)
- {
- if (!_M_data)
- _M_data = new __numpunct_cache<pod_ushort>;
-
- _M_data->_M_grouping = "";
- _M_data->_M_use_grouping = false;
-
- _M_data->_M_decimal_point.value = value_type('.');
- _M_data->_M_thousands_sep.value = value_type(',');
-
- for (size_t i = 0; i < __num_base::_S_oend; ++i)
- {
- value_type v = __num_base::_S_atoms_out[i];
- _M_data->_M_atoms_out[i].value = v;
- }
- _M_data->_M_atoms_out[__num_base::_S_oend] = pod_ushort();
-
- for (size_t j = 0; j < __num_base::_S_iend; ++j)
- _M_data->_M_atoms_in[j].value = value_type(__num_base::_S_atoms_in[j]);
- _M_data->_M_atoms_in[__num_base::_S_iend] = pod_ushort();
-
- // "true"
- pod_ushort* __truename = new pod_ushort[4 + 1];
- __truename[0].value = value_type('t');
- __truename[1].value = value_type('r');
- __truename[2].value = value_type('u');
- __truename[3].value = value_type('e');
- __truename[4] = pod_ushort();
- _M_data->_M_truename = __truename;
-
- // "false"
- pod_ushort* __falsename = new pod_ushort[5 + 1];
- __falsename[0].value = value_type('f');
- __falsename[1].value = value_type('a');
- __falsename[2].value = value_type('l');
- __falsename[3].value = value_type('s');
- __falsename[4].value = value_type('e');
- __falsename[5] = pod_ushort();
- _M_data->_M_falsename = __falsename;
- }
-
- template<>
- numpunct<pod_ushort>::~numpunct()
- { delete _M_data; }
-} // namespace std
+++ /dev/null
-// -*- C++ -*-
-
-// Testing character type and state type with char_traits and codecvt
-// specializations for the C++ library testsuite.
-//
-// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H
-#define _GLIBCXX_TESTSUITE_CHARACTER_H
-
-#include <climits>
-#include <string> // for char_traits
-#include <locale> // for codecvt
-#include <ext/pod_char_traits.h>
-
-namespace __gnu_test
-{
- struct pod_int
- {
- int value;
- };
-
- inline bool
- operator==(const pod_int& lhs, const pod_int& rhs)
- { return lhs.value == rhs.value; }
-
- inline bool
- operator<(const pod_int& lhs, const pod_int& rhs)
- { return lhs.value < rhs.value; }
-
- struct pod_state
- {
- unsigned long value;
- };
-
- inline bool
- operator==(const pod_state& lhs, const pod_state& rhs)
- { return lhs.value == rhs.value; }
-
- inline bool
- operator<(const pod_state& lhs, const pod_state& rhs)
- { return lhs.value < rhs.value; }
-
- // Alternate character types.
- using __gnu_cxx::character;
- typedef character<unsigned char, pod_int, pod_state> pod_char;
- typedef character<unsigned char, unsigned int, pod_state> pod_uchar;
- typedef character<unsigned short, unsigned int> pod_ushort;
- typedef character<unsigned int, unsigned long> pod_uint;
-}
-
-namespace __gnu_cxx
-{
- // Specializations.
- // pod_char
- template<>
- template<typename V2>
- inline __gnu_test::pod_char::char_type
- __gnu_test::pod_char::char_type::from(const V2& v)
- {
- char_type ret = { static_cast<value_type>(v.value) };
- return ret;
- }
-
- template<>
- template<typename V2>
- inline V2
- __gnu_test::pod_char::char_type::to(const char_type& c)
- {
- V2 ret = { c.value };
- return ret;
- }
-
- template<>
- template<typename V2>
- inline __gnu_test::pod_uchar::char_type
- __gnu_test::pod_uchar::char_type::from(const V2& v)
- {
- char_type ret;
- ret.value = (v >> 5);
- return ret;
- }
-
- template<>
- template<typename V2>
- inline V2
- __gnu_test::pod_uchar::char_type::to(const char_type& c)
- { return static_cast<V2>(c.value << 5); }
-}; // namespace __gnu_test
-
-namespace std
-{
- // codecvt specialization
- //
- // The conversion performed by the specialization is not supposed to
- // be useful, rather it has been designed to demonstrate the
- // essential features of stateful conversions:
- // * Number and value of bytes for each internal character depends on the
- // state in addition to the character itself.
- // * Unshift produces an unshift sequence and resets the state. On input
- // the unshift sequence causes the state to be reset.
- //
- // The conversion for output is as follows:
- // 1. Calculate the value tmp by xor-ing the state and the internal
- // character
- // 2. Split tmp into either two or three bytes depending on the value of
- // state. Output those bytes.
- // 3. tmp becomes the new value of state.
- template<>
- class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>
- : public __codecvt_abstract_base<__gnu_test::pod_uchar, char,
- __gnu_test::pod_state>
- {
- public:
- typedef codecvt_base::result result;
- typedef __gnu_test::pod_uchar intern_type;
- typedef char extern_type;
- typedef __gnu_test::pod_state state_type;
- typedef __codecvt_abstract_base<intern_type, extern_type, state_type>
- base_type;
-
- explicit codecvt(size_t refs = 0) : base_type(refs)
- { }
-
- static locale::id id;
-
- protected:
- ~codecvt()
- { }
-
- virtual result
- do_out(state_type& state, const intern_type* from,
- const intern_type* from_end, const intern_type*& from_next,
- extern_type* to, extern_type* to_limit,
- extern_type*& to_next) const
- {
- while (from < from_end && to < to_limit)
- {
- unsigned char tmp = (state.value ^ from->value);
- if (state.value & 0x8)
- {
- if (to >= to_limit - 2)
- break;
- *to++ = (tmp & 0x7);
- *to++ = ((tmp >> 3) & 0x7);
- *to++ = ((tmp >> 6) & 0x3);
- }
- else
- {
- if (to >= to_limit - 1)
- break;
- *to++ = (tmp & 0xf);
- *to++ = ((tmp >> 4) & 0xf);
- }
- state.value = tmp;
- ++from;
- }
-
- from_next = from;
- to_next = to;
- return (from < from_end) ? partial : ok;
- }
-
- virtual result
- do_in(state_type& state, const extern_type* from,
- const extern_type* from_end, const extern_type*& from_next,
- intern_type* to, intern_type* to_limit,
- intern_type*& to_next) const
- {
- while (from < from_end && to < to_limit)
- {
- unsigned char c = *from;
- if (c & 0xc0)
- {
- // Unshift sequence
- state.value &= c;
- ++from;
- continue;
- }
-
- unsigned char tmp;
- if (state.value & 0x8)
- {
- if (from >= from_end - 2)
- break;
- tmp = (*from++ & 0x7);
- tmp |= ((*from++ << 3) & 0x38);
- tmp |= ((*from++ << 6) & 0xc0);
- }
- else
- {
- if (from >= from_end - 1)
- break;
- tmp = (*from++ & 0xf);
- tmp |= ((*from++ << 4) & 0xf0);
- }
- to->value = (tmp ^ state.value);
- state.value = tmp;
- ++to;
- }
-
- from_next = from;
- to_next = to;
- return (from < from_end) ? partial : ok;
- }
-
- virtual result
- do_unshift(state_type& state, extern_type* to, extern_type* to_limit,
- extern_type*& to_next) const
- {
- for (unsigned int i = 0; i < CHAR_BIT; ++i)
- {
- unsigned int mask = (1 << i);
- if (state.value & mask)
- {
- if (to == to_limit)
- {
- to_next = to;
- return partial;
- }
-
- state.value &= ~mask;
- *to++ = static_cast<unsigned char>(~mask);
- }
- }
-
- to_next = to;
- return state.value == 0 ? ok : error;
- }
-
- virtual int
- do_encoding() const throw()
- { return -1; }
-
- virtual bool
- do_always_noconv() const throw()
- { return false; }
-
- virtual int
- do_length(state_type& state, const extern_type* from,
- const extern_type* end, size_t max) const
- {
- const extern_type* beg = from;
- while (from < end && max)
- {
- unsigned char c = *from;
- if (c & 0xc0)
- {
- // Unshift sequence
- state.value &= c;
- ++from;
- continue;
- }
-
- unsigned char tmp;
- if (state.value & 0x8)
- {
- if (from >= end - 2)
- break;
- tmp = (*from++ & 0x7);
- tmp |= ((*from++ << 3) & 0x38);
- tmp |= ((*from++ << 6) & 0xc0);
- }
- else
- {
- if (from >= end - 1)
- break;
- tmp = (*from++ & 0xf);
- tmp |= ((*from++ << 4) & 0xf0);
- }
- state.value = tmp;
- --max;
- }
- return from - beg;
- }
-
- // Maximum 8 bytes unshift sequence followed by max 3 bytes for
- // one character.
- virtual int
- do_max_length() const throw()
- { return 11; }
- };
-
- template<>
- class ctype<__gnu_test::pod_uchar>
- : public __ctype_abstract_base<__gnu_test::pod_uchar>
- {
- public:
- typedef __gnu_test::pod_uchar char_type;
-
- explicit ctype(size_t refs = 0)
- : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { }
-
- static locale::id id;
-
- protected:
- ~ctype()
- { }
-
- virtual bool
- do_is(mask, char_type) const
- { return false; }
-
- virtual const char_type*
- do_is(const char_type* low, const char_type* high, mask* vec) const
- {
- fill_n(vec, high - low, mask());
- return high;
- }
-
- virtual const char_type*
- do_scan_is(mask, const char_type*, const char_type* high) const
- { return high; }
-
- virtual const char_type*
- do_scan_not(mask, const char_type* low, const char_type*) const
- { return low; }
-
- virtual char_type
- do_toupper(char_type c) const
- { return c; }
-
- virtual const char_type*
- do_toupper(char_type*, const char_type* high) const
- { return high; }
-
- virtual char_type
- do_tolower(char_type c) const
- { return c; }
-
- virtual const char_type*
- do_tolower(char_type*, const char_type* high) const
- { return high; }
-
- virtual char_type
- do_widen(char c) const
- { return __gnu_test::pod_uchar::from<char>(c); }
-
- virtual const char*
- do_widen(const char* low, const char* high, char_type* dest) const
- {
- transform(low, high, dest, &__gnu_test::pod_uchar::from<char>);
- return high;
- }
-
- virtual char
- do_narrow(char_type, char dfault) const
- { return dfault; }
-
- virtual const char_type*
- do_narrow(const char_type* low, const char_type* high,
- char dfault, char* dest) const
- {
- fill_n(dest, high - low, dfault);
- return high;
- }
- };
-
- // numpunct specializations
- template<>
- class numpunct<__gnu_test::pod_uint>
- : public locale::facet
- {
- public:
- typedef __gnu_test::pod_uint char_type;
- typedef basic_string<char_type> string_type;
-
- static locale::id id;
-
- explicit
- numpunct(size_t refs = 0)
- : locale::facet(refs)
- { }
-
- char_type
- decimal_point() const
- { return this->do_decimal_point(); }
-
- char_type
- thousands_sep() const
- { return this->do_thousands_sep(); }
-
- string
- grouping() const
- { return this->do_grouping(); }
-
- string_type
- truename() const
- { return this->do_truename(); }
-
- string_type
- falsename() const
- { return this->do_falsename(); }
-
- protected:
- ~numpunct()
- { }
-
- virtual char_type
- do_decimal_point() const
- { return char_type(); }
-
- virtual char_type
- do_thousands_sep() const
- { return char_type(); }
-
- virtual string
- do_grouping() const
- { return string(); }
-
- virtual string_type
- do_truename() const
- { return string_type(); }
-
- virtual string_type
- do_falsename() const
- { return string_type(); }
- };
-
- template<>
- class moneypunct<__gnu_test::pod_uint>
- : public locale::facet, public money_base
- {
- public:
- typedef __gnu_test::pod_uint char_type;
- typedef basic_string<char_type> string_type;
-
- static locale::id id;
- static const bool intl = false;
-
- explicit
- moneypunct(size_t refs = 0)
- : locale::facet(refs)
- { }
-
- char_type
- decimal_point() const
- { return this->do_decimal_point(); }
-
- char_type
- thousands_sep() const
- { return this->do_thousands_sep(); }
-
- string
- grouping() const
- { return this->do_grouping(); }
-
- string_type
- curr_symbol() const
- { return this->do_curr_symbol(); }
-
- string_type
- positive_sign() const
- { return this->do_positive_sign(); }
-
- string_type
- negative_sign() const
- { return this->do_negative_sign(); }
-
- int
- frac_digits() const
- { return this->do_frac_digits(); }
-
- pattern
- pos_format() const
- { return this->do_pos_format(); }
-
- pattern
- neg_format() const
- { return this->do_neg_format(); }
-
- protected:
- ~moneypunct()
- { }
-
- virtual char_type
- do_decimal_point() const
- { return char_type(); }
-
- virtual char_type
- do_thousands_sep() const
- { return char_type(); }
-
- virtual string
- do_grouping() const
- { return string(); }
-
- virtual string_type
- do_curr_symbol() const
- { return string_type(); }
-
- string_type
- do_positive_sign() const
- { return string_type(); }
-
- string_type
- do_negative_sign() const
- { return string_type(); }
-
- int
- do_frac_digits() const
- { return 0; }
-
- pattern
- do_pos_format() const
- { return pattern(); }
-
- pattern
- do_neg_format() const
- { return pattern(); }
- };
-} // namespace std
-
-#endif // _GLIBCXX_TESTSUITE_CHARACTER_H
-
+++ /dev/null
-// -*- C++ -*-
-// typelist for the C++ library testsuite.
-//
-// Copyright (C) 2005 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#ifndef _TESTSUITE_COMMON_TYPES_H
-#define _TESTSUITE_COMMON_TYPES_H 1
-
-#include <testsuite_visualization.h>
-#include <ext/typelist.h>
-
-#include <ext/new_allocator.h>
-#include <ext/malloc_allocator.h>
-#include <ext/mt_allocator.h>
-#include <ext/bitmap_allocator.h>
-#include <ext/pool_allocator.h>
-
-#include <vector>
-#include <list>
-#include <deque>
-#include <string>
-
-#include <map>
-#include <set>
-#include <ext/hash_map>
-#include <ext/hash_set>
-#include <tr1/unordered_map>
-#include <tr1/unordered_set>
-
-namespace __gnu_test
-{
- using __gnu_cxx::typelist;
- using __gnu_cxx::transform;
- using __gnu_cxx::append;
-
- // All the allocators to test.
- template<typename Tp, bool Thread>
- struct allocator_policies
- {
- typedef Tp value_type;
- typedef __gnu_cxx::new_allocator<Tp> a1;
- typedef __gnu_cxx::malloc_allocator<Tp> a2;
- typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy;
- typedef __gnu_cxx::__mt_alloc<Tp, pool_policy> a3;
- typedef __gnu_cxx::bitmap_allocator<Tp> a4;
- typedef __gnu_cxx::__pool_alloc<Tp> a5;
- typedef typelist<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type;
- };
-
- // Typelists for vector, string, list, deque.
- // XXX should just use template templates
- template<typename Tp, bool Thread>
- struct vectors
- {
- typedef Tp value_type;
-
- template<typename Tl>
- struct vector_shell
- {
- typedef Tl allocator_type;
- typedef std::vector<value_type, allocator_type> type;
- };
-
- typedef allocator_policies<value_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, vector_shell>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct lists
- {
- typedef Tp value_type;
-
- template<typename Tl>
- struct list_shell
- {
- typedef Tl allocator_type;
- typedef std::list<value_type, allocator_type> type;
- };
-
- typedef allocator_policies<value_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, list_shell>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct deques
- {
- typedef Tp value_type;
-
- template<typename Tl>
- struct deque_shell
- {
- typedef Tl allocator_type;
- typedef std::deque<value_type, allocator_type> type;
- };
-
- typedef allocator_policies<value_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, deque_shell>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct strings
- {
- typedef Tp value_type;
-
- template<typename Tl>
- struct string_shell
- {
- typedef Tl allocator_type;
- typedef std::char_traits<value_type> traits_type;
- typedef std::basic_string<value_type, traits_type, allocator_type> type;
- };
-
- typedef allocator_policies<value_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, string_shell>::type type;
- };
-
- // A typelist of vector, list, deque, and string all instantiated
- // with each of the allocator policies.
- template<typename Tp, bool Thread>
- struct sequence_containers
- {
- typedef Tp value_type;
-
- typedef typename vectors<value_type, Thread>::type vector_typelist;
- typedef typename lists<value_type, Thread>::type list_typelist;
- typedef typename deques<value_type, Thread>::type deque_typelist;
- typedef typename strings<value_type, Thread>::type string_typelist;
-
- typedef typename append<vector_typelist, list_typelist>::type a1;
- typedef typename append<deque_typelist, string_typelist>::type a2;
- typedef typename append<a1, a2>::type type;
- };
-
- // Typelists for map, set, hash_map, hash_set, unordered_set, unordered_map.
- template<typename Tp, bool Thread>
- struct maps
- {
- typedef Tp value_type;
- typedef Tp key_type;
- typedef std::pair<const key_type, value_type> pair_type;
- typedef std::less<key_type> compare_function;
-
- template<typename Tl>
- struct container
- {
- typedef Tl allocator_type;
- typedef std::map<key_type, value_type, compare_function, allocator_type> type;
- };
-
- typedef allocator_policies<pair_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, container>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct hash_maps
- {
- typedef Tp value_type;
- typedef Tp key_type;
- typedef __gnu_cxx::hash<key_type> hash_function;
- typedef std::equal_to<key_type> equality_function;
-
- template<typename Tl>
- struct container
- {
- typedef Tl allocator_type;
- typedef __gnu_cxx::hash_map<key_type, value_type, hash_function, equality_function, allocator_type> type;
- };
-
- typedef allocator_policies<value_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, container>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct unordered_maps
- {
- typedef Tp value_type;
- typedef Tp key_type;
- typedef std::pair<const key_type, value_type> pair_type;
- typedef std::tr1::hash<key_type> hash_function;
- typedef std::equal_to<key_type> equality_function;
-
- template<typename Tl>
- struct container
- {
- typedef Tl allocator_type;
- typedef std::tr1::unordered_map<key_type, value_type, hash_function, equality_function, allocator_type> type;
- };
-
- typedef allocator_policies<pair_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, container>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct sets
- {
- typedef Tp value_type;
- typedef Tp key_type;
- typedef std::less<key_type> compare_function;
-
- template<typename Tl>
- struct container
- {
- typedef Tl allocator_type;
- typedef std::set<key_type, compare_function, allocator_type> type;
- };
-
- typedef allocator_policies<key_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, container>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct hash_sets
- {
- typedef Tp value_type;
- typedef Tp key_type;
- typedef __gnu_cxx::hash<key_type> hash_function;
- typedef std::equal_to<key_type> equality_function;
-
- template<typename Tl>
- struct container
- {
- typedef Tl allocator_type;
- typedef __gnu_cxx::hash_set<key_type, hash_function, equality_function, allocator_type> type;
- };
-
- typedef allocator_policies<key_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, container>::type type;
- };
-
- template<typename Tp, bool Thread>
- struct unordered_sets
- {
- typedef Tp value_type;
- typedef Tp key_type;
- typedef std::tr1::hash<key_type> hash_function;
- typedef std::equal_to<key_type> equality_function;
-
- template<typename Tl>
- struct container
- {
- typedef Tl allocator_type;
- typedef std::tr1::unordered_set<key_type, hash_function, equality_function, allocator_type> type;
- };
-
- typedef allocator_policies<key_type, Thread> allocator_types;
- typedef typename allocator_types::type allocator_typelist;
- typedef typename transform<allocator_typelist, container>::type type;
- };
-
-
- // A typelist of all associated container types, with each of the
- // allocator policies.
- template<typename Tp, bool Thread>
- struct associative_containers
- {
- typedef Tp value_type;
-
- typedef typename maps<value_type, Thread>::type map_typelist;
- typedef typename sets<value_type, Thread>::type set_typelist;
- typedef typename hash_maps<value_type, Thread>::type hash_map_typelist;
- typedef typename hash_sets<value_type, Thread>::type hash_set_typelist;
- typedef typename unordered_maps<value_type, Thread>::type unordered_map_typelist;
- typedef typename unordered_sets<value_type, Thread>::type unordered_set_typelist;
-
- typedef typename append<map_typelist, hash_map_typelist>::type a1;
- typedef typename append<a1, unordered_map_typelist>::type a2;
- typedef typename append<set_typelist, hash_set_typelist>::type a3;
- typedef typename append<a3, unordered_set_typelist>::type a4;
- typedef typename append<a2, a4>::type type;
- };
-
-} // namespace __gnu_test
-
-
-// Function template, function objects for the tests.
-template<typename TestType>
- struct value_type : public std::pair<const TestType, TestType>
- {
- inline value_type& operator++()
- {
- ++this->second;
- return *this;
- }
-
- inline operator TestType() const { return this->second; }
- };
-
-template<typename Container, int Iter>
- void
- do_loop();
-
-template<typename Container, int Iter>
- void*
- do_thread(void* p = NULL)
- {
- do_loop<Container, Iter>();
- return p;
- }
-
-template<typename Container, int Iter, bool Thread>
- void
- test_container(const char* filename)
- {
- using namespace __gnu_test;
- time_counter time;
- resource_counter resource;
- {
- start_counters(time, resource);
- if (!Thread)
- {
- // No threads, so run 4x.
- do_loop<Container, Iter * 4>();
- }
- else
- {
-#if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD)
- pthread_t t1, t2, t3, t4;
- pthread_create(&t1, 0, &do_thread<Container, Iter>, 0);
- pthread_create(&t2, 0, &do_thread<Container, Iter>, 0);
- pthread_create(&t3, 0, &do_thread<Container, Iter>, 0);
- pthread_create(&t4, 0, &do_thread<Container, Iter>, 0);
-
- pthread_join(t1, NULL);
- pthread_join(t2, NULL);
- pthread_join(t3, NULL);
- pthread_join(t4, NULL);
-#endif
- }
- stop_counters(time, resource);
-
- // Detailed text data.
- Container obj;
- int status;
- std::ostringstream comment;
- comment << "type: " << abi::__cxa_demangle(typeid(obj).name(),
- 0, 0, &status);
- report_header(filename, comment.str());
- report_performance("", "", time, resource);
-
- // Detailed data for visualization.
- std::string vizfilename(filename);
- vizfilename += ".dat";
- write_viz_data(time, vizfilename.c_str());
- }
- }
-
-template<bool Thread>
- struct test_sequence
- {
- test_sequence(const char* filename) : _M_filename(filename) { }
-
- template<class Container>
- void
- operator()(__gnu_cxx::detail::type_to_type<Container>)
- {
- const int i = 20000;
- test_container<Container, i, Thread>(_M_filename);
- }
-
- private:
- const char* _M_filename;
- };
-
-
-inline std::string::size_type
-sequence_find_container(std::string& type)
-{
- const std::string::size_type npos = std::string::npos;
- std::string::size_type n1 = type.find("vector");
- std::string::size_type n2 = type.find("list");
- std::string::size_type n3 = type.find("deque");
- std::string::size_type n4 = type.find("string");
-
- if (n1 != npos || n2 != npos || n3 != npos || n4 != npos)
- return std::min(std::min(n1, n2), std::min(n3, n4));
- else
- throw std::runtime_error("sequence_find_container not found");
-}
-
-inline std::string::size_type
-associative_find_container(std::string& type)
-{
- using std::string;
- string::size_type n1 = type.find("map");
- string::size_type n2 = type.find("set");
- if (n1 != string::npos || n2 != string::npos)
- return std::min(n1, n2);
- else
- throw std::runtime_error("associative_find_container not found");
-}
-#endif
+++ /dev/null
-// -*- C++ -*-
-
-// Utility subroutines for the C++ library testsuite.
-//
-// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#include <testsuite_hooks.h>
-
-#ifdef _GLIBCXX_RES_LIMITS
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-#include <list>
-#include <string>
-#include <stdexcept>
-#include <clocale>
-#include <locale>
-#include <cxxabi.h>
-
-// If we have <sys/types.h>, <sys/ipc.h>, and <sys/sem.h>, then assume
-// that System V semaphores are available.
-#if defined(_GLIBCXX_HAVE_SYS_TYPES_H) \
- && defined(_GLIBCXX_HAVE_SYS_IPC_H) \
- && defined(_GLIBCXX_HAVE_SYS_SEM_H)
-#define _GLIBCXX_SYSV_SEM
-#endif
-
-#ifdef _GLIBCXX_SYSV_SEM
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#endif
-
-namespace __gnu_test
-{
-#ifdef _GLIBCXX_RES_LIMITS
- void
- set_memory_limits(float size)
- {
- struct rlimit r;
- // Cater to the absence of rlim_t.
- __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size * 1048576);
-
- // Heap size, seems to be common.
-#if _GLIBCXX_HAVE_LIMIT_DATA
- getrlimit(RLIMIT_DATA, &r);
- r.rlim_cur = limit;
- setrlimit(RLIMIT_DATA, &r);
-#endif
-
- // Resident set size.
-#if _GLIBCXX_HAVE_LIMIT_RSS
- getrlimit(RLIMIT_RSS, &r);
- r.rlim_cur = limit;
- setrlimit(RLIMIT_RSS, &r);
-#endif
-
- // Mapped memory (brk + mmap).
-#if _GLIBCXX_HAVE_LIMIT_VMEM
- getrlimit(RLIMIT_VMEM, &r);
- r.rlim_cur = limit;
- setrlimit(RLIMIT_VMEM, &r);
-#endif
-
- // Virtual memory.
- // On HP-UX 11.23, a trivial C++ program that sets RLIMIT_AS to
- // anything less than 128MB cannot "malloc" even 1K of memory.
- // Therefore, we skip RLIMIT_AS on HP-UX.
-#if _GLIBCXX_HAVE_LIMIT_AS && !defined(__hpux__)
- getrlimit(RLIMIT_AS, &r);
- r.rlim_cur = limit;
- setrlimit(RLIMIT_AS, &r);
-#endif
- }
-
-#else
- void
- set_memory_limits(float) { }
-#endif
-
-#ifdef _GLIBCXX_RES_LIMITS
- void
- set_file_limit(unsigned long size)
- {
-#if _GLIBCXX_HAVE_LIMIT_FSIZE
- struct rlimit r;
- // Cater to the absence of rlim_t.
- __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size);
-
- getrlimit(RLIMIT_FSIZE, &r);
- r.rlim_cur = limit;
- setrlimit(RLIMIT_FSIZE, &r);
-#endif
- }
-
-#else
- void
- set_file_limit(unsigned long) { }
-#endif
-
- void
- verify_demangle(const char* mangled, const char* wanted)
- {
- int status = 0;
- const char* s = abi::__cxa_demangle(mangled, 0, 0, &status);
- if (!s)
- {
- switch (status)
- {
- case 0:
- s = "error code = 0: success";
- break;
- case -1:
- s = "error code = -1: memory allocation failure";
- break;
- case -2:
- s = "error code = -2: invalid mangled name";
- break;
- case -3:
- s = "error code = -3: invalid arguments";
- break;
- default:
- s = "error code unknown - who knows what happened";
- }
- }
-
- std::string w(wanted);
- if (w != s)
- std::__throw_runtime_error(s);
- }
-
- void
- run_tests_wrapped_locale(const char* name, const func_callback& l)
- {
- using namespace std;
- bool test = true;
-
- // Set the global locale.
- locale loc_name = locale(name);
- locale orig = locale::global(loc_name);
-
- const char* res = setlocale(LC_ALL, name);
- if (res != NULL)
- {
- string preLC_ALL = res;
- const func_callback::test_type* tests = l.tests();
- for (int i = 0; i < l.size(); ++i)
- (*tests[i])();
- string postLC_ALL= setlocale(LC_ALL, NULL);
- VERIFY( preLC_ALL == postLC_ALL );
- }
- else
- {
- string s("LC_ALL for ");
- s += name;
- __throw_runtime_error(s.c_str());
- }
- }
-
- void
- run_tests_wrapped_env(const char* name, const char* env,
- const func_callback& l)
- {
- using namespace std;
- bool test = true;
-
-#ifdef _GLIBCXX_HAVE_SETENV
- // Set the global locale.
- locale loc_name = locale(name);
- locale orig = locale::global(loc_name);
-
- // Set environment variable env to value in name.
- const char* oldENV = getenv(env);
- if (!setenv(env, name, 1))
- {
- const func_callback::test_type* tests = l.tests();
- for (int i = 0; i < l.size(); ++i)
- (*tests[i])();
- setenv(env, oldENV ? oldENV : "", 1);
- }
- else
- {
- string s(env);
- s += string(" to ");
- s += string(name);
- __throw_runtime_error(s.c_str());
- }
-#endif
- }
-
- counter::size_type counter::count = 0;
- unsigned int copy_constructor::count_ = 0;
- unsigned int copy_constructor::throw_on_ = 0;
- unsigned int assignment_operator::count_ = 0;
- unsigned int assignment_operator::throw_on_ = 0;
- unsigned int destructor::_M_count = 0;
- int copy_tracker::next_id_ = 0;
-
-#ifdef _GLIBCXX_SYSV_SEM
- // This union is not declared in system headers. Instead, it must
- // be defined by user programs.
- union semun
- {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- };
-#endif
-
- semaphore::semaphore()
- {
-#ifdef _GLIBCXX_SYSV_SEM
- // Remeber the PID for the process that created the semaphore set
- // so that only one process will destroy the set.
- pid_ = getpid();
-
- // GLIBC does not define SEM_R and SEM_A.
-#ifndef SEM_R
-#define SEM_R 0400
-#endif
-
-#ifndef SEM_A
-#define SEM_A 0200
-#endif
-
- // Get a semaphore set with one semaphore.
- sem_set_ = semget(IPC_PRIVATE, 1, SEM_R | SEM_A);
- if (sem_set_ == -1)
- std::__throw_runtime_error("could not obtain semaphore set");
-
- // Initialize the semaphore.
- union semun val;
- val.val = 0;
- if (semctl(sem_set_, 0, SETVAL, val) == -1)
- std::__throw_runtime_error("could not initialize semaphore");
-#else
- // There are no semaphores on this system. We have no way to mark
- // a test as "unsupported" at runtime, so we just exit, pretending
- // that the test passed.
- exit(0);
-#endif
- }
-
- semaphore::~semaphore()
- {
-#ifdef _GLIBCXX_SYSV_SEM
- union semun val;
- // Destroy the semaphore set only in the process that created it.
- if (pid_ == getpid())
- semctl(sem_set_, 0, IPC_RMID, val);
-#endif
- }
-
- void
- semaphore::signal()
- {
-#ifdef _GLIBCXX_SYSV_SEM
- struct sembuf op[1] =
- {
- { 0, 1, 0 }
- };
- if (semop(sem_set_, op, 1) == -1)
- std::__throw_runtime_error("could not signal semaphore");
-#endif
- }
-
- void
- semaphore::wait()
- {
-#ifdef _GLIBCXX_SYSV_SEM
- struct sembuf op[1] =
- {
- { 0, -1, SEM_UNDO }
- };
- if (semop(sem_set_, op, 1) == -1)
- std::__throw_runtime_error("could not wait for semaphore");
-#endif
- }
-
- // For use in 22_locale/time_get and time_put.
- tm
- test_tm(int sec, int min, int hour, int mday, int mon,
- int year, int wday, int yday, int isdst)
- {
- static tm tmp;
- tmp.tm_sec = sec;
- tmp.tm_min = min;
- tmp.tm_hour = hour;
- tmp.tm_mday = mday;
- tmp.tm_mon = mon;
- tmp.tm_year = year;
- tmp.tm_wday = wday;
- tmp.tm_yday = yday;
- tmp.tm_isdst = isdst;
- return tmp;
- }
-}; // namespace __gnu_test
+++ /dev/null
-// -*- C++ -*-
-// Utility subroutines for the C++ library testsuite.
-//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
-// Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-// This file provides the following:
-//
-// 1) VERIFY(), via _GLIBCXX_ASSERT, from Brent Verner <brent@rcfile.org>.
-// This file is included in the various testsuite programs to provide
-// #define(able) assert() behavior for debugging/testing. It may be
-// a suitable location for other furry woodland creatures as well.
-//
-// 2) set_memory_limits()
-// set_memory_limits() uses setrlimit() to restrict dynamic memory
-// allocation. We provide a default memory limit if none is passed by the
-// calling application. The argument to set_memory_limits() is the
-// limit in megabytes (a floating-point number). If _GLIBCXX_RES_LIMITS is
-// not #defined before including this header, then no limiting is attempted.
-//
-// 3) counter
-// This is a POD with a static data member, gnu_counting_struct::count,
-// which starts at zero, increments on instance construction, and decrements
-// on instance destruction. "assert_count(n)" can be called to VERIFY()
-// that the count equals N.
-//
-// 4) copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>.
-// A class with nontrivial ctor/dtor that provides the ability to track the
-// number of copy ctors and dtors, and will throw on demand during copy.
-
-#ifndef _GLIBCXX_TESTSUITE_HOOKS_H
-#define _GLIBCXX_TESTSUITE_HOOKS_H
-
-#include <bits/c++config.h>
-#include <bits/functexcept.h>
-#include <cstddef>
-#include <locale>
-#ifdef _GLIBCXX_HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef _GLIBCXX_ASSERT
-# include <cassert>
-# define VERIFY(fn) assert(fn)
-#else
-# define VERIFY(fn) test &= (fn)
-#endif
-
-#ifdef _GLIBCXX_HAVE_UNISTD_H
-# include <unistd.h>
-#else
-# define unlink(x)
-#endif
-
-namespace __gnu_test
-{
- // All macros are defined in GLIBCXX_CONFIGURE_TESTSUITE and imported
- // from c++config.h
-
- // Set memory limits if possible, if not set to 0.
-#ifndef _GLIBCXX_RES_LIMITS
-# define MEMLIMIT_MB 0
-#else
-# ifndef MEMLIMIT_MB
-# define MEMLIMIT_MB 16.0
-# endif
-#endif
- extern void
- set_memory_limits(float __size = MEMLIMIT_MB);
-
- extern void
- set_file_limit(unsigned long __size);
-
- // Check mangled name demangles (using __cxa_demangle) as expected.
- void
- verify_demangle(const char* mangled, const char* wanted);
-
- // 17.3.2.1.2 - Bitmask types [lib.bitmask.types]
- // bitmask_operators
- template<typename bitmask_type>
- void
- bitmask_operators(bitmask_type a = bitmask_type(),
- bitmask_type b = bitmask_type())
- {
- a | b;
- a & b;
- a ^ b;
- ~b;
- a |= b; // set
- a &= ~b; // clear
- a ^= b;
- }
-
- // Simple callback structure for variable numbers of tests (all with
- // same signature). Assume all unit tests are of the signature
- // void test01();
- class func_callback
- {
- public:
- typedef void (*test_type) (void);
-
- private:
- int _M_size;
- test_type _M_tests[15];
-
- func_callback&
- operator=(const func_callback&);
-
- func_callback(const func_callback&);
-
- public:
- func_callback(): _M_size(0) { };
-
- int
- size() const { return _M_size; }
-
- const test_type*
- tests() const { return _M_tests; }
-
- void
- push_back(test_type test)
- {
- _M_tests[_M_size] = test;
- ++_M_size;
- }
- };
-
-
- // Run select unit tests after setting global locale.
- void
- run_tests_wrapped_locale(const char*, const func_callback&);
-
- // Run select unit tests after setting environment variables.
- void
- run_tests_wrapped_env(const char*, const char*, const func_callback&);
-
-
- // For containers (23.1/3).
- struct NonDefaultConstructible
- {
- NonDefaultConstructible(int) { }
- };
-
- inline bool
- operator==(const NonDefaultConstructible&,
- const NonDefaultConstructible&)
- { return false; }
-
- inline bool
- operator<(const NonDefaultConstructible&,
- const NonDefaultConstructible&)
- { return false; }
-
-
- // Counting.
- struct counter
- {
- // Specifically and glaringly-obviously marked 'signed' so that when
- // COUNT mistakenly goes negative, we can track the patterns of
- // deletions more easily.
- typedef signed int size_type;
- static size_type count;
- counter() { ++count; }
- counter (const counter&) { ++count; }
- ~counter() { --count; }
- };
-
-#define assert_count(n) VERIFY(__gnu_test::counter::count == n)
-
- // A (static) class for counting copy constructors and possibly throwing an
- // exception on a desired count.
- class copy_constructor
- {
- public:
- static unsigned int
- count() { return count_; }
-
- static void
- mark_call()
- {
- count_++;
- if (count_ == throw_on_)
- std::__throw_runtime_error("copy_constructor::mark_call");
- }
-
- static void
- reset()
- {
- count_ = 0;
- throw_on_ = 0;
- }
-
- static void
- throw_on(unsigned int count) { throw_on_ = count; }
-
- private:
- static unsigned int count_;
- static unsigned int throw_on_;
- };
-
- // A (static) class for counting assignment operator calls and
- // possibly throwing an exception on a desired count.
- class assignment_operator
- {
- public:
- static unsigned int
- count() { return count_; }
-
- static void
- mark_call()
- {
- count_++;
- if (count_ == throw_on_)
- std::__throw_runtime_error("assignment_operator::mark_call");
- }
-
- static void
- reset()
- {
- count_ = 0;
- throw_on_ = 0;
- }
-
- static void
- throw_on(unsigned int count) { throw_on_ = count; }
-
- private:
- static unsigned int count_;
- static unsigned int throw_on_;
- };
-
- // A (static) class for tracking calls to an object's destructor.
- class destructor
- {
- public:
- static unsigned int
- count() { return _M_count; }
-
- static void
- mark_call() { _M_count++; }
-
- static void
- reset() { _M_count = 0; }
-
- private:
- static unsigned int _M_count;
- };
-
- // An class of objects that can be used for validating various
- // behaviours and guarantees of containers and algorithms defined in
- // the standard library.
- class copy_tracker
- {
- public:
- // Creates a copy-tracking object with the given ID number. If
- // "throw_on_copy" is set, an exception will be thrown if an
- // attempt is made to copy this object.
- copy_tracker(int id = next_id_--, bool throw_on_copy = false)
- : id_(id) , throw_on_copy_(throw_on_copy) { }
-
- // Copy-constructs the object, marking a call to the copy
- // constructor and forcing an exception if indicated.
- copy_tracker(const copy_tracker& rhs)
- : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_)
- {
- if (throw_on_copy_)
- copy_constructor::throw_on(copy_constructor::count() + 1);
- copy_constructor::mark_call();
- }
-
- // Assigns the value of another object to this one, tracking the
- // number of times this member function has been called and if the
- // other object is supposed to throw an exception when it is
- // copied, well, make it so.
- copy_tracker&
- operator=(const copy_tracker& rhs)
- {
- id_ = rhs.id();
- if (rhs.throw_on_copy_)
- assignment_operator::throw_on(assignment_operator::count() + 1);
- assignment_operator::mark_call();
- return *this;
- }
-
- ~copy_tracker()
- { destructor::mark_call(); }
-
- int
- id() const { return id_; }
-
- private:
- int id_;
- const bool throw_on_copy_;
-
- public:
- static void
- reset()
- {
- copy_constructor::reset();
- assignment_operator::reset();
- destructor::reset();
- }
-
- // for backwards-compatibility
- static int
- copyCount()
- { return copy_constructor::count(); }
-
- // for backwards-compatibility
- static int
- dtorCount()
- { return destructor::count(); }
-
- private:
- static int next_id_;
- };
-
- inline bool
- operator==(const copy_tracker& lhs, const copy_tracker& rhs)
- { return lhs.id() == rhs.id(); }
-
- // Class for checking required type conversions, implicit and
- // explicit for given library data structures.
- template<typename _Container>
- struct conversion
- {
- typedef typename _Container::const_iterator const_iterator;
-
- // Implicit conversion iterator to const_iterator.
- static const_iterator
- iterator_to_const_iterator()
- {
- _Container v;
- const_iterator it = v.begin();
- const_iterator end = v.end();
- return it == end ? v.end() : it;
- }
- };
-
- // A binary semaphore for use across multiple processes.
- class semaphore
- {
- public:
- // Creates a binary semaphore. The semaphore is initially in the
- // unsignaled state.
- semaphore();
-
- // Destroy the semaphore.
- ~semaphore();
-
- // Signal the semaphore. If there are processes blocked in
- // "wait", exactly one will be permitted to proceed.
- void signal();
-
- // Wait until the semaphore is signaled.
- void wait();
-
- private:
- int sem_set_;
-
- pid_t pid_;
- };
-
- // For use in 22_locale/time_get and time_put.
- tm test_tm(int sec, int min, int hour, int mday, int mon,
- int year, int wday, int yday, int isdst);
-
-} // namespace __gnu_test
-
-#endif // _GLIBCXX_TESTSUITE_HOOKS_H
-
+++ /dev/null
-// -*- C++ -*-
-// Testing streambuf/filebuf/stringbuf for the C++ library testsuite.
-//
-// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#ifndef _GLIBCXX_TESTSUITE_IO_H
-#define _GLIBCXX_TESTSUITE_IO_H
-
-#include <fstream>
-#include <sstream>
-
-namespace __gnu_test
-{
- // Used to verify the constraints/requirements on get and put areas
- // as defined in
- // 27.5.1 - Stream buffer requirements: get and put areas
- // 27.8.1.1 - Template class basic_filebuf p 3
- // If the file is not open (ios_base::in) -> input seq. cannot be read
- // If the file is not open (ios_base::out) -> output seq. cannot be written
- // Joint file position
- // 27.8.1.4 - Overridden virtual functions p9
- // If unbuffered, pbase == pptr == NULL
- // 27.7.1.1 - Basic_stringbuf constructors p 1
- // 27.8.1.2 - Basic_filebuf constructors p 1
- // ... , initializing the base class with basic_streambuf() 27.5.2.1
- template<typename T>
- class constraint_buf
- : public T
- {
- public:
- bool
- write_position()
- {
- bool one = this->pptr() != NULL;
- bool two = this->pptr() < this->epptr();
- return one && two;
- }
-
- bool
- read_position()
- {
- bool one = this->gptr() != NULL;
- bool two = this->gptr() < this->egptr();
- return one && two;
- }
-
- bool
- unbuffered()
- {
- bool one = this->pbase() == NULL;
- bool two = this->pptr() == NULL;
- return one && two;
- }
-
- bool
- check_pointers()
- {
- bool one = this->eback() == NULL;
- bool two = this->gptr() == NULL;
- bool three = this->egptr() == NULL;
-
- bool four = this->pbase() == NULL;
- bool five = this->pptr() == NULL;
- bool six = this->epptr() == NULL;
- return one && two && three && four && five && six;
- }
- };
-
- typedef constraint_buf<std::streambuf> constraint_streambuf;
- typedef constraint_buf<std::filebuf> constraint_filebuf;
- typedef constraint_buf<std::stringbuf> constraint_stringbuf;
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef constraint_buf<std::wstreambuf> constraint_wstreambuf;
- typedef constraint_buf<std::wfilebuf> constraint_wfilebuf;
- typedef constraint_buf<std::wstringbuf> constraint_wstringbuf;
-#endif
-
- // Used to check if basic_streambuf::pubsync() has been called.
- // This is useful for checking if a function creates [io]stream::sentry
- // objects, since the sentry constructors call tie()->flush().
- template<typename T>
- class sync_buf
- : public T
- {
- private:
- bool m_sync_called;
-
- public:
- sync_buf()
- : m_sync_called(false)
- { }
-
- bool sync_called() const
- { return m_sync_called; }
-
- protected:
- int sync()
- {
- m_sync_called = true;
- return 0;
- }
- };
-
- typedef sync_buf<std::streambuf> sync_streambuf;
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef sync_buf<std::wstreambuf> sync_wstreambuf;
-#endif
-
- // Throws on all overflow and underflow calls.
- struct underflow_error: std::exception { };
- struct overflow_error: std::exception { };
- struct positioning_error: std::exception { };
-
- template<typename T>
- struct fail_buf
- : public T
- {
- typedef typename T::char_type char_type;
- typedef typename T::int_type int_type;
- typedef typename T::off_type off_type;
- typedef typename T::pos_type pos_type;
-
- private:
- char_type p[2];
-
- public:
- fail_buf()
- {
- p[0] = char_type('s');
- p[1] = char_type();
- setg(p, p, p + 1);
- }
-
- virtual int_type underflow()
- {
- throw underflow_error();
- return int_type();
- }
-
- virtual int_type uflow()
- {
- throw underflow_error();
- return int_type();
- }
-
- virtual int_type
- overflow(int_type)
- {
- throw overflow_error();
- return int_type();
- }
-
- virtual pos_type
- seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode)
- {
- throw positioning_error();
- return pos_type(off_type(-1));
- }
-
- virtual pos_type
- seekpos(pos_type, std::ios_base::openmode)
- {
- throw positioning_error();
- return pos_type(off_type(-1));
- }
-
- virtual int
- sync()
- {
- throw positioning_error();
- return 0;
- }
- };
-
- typedef fail_buf<std::streambuf> fail_streambuf;
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef fail_buf<std::wstreambuf> fail_wstreambuf;
-#endif
-
- // Facets that throw an exception for every virtual function.
- struct facet_error: std::exception { };
-
- template<typename T>
- class fail_num_get
- : public std::num_get<T>
- {
- typedef std::ios_base ios_base;
- typedef typename std::num_get<T>::iter_type iter_type;
-
- protected:
- iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- unsigned short&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- unsigned int&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- unsigned long&) const
- { throw facet_error(); return iter_type(); }
-
-#ifdef _GLIBCXX_USE_LONG_LONG
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- long long&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- unsigned long long&) const
- { throw facet_error(); return iter_type(); }
-#endif
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- float&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- double&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- long double&) const
- { throw facet_error(); return iter_type(); }
-
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
- void*&) const
- { throw facet_error(); return iter_type(); }
- };
-
- typedef fail_num_get<char> fail_num_get_char;
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef fail_num_get<wchar_t> fail_num_get_wchar_t;
-#endif
-
- template<typename T>
- class fail_num_put
- : public std::num_put<T>
- {
- typedef std::ios_base ios_base;
- typedef typename std::num_put<T>::iter_type iter_type;
- typedef typename std::num_put<T>::char_type char_type;
-
- protected:
- iter_type
- do_put(iter_type, ios_base&, char_type, bool) const
- { throw facet_error(); return iter_type(NULL); }
-
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, long) const
- { throw facet_error(); return iter_type(NULL); }
-
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, unsigned long) const
- { throw facet_error(); return iter_type(NULL); }
-
-#ifdef _GLIBCXX_USE_LONG_LONG
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, long long) const
- { throw facet_error(); return iter_type(NULL); }
-
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, unsigned long long) const
- { throw facet_error(); return iter_type(NULL); }
-#endif
-
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, double) const
- { throw facet_error(); return iter_type(NULL); }
-
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, long double) const
- { throw facet_error(); return iter_type(NULL); }
-
- virtual iter_type
- do_put(iter_type, ios_base&, char_type, const void*) const
- { throw facet_error(); return iter_type(NULL); }
- };
-
- typedef fail_num_put<char> fail_num_put_char;
-#ifdef _GLIBCXX_USE_WCHAR_T
- typedef fail_num_put<wchar_t> fail_num_put_wchar_t;
-#endif
-}; // namespace __gnu_test
-
-#endif // _GLIBCXX_TESTSUITE_IO_H
-
+++ /dev/null
-// -*- C++ -*-
-// Iterator Wrappers for the C++ library testsuite.
-//
-// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-// This file provides the following:
-//
-// input_iterator_wrapper, output_iterator_wrapper
-// forward_iterator_wrapper, bidirectional_iterator_wrapper and
-// random_access_wrapper, which attempt to exactly perform the requirements
-// of these types of iterators. These are constructed from the class
-// test_container, which is given two pointers to T and an iterator type.
-
-#include <testsuite_hooks.h>
-#include <iterator>
-
-#ifndef _TESTSUITE_ITERATORS
-#define _TESTSUITE_ITERATORS
-
-#ifdef DISABLE_ITERATOR_DEBUG
-#define ITERATOR_VERIFY(x)
-#else
-#define ITERATOR_VERIFY(x) VERIFY(x)
-#endif
-
-namespace __gnu_test
-{
- /**
- * @brief Simple container for holding two pointers.
- *
- * Note that input_iterator_wrapper changes first to denote
- * how the valid range of == , ++, etc. change as the iterators are used.
- */
- template<typename T>
- struct BoundsContainer
- {
- T* first;
- T* last;
- BoundsContainer(T* _first, T* _last)
- : first(_first), last(_last)
- { }
- };
-
- // Simple container for holding state of a set of output iterators.
- template<typename T>
- struct OutputContainer : public BoundsContainer<T>
- {
- T* incrementedto;
- bool* writtento;
- OutputContainer(T* _first, T* _last)
- : BoundsContainer<T>(_first, _last), incrementedto(_first)
- {
- writtento = new bool[this->last - this->first];
- for(int i = 0; i < this->last - this->first; i++)
- writtento[i] = false;
- }
-
- ~OutputContainer()
- { delete[] writtento; }
- };
-
- // Produced by output_iterator to allow limited writing to pointer
- template<class T>
- class WritableObject
- {
- T* ptr;
-
- public:
- OutputContainer<T>* SharedInfo;
- WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
- ptr(ptr_in), SharedInfo(SharedInfo_in)
- { }
-
- template<class U>
- void
- operator=(const U& new_val)
- {
- ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
- SharedInfo->writtento[ptr - SharedInfo->first] = 1;
- *ptr = new_val;
- }
- };
-
- /**
- * @brief output_iterator wrapper for pointer
- *
- * This class takes a pointer and wraps it to provide exactly
- * the requirements of a output_iterator. It should not be
- * instansiated directly, but generated from a test_container
- */
- template<class T>
- struct output_iterator_wrapper: public std::iterator
- <std::output_iterator_tag, T, ptrdiff_t, T*, T&>
- {
- typedef OutputContainer<T> ContainerType;
- T* ptr;
- ContainerType* SharedInfo;
-
- output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
- :ptr(_ptr), SharedInfo(SharedInfo_in)
- {
- ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
- }
-
- output_iterator_wrapper(const output_iterator_wrapper& in)
- :ptr(in.ptr), SharedInfo(in.SharedInfo)
- { }
-
- WritableObject<T>
- operator*() const
- {
- ITERATOR_VERIFY(ptr < SharedInfo->last);
- ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
- return WritableObject<T>(ptr, SharedInfo);
- }
-
- output_iterator_wrapper&
- operator=(const output_iterator_wrapper& in)
- {
- ptr = in.ptr;
- SharedInfo = in.SharedInfo;
- return *this;
- }
-
- output_iterator_wrapper&
- operator++()
- {
- ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
- ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
- ptr++;
- SharedInfo->incrementedto=ptr;
- return *this;
- }
-
- output_iterator_wrapper
- operator++(int)
- {
- output_iterator_wrapper<T> tmp = *this;
- ++*this;
- return tmp;
- }
-
- };
-
- /**
- * @brief input_iterator wrapper for pointer
- *
- * This class takes a pointer and wraps it to provide exactly
- * the requirements of a input_iterator. It should not be
- * instansiated directly, but generated from a test_container
- */
- template<class T>
- class input_iterator_wrapper:public std::iterator
- <std::input_iterator_tag, T, ptrdiff_t, T*, T&>
- {
- protected:
- input_iterator_wrapper()
- { }
-
- public:
- typedef BoundsContainer<T> ContainerType;
- T* ptr;
- ContainerType* SharedInfo;
-
- input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
- : ptr(_ptr), SharedInfo(SharedInfo_in)
- { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
-
- input_iterator_wrapper(const input_iterator_wrapper& in)
- : ptr(in.ptr), SharedInfo(in.SharedInfo)
- { }
-
- bool
- operator==(const input_iterator_wrapper& in) const
- {
- ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
- ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
- return ptr == in.ptr;
- }
-
- bool
- operator!=(const input_iterator_wrapper& in) const
- {
- return !(*this == in);
- }
-
- T&
- operator*() const
- {
- ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
- ITERATOR_VERIFY(ptr >= SharedInfo->first);
- return *ptr;
- }
-
- T*
- operator->() const
- {
- return &**this;
- }
-
- input_iterator_wrapper&
- operator=(const input_iterator_wrapper& in)
- {
- ptr = in.ptr;
- SharedInfo = in.SharedInfo;
- return *this;
- }
-
- input_iterator_wrapper&
- operator++()
- {
- ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
- ITERATOR_VERIFY(ptr>=SharedInfo->first);
- ptr++;
- SharedInfo->first=ptr;
- return *this;
- }
-
- void
- operator++(int)
- {
- ++*this;
- }
- };
-
-
- /**
- * @brief forward_iterator wrapper for pointer
- *
- * This class takes a pointer and wraps it to provide exactly
- * the requirements of a forward_iterator. It should not be
- * instansiated directly, but generated from a test_container
- */
- template<class T>
- struct forward_iterator_wrapper:public input_iterator_wrapper<T>
- {
- typedef BoundsContainer<T> ContainerType;
- typedef std::forward_iterator_tag iterator_category;
- forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
- :input_iterator_wrapper<T>(_ptr, SharedInfo_in)
- { }
-
- forward_iterator_wrapper(const forward_iterator_wrapper& in)
- :input_iterator_wrapper<T>(in)
- { }
-
- forward_iterator_wrapper()
- {
- this->ptr = NULL;
- this->SharedInfo = NULL;
- }
-
- T&
- operator*() const
- {
- ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
- return *(this->ptr);
- }
-
- T*
- operator->() const
- { return &**this; }
-
- forward_iterator_wrapper&
- operator++()
- {
- ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
- this->ptr++;
- return *this;
- }
-
- forward_iterator_wrapper
- operator++(int)
- {
- forward_iterator_wrapper<T> tmp = *this;
- ++*this;
- return tmp;
- }
- };
-
- /**
- * @brief bidirectional_iterator wrapper for pointer
- *
- * This class takes a pointer and wraps it to provide exactly
- * the requirements of a forward_iterator. It should not be
- * instansiated directly, but generated from a test_container
- */
- template<class T>
- struct bidirectional_iterator_wrapper:public forward_iterator_wrapper<T>
- {
- typedef BoundsContainer<T> ContainerType;
- typedef std::bidirectional_iterator_tag iterator_category;
- bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
- :forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
- { }
-
- bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
- :forward_iterator_wrapper<T>(in)
- { }
-
- bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
- { }
-
- bidirectional_iterator_wrapper&
- operator=(const bidirectional_iterator_wrapper& in)
- {
- this->ptr = in.ptr;
- this->SharedInfo = in.SharedInfo;
- return *this;
- }
-
- bidirectional_iterator_wrapper&
- operator++()
- {
- ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
- this->ptr++;
- return *this;
- }
-
- bidirectional_iterator_wrapper
- operator++(int)
- {
- bidirectional_iterator_wrapper<T> tmp = *this;
- ++*this;
- return tmp;
- }
-
- bidirectional_iterator_wrapper&
- operator--()
- {
- ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
- this->ptr--;
- return *this;
- }
-
- bidirectional_iterator_wrapper
- operator--(int)
- {
- bidirectional_iterator_wrapper<T> tmp = *this;
- --*this;
- return tmp;
- }
- };
-
- /**
- * @brief random_access_iterator wrapper for pointer
- *
- * This class takes a pointer and wraps it to provide exactly
- * the requirements of a forward_iterator. It should not be
- * instansiated directly, but generated from a test_container
- */
- template<class T>
- struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper<T>
- {
- typedef BoundsContainer<T> ContainerType;
- typedef std::random_access_iterator_tag iterator_category;
- random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
- : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
- { }
-
- random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
- : bidirectional_iterator_wrapper<T>(in)
- { }
-
- random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
- { }
-
- random_access_iterator_wrapper&
- operator=(const random_access_iterator_wrapper& in)
- {
- this->ptr = in.ptr;
- this->SharedInfo = in.SharedInfo;
- return *this;
- }
-
- random_access_iterator_wrapper&
- operator++()
- {
- ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
- this->ptr++;
- return *this;
- }
-
- random_access_iterator_wrapper
- operator++(int)
- {
- random_access_iterator_wrapper<T> tmp = *this;
- ++*this;
- return tmp;
- }
-
- random_access_iterator_wrapper&
- operator--()
- {
- ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
- this->ptr--;
- return *this;
- }
-
- random_access_iterator_wrapper
- operator--(int)
- {
- random_access_iterator_wrapper<T> tmp = *this;
- --*this;
- return tmp;
- }
-
- random_access_iterator_wrapper&
- operator+=(ptrdiff_t n)
- {
- if(n > 0)
- {
- ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
- this->ptr += n;
- }
- else
- {
- ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
- this->ptr += n;
- }
- return *this;
- }
-
- random_access_iterator_wrapper&
- operator-=(ptrdiff_t n)
- { return *this += -n; }
-
- random_access_iterator_wrapper
- operator-(ptrdiff_t n) const
- {
- random_access_iterator_wrapper<T> tmp = *this;
- return tmp -= n;
- }
-
- ptrdiff_t
- operator-(const random_access_iterator_wrapper<T>& in) const
- {
- ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
- return this->ptr - in.ptr;
- }
-
- T&
- operator[](ptrdiff_t n) const
- { return *(*this + n); }
-
- bool
- operator<(const random_access_iterator_wrapper<T>& in) const
- {
- ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
- return this->ptr < in.ptr;
- }
-
- bool
- operator>(const random_access_iterator_wrapper<T>& in) const
- {
- return in < *this;
- }
-
- bool
- operator>=(const random_access_iterator_wrapper<T>& in) const
- {
- return !(*this < in);
- }
-
- bool
- operator<=(const random_access_iterator_wrapper<T>& in) const
- {
- return !(*this > in);
- }
- };
-
- template<typename T>
- random_access_iterator_wrapper<T>
- operator+(random_access_iterator_wrapper<T> it, ptrdiff_t n)
- { return it += n; }
-
- template<typename T>
- random_access_iterator_wrapper<T>
- operator+(ptrdiff_t n, random_access_iterator_wrapper<T> it)
- { return it += n; }
-
-
- /**
- * @brief A container-type class for holding iterator wrappers
- * test_container takes two parameters, a class T and an iterator
- * wrapper templated by T (for example forward_iterator_wrapper<T>.
- * It takes two pointers representing a range and presents them as
- * a container of iterators.
- */
- template <class T, template<class T> class ItType>
- struct test_container
- {
- typename ItType<T>::ContainerType bounds;
- test_container(T* _first, T* _last):bounds(_first, _last)
- { }
-
- ItType<T>
- it(int pos)
- {
- ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
- return ItType<T>(bounds.first + pos, &bounds);
- }
-
- ItType<T>
- it(T* pos)
- {
- ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
- return ItType<T>(pos, &bounds);
- }
-
- ItType<T>
- begin()
- { return it(bounds.first); }
-
- ItType<T>
- end()
- { return it(bounds.last); }
- };
-}
-#endif
+++ /dev/null
-// -*- C++ -*-
-// Testing performance utilities for the C++ library testsuite.
-//
-// Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#ifndef _GLIBCXX_PERFORMANCE_H
-#define _GLIBCXX_PERFORMANCE_H
-
-#include <sys/times.h>
-#include <sys/resource.h>
-#include <cstdlib>
-#include <string>
-#include <fstream>
-#include <iomanip>
-
-#ifdef __linux__
-#include <malloc.h>
-#elif defined (__FreeBSD__)
-extern "C"
-{
- struct mallinfo
- {
- int uordblks;
- int hblkhd;
- };
-
- struct mallinfo
- mallinfo(void)
- {
- struct mallinfo m = { (((size_t) sbrk (0) + 1023) / 1024), 0 };
- return m;
- }
-}
-#elif !defined (__hpux__)
-extern "C"
-{
- struct mallinfo
- {
- int uordblks;
- int hblkhd;
- };
-
- struct mallinfo empty = { 0, 0 };
-
- struct mallinfo
- mallinfo(void)
- { return empty; }
-}
-#endif
-
-namespace __gnu_test
-{
- class time_counter
- {
- private:
- clock_t elapsed_begin;
- clock_t elapsed_end;
- tms tms_begin;
- tms tms_end;
-
- public:
- explicit
- time_counter() : elapsed_begin(), elapsed_end(), tms_begin(), tms_end()
- { }
-
- void
- clear() throw()
- {
- elapsed_begin = clock_t();
- elapsed_end = clock_t();
- tms_begin = tms();
- tms_end = tms();
- }
-
- void
- start()
- {
- this->clear();
- elapsed_begin = times(&tms_begin);
- const clock_t err = clock_t(-1);
- if (elapsed_begin == err)
- std::__throw_runtime_error("time_counter::start");
- }
-
- void
- stop()
- {
- elapsed_end = times(&tms_end);
- const clock_t err = clock_t(-1);
- if (elapsed_end == err)
- std::__throw_runtime_error("time_counter::stop");
- }
-
- size_t
- real_time() const
- { return elapsed_end - elapsed_begin; }
-
- size_t
- user_time() const
- { return tms_end.tms_utime - tms_begin.tms_utime; }
-
- size_t
- system_time() const
- { return tms_end.tms_stime - tms_begin.tms_stime; }
- };
-
- class resource_counter
- {
- int who;
- rusage rusage_begin;
- rusage rusage_end;
- struct mallinfo allocation_begin;
- struct mallinfo allocation_end;
-
- public:
- resource_counter(int i = RUSAGE_SELF) : who(i)
- { this->clear(); }
-
- void
- clear() throw()
- {
- memset(&rusage_begin, 0, sizeof(rusage_begin));
- memset(&rusage_end, 0, sizeof(rusage_end));
- memset(&allocation_begin, 0, sizeof(allocation_begin));
- memset(&allocation_end, 0, sizeof(allocation_end));
- }
-
- void
- start()
- {
- if (getrusage(who, &rusage_begin) != 0 )
- memset(&rusage_begin, 0, sizeof(rusage_begin));
- malloc(0); // Needed for some implementations.
- allocation_begin = mallinfo();
- }
-
- void
- stop()
- {
- if (getrusage(who, &rusage_end) != 0 )
- memset(&rusage_end, 0, sizeof(rusage_end));
- allocation_end = mallinfo();
- }
-
- int
- allocated_memory() const
- { return ((allocation_end.uordblks - allocation_begin.uordblks)
- + (allocation_end.hblkhd - allocation_begin.hblkhd)); }
-
- long
- hard_page_fault() const
- { return rusage_end.ru_majflt - rusage_begin.ru_majflt; }
-
- long
- swapped() const
- { return rusage_end.ru_nswap - rusage_begin.ru_nswap; }
- };
-
- inline void
- start_counters(time_counter& t, resource_counter& r)
- {
- t.start();
- r.start();
- }
-
- inline void
- stop_counters(time_counter& t, resource_counter& r)
- {
- t.stop();
- r.stop();
- }
-
- inline void
- clear_counters(time_counter& t, resource_counter& r)
- {
- t.clear();
- r.clear();
- }
-
- void
- report_performance(const std::string file, const std::string comment,
- const time_counter& t, const resource_counter& r)
- {
- const char space = ' ';
- const char tab = '\t';
- const char* name = "libstdc++-performance.sum";
- std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1;
- std::string testname(i, file.end());
-
- std::ofstream out(name, std::ios_base::app);
-
-#ifdef __GTHREADS
- if (__gthread_active_p())
- testname.append("-thread");
-#endif
-
- out.setf(std::ios_base::left);
- out << std::setw(25) << testname << tab;
- out << std::setw(25) << comment << tab;
-
- out.setf(std::ios_base::right);
- out << std::setw(4) << t.real_time() << "r" << space;
- out << std::setw(4) << t.user_time() << "u" << space;
- out << std::setw(4) << t.system_time() << "s" << space;
- out << std::setw(8) << r.allocated_memory() << "mem" << space;
- out << std::setw(4) << r.hard_page_fault() << "pf" << space;
-
- out << std::endl;
- out.close();
- }
-
- void
- report_header(const std::string file, const std::string header)
- {
- const char space = ' ';
- const char tab = '\t';
- const char* name = "libstdc++-performance.sum";
- std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1;
- std::string testname(i, file.end());
-
- std::ofstream out(name, std::ios_base::app);
-
-#ifdef __GTHREADS
- if (__gthread_active_p ())
- testname.append("-thread");
-#endif
-
- out.setf(std::ios_base::left);
- out << std::setw(25) << testname << tab;
- out << std::setw(40) << header << tab;
-
- out << std::endl;
- out.close();
- }
-}; // namespace __gnu_test
-
-#endif // _GLIBCXX_PERFORMANCE_H
-
+++ /dev/null
-// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-#include <string>
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include <ext/mt_allocator.h>
-
-// libstdc++/22309
-extern "C" void
-try_allocation()
-{
- typedef char value_t;
-
- typedef __gnu_cxx::__mt_alloc<value_t> allocator_t;
-
- typedef std::char_traits<value_t> traits_t;
- typedef std::basic_string<value_t, traits_t, allocator_t> string_t;
-
- string_t s;
- s += "west beach, indiana dunes";
-}
-
-// libstdc++/23591
-extern "C" void
-try_throw_exception()
-{
- try
- {
- throw std::bad_exception();
- }
- catch (const std::exception& e)
- { }
-}
-
-extern "C" void
-try_function_random_fail()
-{
- long seed = lrand48();
- if (seed < 2000)
- seed = 2000;
-
- {
- std::ostringstream s;
- s << "random_throw, seed: " << seed << std::endl;
- std::cout << s.str();
- }
-
- while (--seed > 0)
- {
- try_throw_exception();
- }
-
- // Randomly throw. See if other threads cleanup.
- throw std::bad_exception();
-}
+++ /dev/null
-// -*- C++ -*-
-// Testing utilities for the tr1 testsuite.
-//
-// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-//
-// This library 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.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-//
-// 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.
-
-#ifndef _GLIBCXX_TESTSUITE_TR1_H
-#define _GLIBCXX_TESTSUITE_TR1_H
-
-#include <bits/cpp_type_traits.h>
-
-namespace __gnu_test
-{
- // For tr1/type_traits.
- template<template<typename> class Category,
- typename Type>
- bool
- test_category(bool value)
- {
- bool ret = true;
- ret &= Category<Type>::value == value;
- ret &= Category<const Type>::value == value;
- ret &= Category<volatile Type>::value == value;
- ret &= Category<const volatile Type>::value == value;
- ret &= Category<Type>::type::value == value;
- ret &= Category<const Type>::type::value == value;
- ret &= Category<volatile Type>::type::value == value;
- ret &= Category<const volatile Type>::type::value == value;
- return ret;
- }
-
- template<template<typename> class Property,
- typename Type>
- bool
- test_property(typename Property<Type>::value_type value)
- {
- bool ret = true;
- ret &= Property<Type>::value == value;
- ret &= Property<Type>::type::value == value;
- return ret;
- }
-
- // For testing tr1/type_traits/extent, which has a second template
- // parameter.
- template<template<typename, unsigned> class Property,
- typename Type,
- unsigned Uint>
- bool
- test_property(typename Property<Type, Uint>::value_type value)
- {
- bool ret = true;
- ret &= Property<Type, Uint>::value == value;
- ret &= Property<Type, Uint>::type::value == value;
- return ret;
- }
-
- template<template<typename, typename> class Relationship,
- typename Type1, typename Type2>
- bool
- test_relationship(bool value)
- {
- bool ret = true;
- ret &= Relationship<Type1, Type2>::value == value;
- ret &= Relationship<Type1, Type2>::type::value == value;
- return ret;
- }
-
- // Test types.
- class ClassType { };
- typedef const ClassType cClassType;
- typedef volatile ClassType vClassType;
- typedef const volatile ClassType cvClassType;
-
- class DerivedType : public ClassType { };
-
- enum EnumType { };
-
- struct ConvType
- { operator int() const; };
-
- class AbstractClass
- {
- virtual void rotate(int) = 0;
- virtual ~AbstractClass();
- };
-
- class PolymorphicClass
- {
- virtual void rotate(int);
- virtual ~PolymorphicClass();
- };
-
- class DerivedPolymorphic : public PolymorphicClass { };
-
- union UnionType { };
-
- class IncompleteClass;
-
- int truncate_float(float x) { return (int)x; }
- long truncate_double(double x) { return (long)x; }
-
- struct do_truncate_float_t
- {
- do_truncate_float_t()
- {
- ++live_objects;
- }
-
- do_truncate_float_t(const do_truncate_float_t&)
- {
- ++live_objects;
- }
-
- ~do_truncate_float_t()
- {
- --live_objects;
- }
-
- int operator()(float x) { return (int)x; }
-
- static int live_objects;
- };
-
- int do_truncate_float_t::live_objects = 0;
-
- struct do_truncate_double_t
- {
- do_truncate_double_t()
- {
- ++live_objects;
- }
-
- do_truncate_double_t(const do_truncate_double_t&)
- {
- ++live_objects;
- }
-
- ~do_truncate_double_t()
- {
- --live_objects;
- }
-
- long operator()(double x) { return (long)x; }
-
- static int live_objects;
- };
-
- int do_truncate_double_t::live_objects = 0;
-
- struct X
- {
- int bar;
-
- int foo() { return 1; }
- int foo_c() const { return 2; }
- int foo_v() volatile { return 3; }
- int foo_cv() const volatile { return 4; }
- };
-
- // For use in 8_c_compatibility.
- template<typename R, typename T>
- typename std::__enable_if<bool, std::__are_same<R, T>::__value>::__type
- check_ret_type(T)
- { return true; }
-
-} // namespace __gnu_test
-
-#endif // _GLIBCXX_TESTSUITE_TR1_H
+++ /dev/null
-// Copyright (C) 2005 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
-// any later version.
-
-// This library 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.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-// 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.
-
-#include <typeinfo>
-#include <stdexcept>
-#include <sstream>
-#include <fstream>
-#include <cxxabi.h>
-#include <testsuite_performance.h>
-
-// Ah, we wish it wasn't so...
-bool first_container = false;
-extern const char* filename;
-
-typedef std::string::size_type (*callback_type) (std::string&);
-
-template<typename Container, int Iter, bool Thread>
- void
- write_viz_container(callback_type find_container, const char* filename)
- {
- typedef std::string string;
-
- // Create title.
- {
- const char ws(' ');
- std::ostringstream title;
-
- std::string titlename(filename);
- std::string::size_type n = titlename.find('.');
- if (n != string::npos)
- titlename = std::string(titlename.begin(), titlename.begin() + n);
-
- title << titlename;
- title << ws;
- title << Iter;
- title << ws;
-#if 0
- title << "thread<";
- std::boolalpha(title);
- title << Thread;
- title << '>';
-#endif
-
- titlename += ".title";
- std::ofstream titlefile(titlename.c_str());
- if (!titlefile.good())
- throw std::runtime_error("write_viz_data cannot open titlename");
- titlefile << title.str() << std::endl;
- }
-
- // Create compressed type name.
- Container obj;
- int status;
- std::string type(abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status));
-
- // Extract fully-qualified typename.
- // Assumes "set" or "map" are uniquely determinate.
- string::iterator beg = type.begin();
- string::iterator end;
- string::size_type n = (*find_container)(type);
-
- // Find start of fully-qualified name.
- // Assume map, find end.
- string::size_type nend = type.find('<', n);
- if (nend != string::npos)
- end = type.begin() + nend;
-
- string compressed_type;
- compressed_type += '"';
- compressed_type += string(beg, end);
- compressed_type += '<';
-#if 0
- typename Container::key_type v;
- compressed_type += typeid(v).name();
-#else
- compressed_type += "int";
-#endif
- compressed_type += ", A>";
-
- // XXX
- if (Thread == true)
- compressed_type += " thread";
- compressed_type += '"';
-
- std::ofstream file(filename, std::ios_base::app);
- if (!file.good())
- throw std::runtime_error("write_viz_data cannot open filename");
-
- file << compressed_type;
- first_container = false;
- }
-
-
-void
-write_viz_data(__gnu_test::time_counter& time, const char* filename)
-{
- std::ofstream file(filename, std::ios_base::app);
- if (!file.good())
- throw std::runtime_error("write_viz_data cannot open filename");
-
- // Print out score in appropriate column.
- const char tab('\t');
- int score = time.real_time();
- file << tab << score;
-}
-
-void
-write_viz_endl(const char* filename)
-{
- std::ofstream file(filename, std::ios_base::app);
- if (!file.good())
- throw std::runtime_error("write_viz_endl cannot open filename");
- file << std::endl;
-}
-
-
-#if 0
-// cons
-write_viz_container<container_type, Iter, Thread>(&sequence_find_container,
- filename);
-#endif
-
-#if 0
-// dtor
-write_viz_endl(filename)
-#endif
--- /dev/null
+// -*- C++ -*-
+
+// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+
+// This library 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, or (at
+// your option) any later version.
+
+// This library 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// 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.
+
+// Benjamin Kosnik <bkoz@redhat.com>
+
+#include "testsuite_abi.h"
+#include <sstream>
+#include <fstream>
+#include <iostream>
+
+using namespace std;
+
+void
+symbol::init(string& data)
+{
+ const char delim = ':';
+ const char version_delim = '@';
+ const string::size_type npos = string::npos;
+ string::size_type n = 0;
+
+ // Set the type.
+ if (data.find("FUNC") == 0)
+ type = symbol::function;
+ else if (data.find("OBJECT") == 0)
+ type = symbol::object;
+
+ n = data.find_first_of(delim);
+ if (n != npos)
+ data.erase(data.begin(), data.begin() + n + 1);
+
+ // Iff object, get size info.
+ if (type == symbol::object)
+ {
+ n = data.find_first_of(delim);
+ if (n != npos)
+ {
+ string size(data.begin(), data.begin() + n);
+ istringstream iss(size);
+ int x;
+ iss >> x;
+ if (!iss.fail())
+ size = x;
+ data.erase(data.begin(), data.begin() + n + 1);
+ }
+ }
+
+ // Set the name and raw_name.
+ raw_name = string(data.begin(), data.end());
+ n = data.find_first_of(version_delim);
+ if (n != npos)
+ {
+ // Found version string.
+ name = string(data.begin(), data.begin() + n);
+ n = data.find_last_of(version_delim);
+ data.erase(data.begin(), data.begin() + n + 1);
+
+ // Set version name.
+ version_name = data;
+ }
+ else
+ {
+ // No versioning info.
+ name = string(data.begin(), data.end());
+ version_status = symbol::none;
+ }
+
+ // Set the demangled name.
+ demangled_name = demangle(name);
+}
+
+void
+symbol::print() const
+{
+ const char tab = '\t';
+ cout << name << endl;
+
+ if (demangled_name != name)
+ cout << demangled_name << endl;
+
+ string vers;
+ switch (version_status)
+ {
+ case none:
+ vers = "none";
+ break;
+ case compatible:
+ vers = "compatible";
+ break;
+ case incompatible:
+ vers = "incompatible";
+ break;
+ case unversioned:
+ vers = "unversioned";
+ break;
+ default:
+ vers = "<default>";
+ }
+ cout << "version status: " << vers << endl;
+
+ if (version_name.size()
+ && (version_status == compatible || version_status == incompatible))
+ cout << version_name << endl;
+
+ string type_string;
+ switch (type)
+ {
+ case function:
+ type_string = "function";
+ break;
+ case object:
+ type_string = "object";
+ break;
+ case uncategorized:
+ type_string = "uncategorized";
+ break;
+ default:
+ type_string = "<default>";
+ }
+ cout << "type: " << type_string << endl;
+
+ if (type == object)
+ cout << "type size: " << size << endl;
+
+ string status_string;
+ switch (status)
+ {
+ case added:
+ status_string = "added";
+ break;
+ case subtracted:
+ status_string = "subtracted";
+ break;
+ case undesignated:
+ status_string = "undesignated";
+ break;
+ default:
+ status_string = "<default>";
+ }
+ cout << "status: " << status_string << endl;
+
+ cout << endl;
+}
+
+
+bool
+check_version(symbol& test, bool added)
+{
+ // Construct list of compatible versions.
+ typedef std::vector<std::string> compat_list;
+ static compat_list known_versions;
+ if (known_versions.empty())
+ {
+ // NB: First version here must be the default version for this
+ // version of DT_SONAME.
+ known_versions.push_back("GLIBCXX_3.4");
+ known_versions.push_back("GLIBCXX_3.4.1");
+ known_versions.push_back("GLIBCXX_3.4.2");
+ known_versions.push_back("GLIBCXX_3.4.3");
+ known_versions.push_back("GLIBCXX_3.4.4");
+ known_versions.push_back("GLIBCXX_3.4.5");
+ known_versions.push_back("GLIBCXX_3.4.6");
+ known_versions.push_back("GLIBCXX_3.4.7");
+ known_versions.push_back("GLIBCXX_3.4.8");
+ known_versions.push_back("GLIBCXX_3.4.9");
+ known_versions.push_back("GLIBCXX_LDBL_3.4");
+ known_versions.push_back("GLIBCXX_LDBL_3.4.7");
+ known_versions.push_back("CXXABI_1.3");
+ known_versions.push_back("CXXABI_1.3.1");
+ known_versions.push_back("CXXABI_LDBL_1.3");
+ }
+ compat_list::iterator begin = known_versions.begin();
+ compat_list::iterator end = known_versions.end();
+
+ // Check for compatible version.
+ if (test.version_name.size())
+ {
+ compat_list::iterator it1 = find(begin, end, test.version_name);
+ compat_list::iterator it2 = find(begin, end, test.name);
+ if (it1 != end)
+ test.version_status = symbol::compatible;
+ else
+ test.version_status = symbol::incompatible;
+
+ // Check that added symbols aren't added in the base version.
+ if (added && test.version_name == known_versions[0])
+ test.version_status = symbol::incompatible;
+
+ // Check for weak label.
+ if (it1 == end && it2 == end)
+ test.version_status = symbol::incompatible;
+
+ // Check that
+ // GLIBCXX_3.4
+ // GLIBCXX_3.4.5
+ // version as compatible
+ // XXX
+ }
+ else
+ {
+ if (added)
+ {
+ // New version labels are ok. The rest are not.
+ compat_list::iterator it2 = find(begin, end, test.name);
+ if (it2 != end)
+ test.version_status = symbol::compatible;
+ else
+ test.version_status = symbol::incompatible;
+ }
+ }
+ return test.version_status == symbol::compatible;
+}
+
+bool
+check_compatible(symbol& lhs, symbol& rhs, bool verbose)
+{
+ bool ret = true;
+ const char tab = '\t';
+
+ // Check to see if symbol_objects are compatible.
+ if (lhs.type != rhs.type)
+ {
+ ret = false;
+ if (verbose)
+ cout << tab << "incompatible types" << endl;
+ }
+
+ if (lhs.name != rhs.name)
+ {
+ ret = false;
+ if (verbose)
+ cout << tab << "incompatible names" << endl;
+ }
+
+ if (lhs.size != rhs.size)
+ {
+ ret = false;
+ if (verbose)
+ {
+ cout << tab << "incompatible sizes" << endl;
+ cout << tab << lhs.size << endl;
+ cout << tab << rhs.size << endl;
+ }
+ }
+
+ if (lhs.version_name != rhs.version_name
+ && !check_version(lhs) && !check_version(rhs))
+ {
+ ret = false;
+ if (verbose)
+ {
+ cout << tab << "incompatible versions" << endl;
+ cout << tab << lhs.version_name << endl;
+ cout << tab << rhs.version_name << endl;
+ }
+ }
+
+ if (verbose)
+ cout << endl;
+
+ return ret;
+}
+
+
+bool
+has_symbol(const string& mangled, const symbols& s) throw()
+{
+ const symbol_names& names = s.first;
+ symbol_names::const_iterator i = find(names.begin(), names.end(), mangled);
+ return i != names.end();
+}
+
+symbol&
+get_symbol(const string& mangled, const symbols& s)
+{
+ const symbol_names& names = s.first;
+ symbol_names::const_iterator i = find(names.begin(), names.end(), mangled);
+ if (i != names.end())
+ {
+ symbol_objects objects = s.second;
+ return objects[mangled];
+ }
+ else
+ {
+ ostringstream os;
+ os << "get_symbol failed for symbol " << mangled;
+ __throw_logic_error(os.str().c_str());
+ }
+}
+
+void
+examine_symbol(const char* name, const char* file)
+{
+ try
+ {
+ symbols s = create_symbols(file);
+ symbol& sym = get_symbol(name, s);
+ sym.print();
+ }
+ catch(...)
+ { __throw_exception_again; }
+}
+
+int
+compare_symbols(const char* baseline_file, const char* test_file,
+ bool verbose)
+{
+ // Input both lists of symbols into container.
+ symbols baseline = create_symbols(baseline_file);
+ symbols test = create_symbols(test_file);
+ symbol_names& baseline_names = baseline.first;
+ symbol_objects& baseline_objects = baseline.second;
+ symbol_names& test_names = test.first;
+ symbol_objects& test_objects = test.second;
+
+ // Sanity check results.
+ const symbol_names::size_type baseline_size = baseline_names.size();
+ const symbol_names::size_type test_size = test_names.size();
+ if (!baseline_size || !test_size)
+ {
+ cerr << "Problems parsing the list of exported symbols." << endl;
+ exit(2);
+ }
+
+ // Sort out names.
+ // Assuming baseline_names, test_names are both unique w/ no duplicates.
+ //
+ // The names added to missing_names are baseline_names not found in
+ // test_names
+ // -> symbols that have been deleted.
+ //
+ // The names added to added_names are test_names not in
+ // baseline_names
+ // -> symbols that have been added.
+ symbol_names shared_names;
+ symbol_names missing_names;
+ symbol_names added_names = test_names;
+ for (size_t i = 0; i < baseline_size; ++i)
+ {
+ string what(baseline_names[i]);
+ symbol_names::iterator end = added_names.end();
+ symbol_names::iterator it = find(added_names.begin(), end, what);
+ if (it != end)
+ {
+ // Found.
+ shared_names.push_back(what);
+ added_names.erase(it);
+ }
+ else
+ missing_names.push_back(what);
+ }
+
+ // Check missing names for compatibility.
+ typedef pair<symbol, symbol> symbol_pair;
+ vector<symbol_pair> incompatible;
+ const symbol_names::size_type missing_size = missing_names.size();
+ for (size_t j = 0; j < missing_size; ++j)
+ {
+ symbol& base = baseline_objects[missing_names[j]];
+ base.status = symbol::subtracted;
+ incompatible.push_back(symbol_pair(base, base));
+ }
+
+ // Check shared names for compatibility.
+ const symbol_names::size_type shared_size = shared_names.size();
+ for (size_t k = 0; k < shared_size; ++k)
+ {
+ symbol& base = baseline_objects[shared_names[k]];
+ symbol& test = test_objects[shared_names[k]];
+ test.status = symbol::existing;
+ if (!check_compatible(base, test))
+ incompatible.push_back(symbol_pair(base, test));
+ }
+
+ // Check added names for compatibility.
+ const symbol_names::size_type added_size = added_names.size();
+ for (size_t l = 0; l < added_size; ++l)
+ {
+ symbol& test = test_objects[added_names[l]];
+ test.status = symbol::added;
+ if (!check_version(test, true))
+ incompatible.push_back(symbol_pair(test, test));
+ }
+
+ // Report results.
+ if (verbose && added_names.size())
+ {
+ cout << endl << added_names.size() << " added symbols " << endl;
+ for (size_t j = 0; j < added_names.size() ; ++j)
+ {
+ cout << j << endl;
+ test_objects[added_names[j]].print();
+ }
+ }
+
+ if (verbose && missing_names.size())
+ {
+ cout << endl << missing_names.size() << " missing symbols " << endl;
+ for (size_t j = 0; j < missing_names.size() ; ++j)
+ {
+ cout << j << endl;
+ baseline_objects[missing_names[j]].print();
+ }
+ }
+
+ if (verbose && incompatible.size())
+ {
+ cout << endl << incompatible.size() << " incompatible symbols " << endl;
+ for (size_t j = 0; j < incompatible.size() ; ++j)
+ {
+ // First, print index.
+ cout << j << endl;
+
+ // Second, report name.
+ symbol& base = incompatible[j].first;
+ symbol& test = incompatible[j].second;
+ test.print();
+
+ // Second, report reason or reasons incompatible.
+ check_compatible(base, test, true);
+ }
+ }
+
+ cout << "\n\t\t=== libstdc++-v3 check-abi Summary ===" << endl;
+ cout << endl;
+ cout << "# of added symbols:\t\t " << added_names.size() << endl;
+ cout << "# of missing symbols:\t\t " << missing_names.size() << endl;
+ cout << "# of incompatible symbols:\t " << incompatible.size() << endl;
+ cout << endl;
+ cout << "using: " << baseline_file << endl;
+
+ return !(missing_names.size() || incompatible.size());
+}
+
+
+symbols
+create_symbols(const char* file)
+{
+ symbols s;
+ ifstream ifs(file);
+ if (ifs.is_open())
+ {
+ // Organize file data into container of symbol objects, and a
+ // container of mangled names without versioning information.
+ symbol_names& names = s.first;
+ symbol_objects& objects = s.second;
+ const string empty;
+ string line = empty;
+ while (getline(ifs, line).good())
+ {
+ symbol tmp;
+ tmp.init(line);
+ objects[tmp.name] = tmp;
+ names.push_back(tmp.name);
+ line = empty;
+ }
+ }
+ else
+ {
+ ostringstream os;
+ os << "create_symbols failed for file " << file;
+ __throw_runtime_error(os.str().c_str());
+ }
+ return s;
+}
+
+
+const char*
+demangle(const std::string& mangled)
+{
+ const char* name;
+ if (mangled[0] != '_' || mangled[1] != 'Z')
+ {
+ // This is not a mangled symbol, thus has "C" linkage.
+ name = mangled.c_str();
+ }
+ else
+ {
+ // Use __cxa_demangle to demangle.
+ int status = 0;
+ name = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
+ if (!name)
+ {
+ switch (status)
+ {
+ case 0:
+ name = "error code = 0: success";
+ break;
+ case -1:
+ name = "error code = -1: memory allocation failure";
+ break;
+ case -2:
+ name = "error code = -2: invalid mangled name";
+ break;
+ case -3:
+ name = "error code = -3: invalid arguments";
+ break;
+ default:
+ name = "error code unknown - who knows what happened";
+ }
+ }
+ }
+ return name;
+}
+
--- /dev/null
+// -*- C++ -*-
+
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+// This library 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, or (at
+// your option) any later version.
+
+// This library 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// 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.
+
+// Benjamin Kosnik <bkoz@redhat.com>
+
+#include <string>
+#include <stdexcept>
+#include <deque>
+#include <ext/hash_map>
+#include <cxxabi.h>
+
+// Encapsulates symbol characteristics.
+struct symbol
+{
+ enum category { function, object, uncategorized };
+ enum designation { existing, added, subtracted, undesignated };
+ enum version { none, compatible, incompatible, unversioned };
+ enum compatibility
+ {
+ compat_type = 1,
+ compat_name = 2,
+ compat_size = 4,
+ compat_version = 8
+ };
+
+ category type;
+ std::string name;
+ std::string raw_name; // Name with versioning info still attached.
+ std::string demangled_name;
+ int size;
+ std::string version_name;
+ version version_status;
+ designation status;
+
+ symbol()
+ : type(uncategorized), size(0), version_status(unversioned),
+ status(undesignated) { }
+
+ symbol(const symbol& other)
+ : type(other.type), name(other.name), demangled_name(other.demangled_name),
+ size(other.size), version_name(other.version_name),
+ version_status(other.version_status), status(other.status) { }
+
+ void
+ print() const;
+
+ void
+ init(std::string& data);
+};
+
+typedef __gnu_cxx::hash_map<std::string, symbol> symbol_objects;
+
+typedef std::deque<std::string> symbol_names;
+
+typedef std::pair<symbol_names, symbol_objects> symbols;
+
+
+// Check.
+bool
+check_version(symbol& test, bool added = false);
+
+bool
+check_compatible(symbol& lhs, symbol& rhs, bool verbose = false);
+
+
+// Examine.
+bool
+has_symbol(const std::string& mangled, const symbols& list) throw();
+
+symbol&
+get_symbol(const std::string& mangled, const symbols& list);
+
+extern "C" void
+examine_symbol(const char* name, const char* file);
+
+extern "C" int
+compare_symbols(const char* baseline_file, const char* test_file, bool verb);
+
+
+// Util.
+symbols
+create_symbols(const char* file);
+
+const char*
+demangle(const std::string& mangled);
+
+
+// Specialization.
+namespace __gnu_cxx
+{
+ using namespace std;
+
+ template<>
+ struct hash<string>
+ {
+ size_t operator()(const string& s) const
+ {
+ const collate<char>& c = use_facet<collate<char> >(locale::classic());
+ return c.hash(s.c_str(), s.c_str() + s.size());
+ }
+ };
+}
--- /dev/null
+// -*- C++ -*-
+
+// Copyright (C) 2004 Free Software Foundation, Inc.
+
+// This library 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, or (at
+// your option) any later version.
+
+// This library 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.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// 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.
+
+// Benjamin Kosnik <bkoz@redhat.com>
+// Blame subsequent hacks on Loren J. Rittle <ljrittle@acm.org>, Phil
+// Edwards <pme@gcc.gnu.org>, and a cast of dozens at libstdc++@gcc.gnu.org.
+
+#include "testsuite_abi.h"
+#include <iostream>
+#include <unistd.h> // for access(2)
+
+int
+main(int argc, char** argv)
+{
+ using namespace std;
+
+ // Get arguments. (Heading towards getopt_long, I can feel it.)
+ string argv1 = argc > 1 ? argv[1] : "";
+ if (argv1 == "--help" || argc < 4)
+ {
+ cerr << "usage: abi_check --check current baseline\n"
+ " --check-verbose current baseline\n"
+ " --examine symbol current\n"
+ " --help\n"
+ "\n"
+ "All arguments are string literals.\n"
+ "CURRENT is a file generated byextract_symvers.\n"
+ "BASELINE is a file from config/abi.\n"
+ "SYMBOL is a mangled name.\n"
+ << endl;
+ exit(1);
+ }
+
+ if (argv1.find("--check") != string::npos)
+ {
+ bool verbose = false;
+ if (argv1 == "--check-verbose")
+ verbose = true;
+
+ // Quick sanity/setup check for arguments.
+ const char* test_file = argv[2];
+ const char* baseline_file = argv[3];
+ if (access(test_file, R_OK) != 0)
+ {
+ cerr << "Cannot read symbols file " << test_file
+ << ", did you forget to build first?" << endl;
+ exit(1);
+ }
+ if (access(baseline_file, R_OK) != 0)
+ {
+ cerr << "Cannot read baseline file " << baseline_file << endl;
+ exit(1);
+ }
+ if (!compare_symbols(baseline_file, test_file, verbose))
+ exit (1);
+ }
+
+ if (argv1 == "--examine")
+ {
+ const char* file = argv[3];
+ if (access(file, R_OK) != 0)
+ {
+ cerr << "Cannot read symbol file " << file << endl;
+ exit(1);
+ }
+ examine_symbol(argv[2], file);
+ }
+ return 0;
+}
--- /dev/null
+// -*- C++ -*-
+// Testing allocator for the C++ library testsuite.
+//
+// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#include <iostream>
+#include <testsuite_allocator.h>
+
+namespace __gnu_test
+{
+ allocation_tracker::size_type allocation_tracker::allocationTotal_ = 0;
+ allocation_tracker::size_type allocation_tracker::deallocationTotal_ = 0;
+ int allocation_tracker::constructCount_ = 0;
+ int allocation_tracker::destructCount_ = 0;
+
+ bool
+ check_construct_destroy(const char* tag, int expected_c, int expected_d)
+ {
+ if (allocation_tracker::constructCount() == expected_c &&
+ allocation_tracker::destructCount() == expected_d)
+ return true;
+
+ else {
+ std::cerr << tag << ": "
+ << " construct = " << allocation_tracker::constructCount()
+ << " (should be " << expected_c << "),"
+ << " destroy = " << allocation_tracker::destructCount()
+ << " (should be " << expected_d << ")"
+ << std::endl;
+ return false;
+ }
+ }
+
+}; // namespace __cxx_test
+
--- /dev/null
+// -*- C++ -*-
+// Testing allocator for the C++ library testsuite.
+//
+// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+// This file provides an test instrumentation allocator that can be
+// used to verify allocation functionality of standard library
+// containers. 2002.11.25 smw
+
+#ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H
+#define _GLIBCXX_TESTSUITE_ALLOCATOR_H
+
+#include <cstddef>
+#include <limits>
+#include <tr1/unordered_map>
+#include <cassert>
+
+namespace
+{
+ bool new_called = false;
+ bool delete_called = false;
+};
+
+namespace __gnu_test
+{
+ class allocation_tracker
+ {
+ public:
+ typedef std::size_t size_type;
+
+ static void*
+ allocate(size_type blocksize)
+ {
+ allocationTotal_ += blocksize;
+ return ::operator new(blocksize);
+ }
+
+ static void
+ construct() { constructCount_++; }
+
+ static void
+ destroy() { destructCount_++; }
+
+ static void
+ deallocate(void* p, size_type blocksize)
+ {
+ ::operator delete(p);
+ deallocationTotal_ += blocksize;
+ }
+
+ static size_type
+ allocationTotal() { return allocationTotal_; }
+
+ static size_type
+ deallocationTotal() { return deallocationTotal_; }
+
+ static int
+ constructCount() { return constructCount_; }
+
+ static int
+ destructCount() { return destructCount_; }
+
+ static void
+ resetCounts()
+ {
+ allocationTotal_ = 0;
+ deallocationTotal_ = 0;
+ constructCount_ = 0;
+ destructCount_ = 0;
+ }
+
+ private:
+ static size_type allocationTotal_;
+ static size_type deallocationTotal_;
+ static int constructCount_;
+ static int destructCount_;
+ };
+
+ // A simple basic allocator that just forwards to the
+ // allocation_tracker to fulfill memory requests. This class is
+ // templated on the target object type, but tracker isn't.
+ template<class T>
+ class tracker_alloc
+ {
+ public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ template<class U> struct rebind { typedef tracker_alloc<U> other; };
+
+ pointer
+ address(reference value) const
+ { return &value; }
+
+ const_pointer
+ address(const_reference value) const
+ { return &value; }
+
+ tracker_alloc() throw()
+ { }
+
+ tracker_alloc(const tracker_alloc&) throw()
+ { }
+
+ template<class U>
+ tracker_alloc(const tracker_alloc<U>&) throw()
+ { }
+
+ ~tracker_alloc() throw()
+ { }
+
+ size_type
+ max_size() const throw()
+ { return std::numeric_limits<std::size_t>::max() / sizeof(T); }
+
+ pointer
+ allocate(size_type n, const void* = 0)
+ {
+ return static_cast<pointer>(allocation_tracker::allocate(n * sizeof(T)));
+ }
+
+ void
+ construct(pointer p, const T& value)
+ {
+ new (p) T(value);
+ allocation_tracker::construct();
+ }
+
+ void
+ destroy(pointer p)
+ {
+ p->~T();
+ allocation_tracker::destroy();
+ }
+
+ void
+ deallocate(pointer p, size_type num)
+ { allocation_tracker::deallocate(p, num * sizeof(T)); }
+ };
+
+ template<class T1, class T2>
+ bool
+ operator==(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
+ { return true; }
+
+ template<class T1, class T2>
+ bool
+ operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
+ { return false; }
+
+ bool
+ check_construct_destroy(const char* tag, int expected_c, int expected_d);
+
+ template<typename Alloc, bool uses_global_new>
+ bool
+ check_new(Alloc a = Alloc())
+ {
+ bool test __attribute__((unused)) = true;
+ a.allocate(10);
+ test &= ( new_called == uses_global_new );
+ return test;
+ }
+
+ template<typename Alloc, bool uses_global_delete>
+ bool
+ check_delete(Alloc a = Alloc())
+ {
+ bool test __attribute__((unused)) = true;
+ typename Alloc::pointer p = a.allocate(10);
+ a.deallocate(p, 10);
+ test &= ( delete_called == uses_global_delete );
+ return test;
+ }
+
+ template<typename Alloc>
+ bool
+ check_deallocate_null()
+ {
+ // Let's not core here...
+ Alloc a;
+ a.deallocate(NULL, 1);
+ a.deallocate(NULL, 10);
+ return true;
+ }
+
+ template<typename Alloc>
+ bool
+ check_allocate_max_size()
+ {
+ Alloc a;
+ try
+ {
+ a.allocate(a.max_size() + 1);
+ }
+ catch(std::bad_alloc&)
+ {
+ return true;
+ }
+ catch(...)
+ {
+ throw;
+ }
+ throw;
+ }
+
+
+ // A simple allocator which can be constructed endowed of a given
+ // "personality" (an integer), queried in operator== to simulate the
+ // behavior of realworld "unequal" allocators (i.e., not exploiting
+ // the provision in 20.1.5/4, first bullet). A global unordered_map,
+ // filled at allocation time with (pointer, personality) pairs, is
+ // then consulted to enforce the requirements in Table 32 about
+ // deallocation vs allocator equality. Note that this allocator is
+ // swappable, not assignable, consistently with Option 3 of DR 431
+ // (see N1599).
+ struct uneq_allocator_base
+ {
+ typedef std::tr1::unordered_map<void*, int> map_type;
+
+ // Avoid static initialization troubles and/or bad interactions
+ // with tests linking testsuite_allocator.o and playing globally
+ // with operator new/delete.
+ static map_type&
+ get_map()
+ {
+ static map_type alloc_map;
+ return alloc_map;
+ }
+ };
+
+ template<typename Tp>
+ class uneq_allocator
+ : private uneq_allocator_base
+ {
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef Tp* pointer;
+ typedef const Tp* const_pointer;
+ typedef Tp& reference;
+ typedef const Tp& const_reference;
+ typedef Tp value_type;
+
+ template<typename Tp1>
+ struct rebind
+ { typedef uneq_allocator<Tp1> other; };
+
+ uneq_allocator() throw()
+ : personality(0) { }
+
+ uneq_allocator(int person) throw()
+ : personality(person) { }
+
+ template<typename Tp1>
+ uneq_allocator(const uneq_allocator<Tp1>& b) throw()
+ : personality(b.get_personality()) { }
+
+ int get_personality() const { return personality; }
+
+ pointer
+ address(reference x) const { return &x; }
+
+ const_pointer
+ address(const_reference x) const { return &x; }
+
+ pointer
+ allocate(size_type n, const void* = 0)
+ {
+ if (__builtin_expect(n > this->max_size(), false))
+ std::__throw_bad_alloc();
+
+ pointer p = static_cast<Tp*>(::operator new(n * sizeof(Tp)));
+ try
+ {
+ get_map().insert(map_type::value_type(reinterpret_cast<void*>(p),
+ personality));
+ }
+ catch(...)
+ {
+ ::operator delete(p);
+ __throw_exception_again;
+ }
+ return p;
+ }
+
+ void
+ deallocate(pointer p, size_type)
+ {
+ assert( p );
+
+ map_type::iterator it = get_map().find(reinterpret_cast<void*>(p));
+ assert( it != get_map().end() );
+
+ // Enforce requirements in Table 32 about deallocation vs
+ // allocator equality.
+ assert( it->second == personality );
+
+ get_map().erase(it);
+ ::operator delete(p);
+ }
+
+ size_type
+ max_size() const throw()
+ { return size_t(-1) / sizeof(Tp); }
+
+ void
+ construct(pointer p, const Tp& val)
+ { ::new(p) Tp(val); }
+
+ void
+ destroy(pointer p) { p->~Tp(); }
+
+ private:
+ // Not assignable...
+ uneq_allocator&
+ operator=(const uneq_allocator&);
+
+ // ... yet swappable!
+ friend inline void
+ swap(uneq_allocator& a, uneq_allocator& b)
+ { std::swap(a.personality, b.personality); }
+
+ template<typename Tp1>
+ friend inline bool
+ operator==(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
+ { return a.personality == b.personality; }
+
+ template<typename Tp1>
+ friend inline bool
+ operator!=(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
+ { return !(a == b); }
+
+ int personality;
+ };
+
+
+ template<typename Tp>
+ class throw_allocator
+ {
+ public:
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef Tp* pointer;
+ typedef const Tp* const_pointer;
+ typedef Tp& reference;
+ typedef const Tp& const_reference;
+ typedef Tp value_type;
+
+ template<typename Tp1>
+ struct rebind
+ { typedef throw_allocator<Tp1> other; };
+
+ throw_allocator() throw()
+ : count(size_type(-1)) { }
+
+ throw_allocator(size_type c) throw()
+ : count(c) { }
+
+ template<typename Tp1>
+ throw_allocator(const throw_allocator<Tp1>& b) throw()
+ : count(b.get_count()) { }
+
+ size_type get_count() const { return count; }
+
+ pointer
+ address(reference x) const { return &x; }
+
+ const_pointer
+ address(const_reference x) const { return &x; }
+
+ pointer
+ allocate(size_type n, const void* = 0)
+ {
+ if (count == 0)
+ throw std::bad_alloc();
+
+ if (count != size_type(-1))
+ --count;
+
+ return static_cast<Tp*>(::operator new(n * sizeof(Tp)));
+ }
+
+ void
+ deallocate(pointer p, size_type)
+ { ::operator delete(p); }
+
+ size_type
+ max_size() const throw()
+ { return size_type(-1) / sizeof(Tp); }
+
+ void
+ construct(pointer p, const Tp& val)
+ { ::new(p) Tp(val); }
+
+ void
+ destroy(pointer p) { p->~Tp(); }
+
+ private:
+ template<typename Tp1>
+ friend inline bool
+ operator==(const throw_allocator&, const throw_allocator<Tp1>&)
+ { return true; }
+
+ template<typename Tp1>
+ friend inline bool
+ operator!=(const throw_allocator&, const throw_allocator<Tp1>&)
+ { return false; }
+
+ size_type count;
+ };
+}; // namespace __gnu_test
+
+#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
--- /dev/null
+// -*- C++ -*-
+
+// Utility subroutines for the C++ library testsuite.
+//
+// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#include <testsuite_character.h>
+
+namespace std
+{
+ locale::id
+ codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>::id;
+
+ locale::id
+ ctype<__gnu_test::pod_uchar>::id;
+
+ locale::id
+ numpunct<__gnu_test::pod_uint>::id;
+
+ locale::id
+ moneypunct<__gnu_test::pod_uint>::id;
+
+ // Member specializations for the existing facet classes.
+ // NB: This isn't especially portable. Perhaps a better way would be
+ // to just specialize all of numpunct and ctype.
+ using __gnu_test::pod_ushort;
+ typedef pod_ushort::value_type value_type;
+
+ template<>
+ bool
+ ctype<pod_ushort>::
+ do_is(mask, char_type) const { return true; }
+
+ template<>
+ const pod_ushort*
+ ctype<pod_ushort>::
+ do_is(const char_type* __lo, const char_type*, mask*) const
+ { return __lo; }
+
+ template<>
+ const pod_ushort*
+ ctype<pod_ushort>::
+ do_scan_is(mask, const char_type* __lo, const char_type*) const
+ { return __lo; }
+
+ template<>
+ const pod_ushort*
+ ctype<pod_ushort>::
+ do_scan_not(mask, const char_type* __lo, const char_type*) const
+ { return __lo; }
+
+ template<>
+ pod_ushort
+ ctype<pod_ushort>::
+ do_toupper(char_type __c) const
+ { return __c; }
+
+ template<>
+ const pod_ushort*
+ ctype<pod_ushort>::
+ do_toupper(char_type*, const char_type* __hi) const
+ { return __hi; }
+
+ template<>
+ pod_ushort
+ ctype<pod_ushort>::
+ do_tolower(char_type __c) const
+ { return __c; }
+
+ template<>
+ const pod_ushort*
+ ctype<pod_ushort>::
+ do_tolower(char_type*, const char_type* __hi) const
+ { return __hi; }
+
+ template<>
+ pod_ushort
+ ctype<pod_ushort>::
+ do_widen(char __c) const
+ {
+ char_type ret = { value_type(__c) };
+ return ret;
+ }
+
+ template<>
+ const char*
+ ctype<pod_ushort>::
+ do_widen(const char* __lo, const char* __hi, char_type* __dest) const
+ {
+ while (__lo < __hi)
+ {
+ *__dest = this->do_widen(*__lo);
+ ++__lo;
+ ++__dest;
+ }
+ return __hi;
+ }
+
+ template<>
+ char
+ ctype<pod_ushort>::
+ do_narrow(char_type __wc, char) const
+ { return static_cast<char>(__wc.value); }
+
+ template<>
+ const pod_ushort*
+ ctype<pod_ushort>::
+ do_narrow(const pod_ushort* __lo, const pod_ushort* __hi,
+ char, char* __dest) const
+ {
+ while (__lo < __hi)
+ {
+ *__dest = this->do_narrow(*__lo, char());
+ ++__lo;
+ ++__dest;
+ }
+ return __hi;
+ }
+
+ template<>
+ ctype<pod_ushort>::~ctype() { }
+
+ template<>
+ void
+ numpunct<pod_ushort>::_M_initialize_numpunct(__c_locale)
+ {
+ if (!_M_data)
+ _M_data = new __numpunct_cache<pod_ushort>;
+
+ _M_data->_M_grouping = "";
+ _M_data->_M_use_grouping = false;
+
+ _M_data->_M_decimal_point.value = value_type('.');
+ _M_data->_M_thousands_sep.value = value_type(',');
+
+ for (size_t i = 0; i < __num_base::_S_oend; ++i)
+ {
+ value_type v = __num_base::_S_atoms_out[i];
+ _M_data->_M_atoms_out[i].value = v;
+ }
+ _M_data->_M_atoms_out[__num_base::_S_oend] = pod_ushort();
+
+ for (size_t j = 0; j < __num_base::_S_iend; ++j)
+ _M_data->_M_atoms_in[j].value = value_type(__num_base::_S_atoms_in[j]);
+ _M_data->_M_atoms_in[__num_base::_S_iend] = pod_ushort();
+
+ // "true"
+ pod_ushort* __truename = new pod_ushort[4 + 1];
+ __truename[0].value = value_type('t');
+ __truename[1].value = value_type('r');
+ __truename[2].value = value_type('u');
+ __truename[3].value = value_type('e');
+ __truename[4] = pod_ushort();
+ _M_data->_M_truename = __truename;
+
+ // "false"
+ pod_ushort* __falsename = new pod_ushort[5 + 1];
+ __falsename[0].value = value_type('f');
+ __falsename[1].value = value_type('a');
+ __falsename[2].value = value_type('l');
+ __falsename[3].value = value_type('s');
+ __falsename[4].value = value_type('e');
+ __falsename[5] = pod_ushort();
+ _M_data->_M_falsename = __falsename;
+ }
+
+ template<>
+ numpunct<pod_ushort>::~numpunct()
+ { delete _M_data; }
+} // namespace std
--- /dev/null
+// -*- C++ -*-
+
+// Testing character type and state type with char_traits and codecvt
+// specializations for the C++ library testsuite.
+//
+// Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#ifndef _GLIBCXX_TESTSUITE_CHARACTER_H
+#define _GLIBCXX_TESTSUITE_CHARACTER_H
+
+#include <climits>
+#include <string> // for char_traits
+#include <locale> // for codecvt
+#include <ext/pod_char_traits.h>
+
+namespace __gnu_test
+{
+ struct pod_int
+ {
+ int value;
+ };
+
+ inline bool
+ operator==(const pod_int& lhs, const pod_int& rhs)
+ { return lhs.value == rhs.value; }
+
+ inline bool
+ operator<(const pod_int& lhs, const pod_int& rhs)
+ { return lhs.value < rhs.value; }
+
+ struct pod_state
+ {
+ unsigned long value;
+ };
+
+ inline bool
+ operator==(const pod_state& lhs, const pod_state& rhs)
+ { return lhs.value == rhs.value; }
+
+ inline bool
+ operator<(const pod_state& lhs, const pod_state& rhs)
+ { return lhs.value < rhs.value; }
+
+ // Alternate character types.
+ using __gnu_cxx::character;
+ typedef character<unsigned char, pod_int, pod_state> pod_char;
+ typedef character<unsigned char, unsigned int, pod_state> pod_uchar;
+ typedef character<unsigned short, unsigned int> pod_ushort;
+ typedef character<unsigned int, unsigned long> pod_uint;
+}
+
+namespace __gnu_cxx
+{
+ // Specializations.
+ // pod_char
+ template<>
+ template<typename V2>
+ inline __gnu_test::pod_char::char_type
+ __gnu_test::pod_char::char_type::from(const V2& v)
+ {
+ char_type ret = { static_cast<value_type>(v.value) };
+ return ret;
+ }
+
+ template<>
+ template<typename V2>
+ inline V2
+ __gnu_test::pod_char::char_type::to(const char_type& c)
+ {
+ V2 ret = { c.value };
+ return ret;
+ }
+
+ template<>
+ template<typename V2>
+ inline __gnu_test::pod_uchar::char_type
+ __gnu_test::pod_uchar::char_type::from(const V2& v)
+ {
+ char_type ret;
+ ret.value = (v >> 5);
+ return ret;
+ }
+
+ template<>
+ template<typename V2>
+ inline V2
+ __gnu_test::pod_uchar::char_type::to(const char_type& c)
+ { return static_cast<V2>(c.value << 5); }
+}; // namespace __gnu_test
+
+namespace std
+{
+ // codecvt specialization
+ //
+ // The conversion performed by the specialization is not supposed to
+ // be useful, rather it has been designed to demonstrate the
+ // essential features of stateful conversions:
+ // * Number and value of bytes for each internal character depends on the
+ // state in addition to the character itself.
+ // * Unshift produces an unshift sequence and resets the state. On input
+ // the unshift sequence causes the state to be reset.
+ //
+ // The conversion for output is as follows:
+ // 1. Calculate the value tmp by xor-ing the state and the internal
+ // character
+ // 2. Split tmp into either two or three bytes depending on the value of
+ // state. Output those bytes.
+ // 3. tmp becomes the new value of state.
+ template<>
+ class codecvt<__gnu_test::pod_uchar, char, __gnu_test::pod_state>
+ : public __codecvt_abstract_base<__gnu_test::pod_uchar, char,
+ __gnu_test::pod_state>
+ {
+ public:
+ typedef codecvt_base::result result;
+ typedef __gnu_test::pod_uchar intern_type;
+ typedef char extern_type;
+ typedef __gnu_test::pod_state state_type;
+ typedef __codecvt_abstract_base<intern_type, extern_type, state_type>
+ base_type;
+
+ explicit codecvt(size_t refs = 0) : base_type(refs)
+ { }
+
+ static locale::id id;
+
+ protected:
+ ~codecvt()
+ { }
+
+ virtual result
+ do_out(state_type& state, const intern_type* from,
+ const intern_type* from_end, const intern_type*& from_next,
+ extern_type* to, extern_type* to_limit,
+ extern_type*& to_next) const
+ {
+ while (from < from_end && to < to_limit)
+ {
+ unsigned char tmp = (state.value ^ from->value);
+ if (state.value & 0x8)
+ {
+ if (to >= to_limit - 2)
+ break;
+ *to++ = (tmp & 0x7);
+ *to++ = ((tmp >> 3) & 0x7);
+ *to++ = ((tmp >> 6) & 0x3);
+ }
+ else
+ {
+ if (to >= to_limit - 1)
+ break;
+ *to++ = (tmp & 0xf);
+ *to++ = ((tmp >> 4) & 0xf);
+ }
+ state.value = tmp;
+ ++from;
+ }
+
+ from_next = from;
+ to_next = to;
+ return (from < from_end) ? partial : ok;
+ }
+
+ virtual result
+ do_in(state_type& state, const extern_type* from,
+ const extern_type* from_end, const extern_type*& from_next,
+ intern_type* to, intern_type* to_limit,
+ intern_type*& to_next) const
+ {
+ while (from < from_end && to < to_limit)
+ {
+ unsigned char c = *from;
+ if (c & 0xc0)
+ {
+ // Unshift sequence
+ state.value &= c;
+ ++from;
+ continue;
+ }
+
+ unsigned char tmp;
+ if (state.value & 0x8)
+ {
+ if (from >= from_end - 2)
+ break;
+ tmp = (*from++ & 0x7);
+ tmp |= ((*from++ << 3) & 0x38);
+ tmp |= ((*from++ << 6) & 0xc0);
+ }
+ else
+ {
+ if (from >= from_end - 1)
+ break;
+ tmp = (*from++ & 0xf);
+ tmp |= ((*from++ << 4) & 0xf0);
+ }
+ to->value = (tmp ^ state.value);
+ state.value = tmp;
+ ++to;
+ }
+
+ from_next = from;
+ to_next = to;
+ return (from < from_end) ? partial : ok;
+ }
+
+ virtual result
+ do_unshift(state_type& state, extern_type* to, extern_type* to_limit,
+ extern_type*& to_next) const
+ {
+ for (unsigned int i = 0; i < CHAR_BIT; ++i)
+ {
+ unsigned int mask = (1 << i);
+ if (state.value & mask)
+ {
+ if (to == to_limit)
+ {
+ to_next = to;
+ return partial;
+ }
+
+ state.value &= ~mask;
+ *to++ = static_cast<unsigned char>(~mask);
+ }
+ }
+
+ to_next = to;
+ return state.value == 0 ? ok : error;
+ }
+
+ virtual int
+ do_encoding() const throw()
+ { return -1; }
+
+ virtual bool
+ do_always_noconv() const throw()
+ { return false; }
+
+ virtual int
+ do_length(state_type& state, const extern_type* from,
+ const extern_type* end, size_t max) const
+ {
+ const extern_type* beg = from;
+ while (from < end && max)
+ {
+ unsigned char c = *from;
+ if (c & 0xc0)
+ {
+ // Unshift sequence
+ state.value &= c;
+ ++from;
+ continue;
+ }
+
+ unsigned char tmp;
+ if (state.value & 0x8)
+ {
+ if (from >= end - 2)
+ break;
+ tmp = (*from++ & 0x7);
+ tmp |= ((*from++ << 3) & 0x38);
+ tmp |= ((*from++ << 6) & 0xc0);
+ }
+ else
+ {
+ if (from >= end - 1)
+ break;
+ tmp = (*from++ & 0xf);
+ tmp |= ((*from++ << 4) & 0xf0);
+ }
+ state.value = tmp;
+ --max;
+ }
+ return from - beg;
+ }
+
+ // Maximum 8 bytes unshift sequence followed by max 3 bytes for
+ // one character.
+ virtual int
+ do_max_length() const throw()
+ { return 11; }
+ };
+
+ template<>
+ class ctype<__gnu_test::pod_uchar>
+ : public __ctype_abstract_base<__gnu_test::pod_uchar>
+ {
+ public:
+ typedef __gnu_test::pod_uchar char_type;
+
+ explicit ctype(size_t refs = 0)
+ : __ctype_abstract_base<__gnu_test::pod_uchar>(refs) { }
+
+ static locale::id id;
+
+ protected:
+ ~ctype()
+ { }
+
+ virtual bool
+ do_is(mask, char_type) const
+ { return false; }
+
+ virtual const char_type*
+ do_is(const char_type* low, const char_type* high, mask* vec) const
+ {
+ fill_n(vec, high - low, mask());
+ return high;
+ }
+
+ virtual const char_type*
+ do_scan_is(mask, const char_type*, const char_type* high) const
+ { return high; }
+
+ virtual const char_type*
+ do_scan_not(mask, const char_type* low, const char_type*) const
+ { return low; }
+
+ virtual char_type
+ do_toupper(char_type c) const
+ { return c; }
+
+ virtual const char_type*
+ do_toupper(char_type*, const char_type* high) const
+ { return high; }
+
+ virtual char_type
+ do_tolower(char_type c) const
+ { return c; }
+
+ virtual const char_type*
+ do_tolower(char_type*, const char_type* high) const
+ { return high; }
+
+ virtual char_type
+ do_widen(char c) const
+ { return __gnu_test::pod_uchar::from<char>(c); }
+
+ virtual const char*
+ do_widen(const char* low, const char* high, char_type* dest) const
+ {
+ transform(low, high, dest, &__gnu_test::pod_uchar::from<char>);
+ return high;
+ }
+
+ virtual char
+ do_narrow(char_type, char dfault) const
+ { return dfault; }
+
+ virtual const char_type*
+ do_narrow(const char_type* low, const char_type* high,
+ char dfault, char* dest) const
+ {
+ fill_n(dest, high - low, dfault);
+ return high;
+ }
+ };
+
+ // numpunct specializations
+ template<>
+ class numpunct<__gnu_test::pod_uint>
+ : public locale::facet
+ {
+ public:
+ typedef __gnu_test::pod_uint char_type;
+ typedef basic_string<char_type> string_type;
+
+ static locale::id id;
+
+ explicit
+ numpunct(size_t refs = 0)
+ : locale::facet(refs)
+ { }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ truename() const
+ { return this->do_truename(); }
+
+ string_type
+ falsename() const
+ { return this->do_falsename(); }
+
+ protected:
+ ~numpunct()
+ { }
+
+ virtual char_type
+ do_decimal_point() const
+ { return char_type(); }
+
+ virtual char_type
+ do_thousands_sep() const
+ { return char_type(); }
+
+ virtual string
+ do_grouping() const
+ { return string(); }
+
+ virtual string_type
+ do_truename() const
+ { return string_type(); }
+
+ virtual string_type
+ do_falsename() const
+ { return string_type(); }
+ };
+
+ template<>
+ class moneypunct<__gnu_test::pod_uint>
+ : public locale::facet, public money_base
+ {
+ public:
+ typedef __gnu_test::pod_uint char_type;
+ typedef basic_string<char_type> string_type;
+
+ static locale::id id;
+ static const bool intl = false;
+
+ explicit
+ moneypunct(size_t refs = 0)
+ : locale::facet(refs)
+ { }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ curr_symbol() const
+ { return this->do_curr_symbol(); }
+
+ string_type
+ positive_sign() const
+ { return this->do_positive_sign(); }
+
+ string_type
+ negative_sign() const
+ { return this->do_negative_sign(); }
+
+ int
+ frac_digits() const
+ { return this->do_frac_digits(); }
+
+ pattern
+ pos_format() const
+ { return this->do_pos_format(); }
+
+ pattern
+ neg_format() const
+ { return this->do_neg_format(); }
+
+ protected:
+ ~moneypunct()
+ { }
+
+ virtual char_type
+ do_decimal_point() const
+ { return char_type(); }
+
+ virtual char_type
+ do_thousands_sep() const
+ { return char_type(); }
+
+ virtual string
+ do_grouping() const
+ { return string(); }
+
+ virtual string_type
+ do_curr_symbol() const
+ { return string_type(); }
+
+ string_type
+ do_positive_sign() const
+ { return string_type(); }
+
+ string_type
+ do_negative_sign() const
+ { return string_type(); }
+
+ int
+ do_frac_digits() const
+ { return 0; }
+
+ pattern
+ do_pos_format() const
+ { return pattern(); }
+
+ pattern
+ do_neg_format() const
+ { return pattern(); }
+ };
+} // namespace std
+
+#endif // _GLIBCXX_TESTSUITE_CHARACTER_H
+
--- /dev/null
+// -*- C++ -*-
+// typelist for the C++ library testsuite.
+//
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#ifndef _TESTSUITE_COMMON_TYPES_H
+#define _TESTSUITE_COMMON_TYPES_H 1
+
+#include <testsuite_visualization.h>
+#include <ext/typelist.h>
+
+#include <ext/new_allocator.h>
+#include <ext/malloc_allocator.h>
+#include <ext/mt_allocator.h>
+#include <ext/bitmap_allocator.h>
+#include <ext/pool_allocator.h>
+
+#include <vector>
+#include <list>
+#include <deque>
+#include <string>
+
+#include <map>
+#include <set>
+#include <ext/hash_map>
+#include <ext/hash_set>
+#include <tr1/unordered_map>
+#include <tr1/unordered_set>
+
+namespace __gnu_test
+{
+ using __gnu_cxx::typelist;
+ using __gnu_cxx::transform;
+ using __gnu_cxx::append;
+
+ // All the allocators to test.
+ template<typename Tp, bool Thread>
+ struct allocator_policies
+ {
+ typedef Tp value_type;
+ typedef __gnu_cxx::new_allocator<Tp> a1;
+ typedef __gnu_cxx::malloc_allocator<Tp> a2;
+ typedef __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, Thread> pool_policy;
+ typedef __gnu_cxx::__mt_alloc<Tp, pool_policy> a3;
+ typedef __gnu_cxx::bitmap_allocator<Tp> a4;
+ typedef __gnu_cxx::__pool_alloc<Tp> a5;
+ typedef typelist<_GLIBCXX_TYPELIST_CHAIN5(a1, a2, a3, a4, a5)> type;
+ };
+
+ // Typelists for vector, string, list, deque.
+ // XXX should just use template templates
+ template<typename Tp, bool Thread>
+ struct vectors
+ {
+ typedef Tp value_type;
+
+ template<typename Tl>
+ struct vector_shell
+ {
+ typedef Tl allocator_type;
+ typedef std::vector<value_type, allocator_type> type;
+ };
+
+ typedef allocator_policies<value_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, vector_shell>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct lists
+ {
+ typedef Tp value_type;
+
+ template<typename Tl>
+ struct list_shell
+ {
+ typedef Tl allocator_type;
+ typedef std::list<value_type, allocator_type> type;
+ };
+
+ typedef allocator_policies<value_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, list_shell>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct deques
+ {
+ typedef Tp value_type;
+
+ template<typename Tl>
+ struct deque_shell
+ {
+ typedef Tl allocator_type;
+ typedef std::deque<value_type, allocator_type> type;
+ };
+
+ typedef allocator_policies<value_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, deque_shell>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct strings
+ {
+ typedef Tp value_type;
+
+ template<typename Tl>
+ struct string_shell
+ {
+ typedef Tl allocator_type;
+ typedef std::char_traits<value_type> traits_type;
+ typedef std::basic_string<value_type, traits_type, allocator_type> type;
+ };
+
+ typedef allocator_policies<value_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, string_shell>::type type;
+ };
+
+ // A typelist of vector, list, deque, and string all instantiated
+ // with each of the allocator policies.
+ template<typename Tp, bool Thread>
+ struct sequence_containers
+ {
+ typedef Tp value_type;
+
+ typedef typename vectors<value_type, Thread>::type vector_typelist;
+ typedef typename lists<value_type, Thread>::type list_typelist;
+ typedef typename deques<value_type, Thread>::type deque_typelist;
+ typedef typename strings<value_type, Thread>::type string_typelist;
+
+ typedef typename append<vector_typelist, list_typelist>::type a1;
+ typedef typename append<deque_typelist, string_typelist>::type a2;
+ typedef typename append<a1, a2>::type type;
+ };
+
+ // Typelists for map, set, hash_map, hash_set, unordered_set, unordered_map.
+ template<typename Tp, bool Thread>
+ struct maps
+ {
+ typedef Tp value_type;
+ typedef Tp key_type;
+ typedef std::pair<const key_type, value_type> pair_type;
+ typedef std::less<key_type> compare_function;
+
+ template<typename Tl>
+ struct container
+ {
+ typedef Tl allocator_type;
+ typedef std::map<key_type, value_type, compare_function, allocator_type> type;
+ };
+
+ typedef allocator_policies<pair_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, container>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct hash_maps
+ {
+ typedef Tp value_type;
+ typedef Tp key_type;
+ typedef __gnu_cxx::hash<key_type> hash_function;
+ typedef std::equal_to<key_type> equality_function;
+
+ template<typename Tl>
+ struct container
+ {
+ typedef Tl allocator_type;
+ typedef __gnu_cxx::hash_map<key_type, value_type, hash_function, equality_function, allocator_type> type;
+ };
+
+ typedef allocator_policies<value_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, container>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct unordered_maps
+ {
+ typedef Tp value_type;
+ typedef Tp key_type;
+ typedef std::pair<const key_type, value_type> pair_type;
+ typedef std::tr1::hash<key_type> hash_function;
+ typedef std::equal_to<key_type> equality_function;
+
+ template<typename Tl>
+ struct container
+ {
+ typedef Tl allocator_type;
+ typedef std::tr1::unordered_map<key_type, value_type, hash_function, equality_function, allocator_type> type;
+ };
+
+ typedef allocator_policies<pair_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, container>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct sets
+ {
+ typedef Tp value_type;
+ typedef Tp key_type;
+ typedef std::less<key_type> compare_function;
+
+ template<typename Tl>
+ struct container
+ {
+ typedef Tl allocator_type;
+ typedef std::set<key_type, compare_function, allocator_type> type;
+ };
+
+ typedef allocator_policies<key_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, container>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct hash_sets
+ {
+ typedef Tp value_type;
+ typedef Tp key_type;
+ typedef __gnu_cxx::hash<key_type> hash_function;
+ typedef std::equal_to<key_type> equality_function;
+
+ template<typename Tl>
+ struct container
+ {
+ typedef Tl allocator_type;
+ typedef __gnu_cxx::hash_set<key_type, hash_function, equality_function, allocator_type> type;
+ };
+
+ typedef allocator_policies<key_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, container>::type type;
+ };
+
+ template<typename Tp, bool Thread>
+ struct unordered_sets
+ {
+ typedef Tp value_type;
+ typedef Tp key_type;
+ typedef std::tr1::hash<key_type> hash_function;
+ typedef std::equal_to<key_type> equality_function;
+
+ template<typename Tl>
+ struct container
+ {
+ typedef Tl allocator_type;
+ typedef std::tr1::unordered_set<key_type, hash_function, equality_function, allocator_type> type;
+ };
+
+ typedef allocator_policies<key_type, Thread> allocator_types;
+ typedef typename allocator_types::type allocator_typelist;
+ typedef typename transform<allocator_typelist, container>::type type;
+ };
+
+
+ // A typelist of all associated container types, with each of the
+ // allocator policies.
+ template<typename Tp, bool Thread>
+ struct associative_containers
+ {
+ typedef Tp value_type;
+
+ typedef typename maps<value_type, Thread>::type map_typelist;
+ typedef typename sets<value_type, Thread>::type set_typelist;
+ typedef typename hash_maps<value_type, Thread>::type hash_map_typelist;
+ typedef typename hash_sets<value_type, Thread>::type hash_set_typelist;
+ typedef typename unordered_maps<value_type, Thread>::type unordered_map_typelist;
+ typedef typename unordered_sets<value_type, Thread>::type unordered_set_typelist;
+
+ typedef typename append<map_typelist, hash_map_typelist>::type a1;
+ typedef typename append<a1, unordered_map_typelist>::type a2;
+ typedef typename append<set_typelist, hash_set_typelist>::type a3;
+ typedef typename append<a3, unordered_set_typelist>::type a4;
+ typedef typename append<a2, a4>::type type;
+ };
+
+} // namespace __gnu_test
+
+
+// Function template, function objects for the tests.
+template<typename TestType>
+ struct value_type : public std::pair<const TestType, TestType>
+ {
+ inline value_type& operator++()
+ {
+ ++this->second;
+ return *this;
+ }
+
+ inline operator TestType() const { return this->second; }
+ };
+
+template<typename Container, int Iter>
+ void
+ do_loop();
+
+template<typename Container, int Iter>
+ void*
+ do_thread(void* p = NULL)
+ {
+ do_loop<Container, Iter>();
+ return p;
+ }
+
+template<typename Container, int Iter, bool Thread>
+ void
+ test_container(const char* filename)
+ {
+ using namespace __gnu_test;
+ time_counter time;
+ resource_counter resource;
+ {
+ start_counters(time, resource);
+ if (!Thread)
+ {
+ // No threads, so run 4x.
+ do_loop<Container, Iter * 4>();
+ }
+ else
+ {
+#if defined (_GLIBCXX_GCC_GTHR_POSIX_H) && !defined (NOTHREAD)
+ pthread_t t1, t2, t3, t4;
+ pthread_create(&t1, 0, &do_thread<Container, Iter>, 0);
+ pthread_create(&t2, 0, &do_thread<Container, Iter>, 0);
+ pthread_create(&t3, 0, &do_thread<Container, Iter>, 0);
+ pthread_create(&t4, 0, &do_thread<Container, Iter>, 0);
+
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+ pthread_join(t3, NULL);
+ pthread_join(t4, NULL);
+#endif
+ }
+ stop_counters(time, resource);
+
+ // Detailed text data.
+ Container obj;
+ int status;
+ std::ostringstream comment;
+ comment << "type: " << abi::__cxa_demangle(typeid(obj).name(),
+ 0, 0, &status);
+ report_header(filename, comment.str());
+ report_performance("", "", time, resource);
+
+ // Detailed data for visualization.
+ std::string vizfilename(filename);
+ vizfilename += ".dat";
+ write_viz_data(time, vizfilename.c_str());
+ }
+ }
+
+template<bool Thread>
+ struct test_sequence
+ {
+ test_sequence(const char* filename) : _M_filename(filename) { }
+
+ template<class Container>
+ void
+ operator()(__gnu_cxx::detail::type_to_type<Container>)
+ {
+ const int i = 20000;
+ test_container<Container, i, Thread>(_M_filename);
+ }
+
+ private:
+ const char* _M_filename;
+ };
+
+
+inline std::string::size_type
+sequence_find_container(std::string& type)
+{
+ const std::string::size_type npos = std::string::npos;
+ std::string::size_type n1 = type.find("vector");
+ std::string::size_type n2 = type.find("list");
+ std::string::size_type n3 = type.find("deque");
+ std::string::size_type n4 = type.find("string");
+
+ if (n1 != npos || n2 != npos || n3 != npos || n4 != npos)
+ return std::min(std::min(n1, n2), std::min(n3, n4));
+ else
+ throw std::runtime_error("sequence_find_container not found");
+}
+
+inline std::string::size_type
+associative_find_container(std::string& type)
+{
+ using std::string;
+ string::size_type n1 = type.find("map");
+ string::size_type n2 = type.find("set");
+ if (n1 != string::npos || n2 != string::npos)
+ return std::min(n1, n2);
+ else
+ throw std::runtime_error("associative_find_container not found");
+}
+#endif
--- /dev/null
+// -*- C++ -*-
+
+// Utility subroutines for the C++ library testsuite.
+//
+// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#include <testsuite_hooks.h>
+
+#ifdef _GLIBCXX_RES_LIMITS
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#include <list>
+#include <string>
+#include <stdexcept>
+#include <clocale>
+#include <locale>
+#include <cxxabi.h>
+
+// If we have <sys/types.h>, <sys/ipc.h>, and <sys/sem.h>, then assume
+// that System V semaphores are available.
+#if defined(_GLIBCXX_HAVE_SYS_TYPES_H) \
+ && defined(_GLIBCXX_HAVE_SYS_IPC_H) \
+ && defined(_GLIBCXX_HAVE_SYS_SEM_H)
+#define _GLIBCXX_SYSV_SEM
+#endif
+
+#ifdef _GLIBCXX_SYSV_SEM
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#endif
+
+namespace __gnu_test
+{
+#ifdef _GLIBCXX_RES_LIMITS
+ void
+ set_memory_limits(float size)
+ {
+ struct rlimit r;
+ // Cater to the absence of rlim_t.
+ __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size * 1048576);
+
+ // Heap size, seems to be common.
+#if _GLIBCXX_HAVE_LIMIT_DATA
+ getrlimit(RLIMIT_DATA, &r);
+ r.rlim_cur = limit;
+ setrlimit(RLIMIT_DATA, &r);
+#endif
+
+ // Resident set size.
+#if _GLIBCXX_HAVE_LIMIT_RSS
+ getrlimit(RLIMIT_RSS, &r);
+ r.rlim_cur = limit;
+ setrlimit(RLIMIT_RSS, &r);
+#endif
+
+ // Mapped memory (brk + mmap).
+#if _GLIBCXX_HAVE_LIMIT_VMEM
+ getrlimit(RLIMIT_VMEM, &r);
+ r.rlim_cur = limit;
+ setrlimit(RLIMIT_VMEM, &r);
+#endif
+
+ // Virtual memory.
+ // On HP-UX 11.23, a trivial C++ program that sets RLIMIT_AS to
+ // anything less than 128MB cannot "malloc" even 1K of memory.
+ // Therefore, we skip RLIMIT_AS on HP-UX.
+#if _GLIBCXX_HAVE_LIMIT_AS && !defined(__hpux__)
+ getrlimit(RLIMIT_AS, &r);
+ r.rlim_cur = limit;
+ setrlimit(RLIMIT_AS, &r);
+#endif
+ }
+
+#else
+ void
+ set_memory_limits(float) { }
+#endif
+
+#ifdef _GLIBCXX_RES_LIMITS
+ void
+ set_file_limit(unsigned long size)
+ {
+#if _GLIBCXX_HAVE_LIMIT_FSIZE
+ struct rlimit r;
+ // Cater to the absence of rlim_t.
+ __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur))(size);
+
+ getrlimit(RLIMIT_FSIZE, &r);
+ r.rlim_cur = limit;
+ setrlimit(RLIMIT_FSIZE, &r);
+#endif
+ }
+
+#else
+ void
+ set_file_limit(unsigned long) { }
+#endif
+
+ void
+ verify_demangle(const char* mangled, const char* wanted)
+ {
+ int status = 0;
+ const char* s = abi::__cxa_demangle(mangled, 0, 0, &status);
+ if (!s)
+ {
+ switch (status)
+ {
+ case 0:
+ s = "error code = 0: success";
+ break;
+ case -1:
+ s = "error code = -1: memory allocation failure";
+ break;
+ case -2:
+ s = "error code = -2: invalid mangled name";
+ break;
+ case -3:
+ s = "error code = -3: invalid arguments";
+ break;
+ default:
+ s = "error code unknown - who knows what happened";
+ }
+ }
+
+ std::string w(wanted);
+ if (w != s)
+ std::__throw_runtime_error(s);
+ }
+
+ void
+ run_tests_wrapped_locale(const char* name, const func_callback& l)
+ {
+ using namespace std;
+ bool test = true;
+
+ // Set the global locale.
+ locale loc_name = locale(name);
+ locale orig = locale::global(loc_name);
+
+ const char* res = setlocale(LC_ALL, name);
+ if (res != NULL)
+ {
+ string preLC_ALL = res;
+ const func_callback::test_type* tests = l.tests();
+ for (int i = 0; i < l.size(); ++i)
+ (*tests[i])();
+ string postLC_ALL= setlocale(LC_ALL, NULL);
+ VERIFY( preLC_ALL == postLC_ALL );
+ }
+ else
+ {
+ string s("LC_ALL for ");
+ s += name;
+ __throw_runtime_error(s.c_str());
+ }
+ }
+
+ void
+ run_tests_wrapped_env(const char* name, const char* env,
+ const func_callback& l)
+ {
+ using namespace std;
+ bool test = true;
+
+#ifdef _GLIBCXX_HAVE_SETENV
+ // Set the global locale.
+ locale loc_name = locale(name);
+ locale orig = locale::global(loc_name);
+
+ // Set environment variable env to value in name.
+ const char* oldENV = getenv(env);
+ if (!setenv(env, name, 1))
+ {
+ const func_callback::test_type* tests = l.tests();
+ for (int i = 0; i < l.size(); ++i)
+ (*tests[i])();
+ setenv(env, oldENV ? oldENV : "", 1);
+ }
+ else
+ {
+ string s(env);
+ s += string(" to ");
+ s += string(name);
+ __throw_runtime_error(s.c_str());
+ }
+#endif
+ }
+
+ counter::size_type counter::count = 0;
+ unsigned int copy_constructor::count_ = 0;
+ unsigned int copy_constructor::throw_on_ = 0;
+ unsigned int assignment_operator::count_ = 0;
+ unsigned int assignment_operator::throw_on_ = 0;
+ unsigned int destructor::_M_count = 0;
+ int copy_tracker::next_id_ = 0;
+
+#ifdef _GLIBCXX_SYSV_SEM
+ // This union is not declared in system headers. Instead, it must
+ // be defined by user programs.
+ union semun
+ {
+ int val;
+ struct semid_ds *buf;
+ unsigned short *array;
+ };
+#endif
+
+ semaphore::semaphore()
+ {
+#ifdef _GLIBCXX_SYSV_SEM
+ // Remeber the PID for the process that created the semaphore set
+ // so that only one process will destroy the set.
+ pid_ = getpid();
+
+ // GLIBC does not define SEM_R and SEM_A.
+#ifndef SEM_R
+#define SEM_R 0400
+#endif
+
+#ifndef SEM_A
+#define SEM_A 0200
+#endif
+
+ // Get a semaphore set with one semaphore.
+ sem_set_ = semget(IPC_PRIVATE, 1, SEM_R | SEM_A);
+ if (sem_set_ == -1)
+ std::__throw_runtime_error("could not obtain semaphore set");
+
+ // Initialize the semaphore.
+ union semun val;
+ val.val = 0;
+ if (semctl(sem_set_, 0, SETVAL, val) == -1)
+ std::__throw_runtime_error("could not initialize semaphore");
+#else
+ // There are no semaphores on this system. We have no way to mark
+ // a test as "unsupported" at runtime, so we just exit, pretending
+ // that the test passed.
+ exit(0);
+#endif
+ }
+
+ semaphore::~semaphore()
+ {
+#ifdef _GLIBCXX_SYSV_SEM
+ union semun val;
+ // Destroy the semaphore set only in the process that created it.
+ if (pid_ == getpid())
+ semctl(sem_set_, 0, IPC_RMID, val);
+#endif
+ }
+
+ void
+ semaphore::signal()
+ {
+#ifdef _GLIBCXX_SYSV_SEM
+ struct sembuf op[1] =
+ {
+ { 0, 1, 0 }
+ };
+ if (semop(sem_set_, op, 1) == -1)
+ std::__throw_runtime_error("could not signal semaphore");
+#endif
+ }
+
+ void
+ semaphore::wait()
+ {
+#ifdef _GLIBCXX_SYSV_SEM
+ struct sembuf op[1] =
+ {
+ { 0, -1, SEM_UNDO }
+ };
+ if (semop(sem_set_, op, 1) == -1)
+ std::__throw_runtime_error("could not wait for semaphore");
+#endif
+ }
+
+ // For use in 22_locale/time_get and time_put.
+ tm
+ test_tm(int sec, int min, int hour, int mday, int mon,
+ int year, int wday, int yday, int isdst)
+ {
+ static tm tmp;
+ tmp.tm_sec = sec;
+ tmp.tm_min = min;
+ tmp.tm_hour = hour;
+ tmp.tm_mday = mday;
+ tmp.tm_mon = mon;
+ tmp.tm_year = year;
+ tmp.tm_wday = wday;
+ tmp.tm_yday = yday;
+ tmp.tm_isdst = isdst;
+ return tmp;
+ }
+}; // namespace __gnu_test
--- /dev/null
+// -*- C++ -*-
+// Utility subroutines for the C++ library testsuite.
+//
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+// This file provides the following:
+//
+// 1) VERIFY(), via _GLIBCXX_ASSERT, from Brent Verner <brent@rcfile.org>.
+// This file is included in the various testsuite programs to provide
+// #define(able) assert() behavior for debugging/testing. It may be
+// a suitable location for other furry woodland creatures as well.
+//
+// 2) set_memory_limits()
+// set_memory_limits() uses setrlimit() to restrict dynamic memory
+// allocation. We provide a default memory limit if none is passed by the
+// calling application. The argument to set_memory_limits() is the
+// limit in megabytes (a floating-point number). If _GLIBCXX_RES_LIMITS is
+// not #defined before including this header, then no limiting is attempted.
+//
+// 3) counter
+// This is a POD with a static data member, gnu_counting_struct::count,
+// which starts at zero, increments on instance construction, and decrements
+// on instance destruction. "assert_count(n)" can be called to VERIFY()
+// that the count equals N.
+//
+// 4) copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>.
+// A class with nontrivial ctor/dtor that provides the ability to track the
+// number of copy ctors and dtors, and will throw on demand during copy.
+
+#ifndef _GLIBCXX_TESTSUITE_HOOKS_H
+#define _GLIBCXX_TESTSUITE_HOOKS_H
+
+#include <bits/c++config.h>
+#include <bits/functexcept.h>
+#include <cstddef>
+#include <locale>
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef _GLIBCXX_ASSERT
+# include <cassert>
+# define VERIFY(fn) assert(fn)
+#else
+# define VERIFY(fn) test &= (fn)
+#endif
+
+#ifdef _GLIBCXX_HAVE_UNISTD_H
+# include <unistd.h>
+#else
+# define unlink(x)
+#endif
+
+namespace __gnu_test
+{
+ // All macros are defined in GLIBCXX_CONFIGURE_TESTSUITE and imported
+ // from c++config.h
+
+ // Set memory limits if possible, if not set to 0.
+#ifndef _GLIBCXX_RES_LIMITS
+# define MEMLIMIT_MB 0
+#else
+# ifndef MEMLIMIT_MB
+# define MEMLIMIT_MB 16.0
+# endif
+#endif
+ extern void
+ set_memory_limits(float __size = MEMLIMIT_MB);
+
+ extern void
+ set_file_limit(unsigned long __size);
+
+ // Check mangled name demangles (using __cxa_demangle) as expected.
+ void
+ verify_demangle(const char* mangled, const char* wanted);
+
+ // 17.3.2.1.2 - Bitmask types [lib.bitmask.types]
+ // bitmask_operators
+ template<typename bitmask_type>
+ void
+ bitmask_operators(bitmask_type a = bitmask_type(),
+ bitmask_type b = bitmask_type())
+ {
+ a | b;
+ a & b;
+ a ^ b;
+ ~b;
+ a |= b; // set
+ a &= ~b; // clear
+ a ^= b;
+ }
+
+ // Simple callback structure for variable numbers of tests (all with
+ // same signature). Assume all unit tests are of the signature
+ // void test01();
+ class func_callback
+ {
+ public:
+ typedef void (*test_type) (void);
+
+ private:
+ int _M_size;
+ test_type _M_tests[15];
+
+ func_callback&
+ operator=(const func_callback&);
+
+ func_callback(const func_callback&);
+
+ public:
+ func_callback(): _M_size(0) { };
+
+ int
+ size() const { return _M_size; }
+
+ const test_type*
+ tests() const { return _M_tests; }
+
+ void
+ push_back(test_type test)
+ {
+ _M_tests[_M_size] = test;
+ ++_M_size;
+ }
+ };
+
+
+ // Run select unit tests after setting global locale.
+ void
+ run_tests_wrapped_locale(const char*, const func_callback&);
+
+ // Run select unit tests after setting environment variables.
+ void
+ run_tests_wrapped_env(const char*, const char*, const func_callback&);
+
+
+ // For containers (23.1/3).
+ struct NonDefaultConstructible
+ {
+ NonDefaultConstructible(int) { }
+ };
+
+ inline bool
+ operator==(const NonDefaultConstructible&,
+ const NonDefaultConstructible&)
+ { return false; }
+
+ inline bool
+ operator<(const NonDefaultConstructible&,
+ const NonDefaultConstructible&)
+ { return false; }
+
+
+ // Counting.
+ struct counter
+ {
+ // Specifically and glaringly-obviously marked 'signed' so that when
+ // COUNT mistakenly goes negative, we can track the patterns of
+ // deletions more easily.
+ typedef signed int size_type;
+ static size_type count;
+ counter() { ++count; }
+ counter (const counter&) { ++count; }
+ ~counter() { --count; }
+ };
+
+#define assert_count(n) VERIFY(__gnu_test::counter::count == n)
+
+ // A (static) class for counting copy constructors and possibly throwing an
+ // exception on a desired count.
+ class copy_constructor
+ {
+ public:
+ static unsigned int
+ count() { return count_; }
+
+ static void
+ mark_call()
+ {
+ count_++;
+ if (count_ == throw_on_)
+ std::__throw_runtime_error("copy_constructor::mark_call");
+ }
+
+ static void
+ reset()
+ {
+ count_ = 0;
+ throw_on_ = 0;
+ }
+
+ static void
+ throw_on(unsigned int count) { throw_on_ = count; }
+
+ private:
+ static unsigned int count_;
+ static unsigned int throw_on_;
+ };
+
+ // A (static) class for counting assignment operator calls and
+ // possibly throwing an exception on a desired count.
+ class assignment_operator
+ {
+ public:
+ static unsigned int
+ count() { return count_; }
+
+ static void
+ mark_call()
+ {
+ count_++;
+ if (count_ == throw_on_)
+ std::__throw_runtime_error("assignment_operator::mark_call");
+ }
+
+ static void
+ reset()
+ {
+ count_ = 0;
+ throw_on_ = 0;
+ }
+
+ static void
+ throw_on(unsigned int count) { throw_on_ = count; }
+
+ private:
+ static unsigned int count_;
+ static unsigned int throw_on_;
+ };
+
+ // A (static) class for tracking calls to an object's destructor.
+ class destructor
+ {
+ public:
+ static unsigned int
+ count() { return _M_count; }
+
+ static void
+ mark_call() { _M_count++; }
+
+ static void
+ reset() { _M_count = 0; }
+
+ private:
+ static unsigned int _M_count;
+ };
+
+ // An class of objects that can be used for validating various
+ // behaviours and guarantees of containers and algorithms defined in
+ // the standard library.
+ class copy_tracker
+ {
+ public:
+ // Creates a copy-tracking object with the given ID number. If
+ // "throw_on_copy" is set, an exception will be thrown if an
+ // attempt is made to copy this object.
+ copy_tracker(int id = next_id_--, bool throw_on_copy = false)
+ : id_(id) , throw_on_copy_(throw_on_copy) { }
+
+ // Copy-constructs the object, marking a call to the copy
+ // constructor and forcing an exception if indicated.
+ copy_tracker(const copy_tracker& rhs)
+ : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_)
+ {
+ if (throw_on_copy_)
+ copy_constructor::throw_on(copy_constructor::count() + 1);
+ copy_constructor::mark_call();
+ }
+
+ // Assigns the value of another object to this one, tracking the
+ // number of times this member function has been called and if the
+ // other object is supposed to throw an exception when it is
+ // copied, well, make it so.
+ copy_tracker&
+ operator=(const copy_tracker& rhs)
+ {
+ id_ = rhs.id();
+ if (rhs.throw_on_copy_)
+ assignment_operator::throw_on(assignment_operator::count() + 1);
+ assignment_operator::mark_call();
+ return *this;
+ }
+
+ ~copy_tracker()
+ { destructor::mark_call(); }
+
+ int
+ id() const { return id_; }
+
+ private:
+ int id_;
+ const bool throw_on_copy_;
+
+ public:
+ static void
+ reset()
+ {
+ copy_constructor::reset();
+ assignment_operator::reset();
+ destructor::reset();
+ }
+
+ // for backwards-compatibility
+ static int
+ copyCount()
+ { return copy_constructor::count(); }
+
+ // for backwards-compatibility
+ static int
+ dtorCount()
+ { return destructor::count(); }
+
+ private:
+ static int next_id_;
+ };
+
+ inline bool
+ operator==(const copy_tracker& lhs, const copy_tracker& rhs)
+ { return lhs.id() == rhs.id(); }
+
+ // Class for checking required type conversions, implicit and
+ // explicit for given library data structures.
+ template<typename _Container>
+ struct conversion
+ {
+ typedef typename _Container::const_iterator const_iterator;
+
+ // Implicit conversion iterator to const_iterator.
+ static const_iterator
+ iterator_to_const_iterator()
+ {
+ _Container v;
+ const_iterator it = v.begin();
+ const_iterator end = v.end();
+ return it == end ? v.end() : it;
+ }
+ };
+
+ // A binary semaphore for use across multiple processes.
+ class semaphore
+ {
+ public:
+ // Creates a binary semaphore. The semaphore is initially in the
+ // unsignaled state.
+ semaphore();
+
+ // Destroy the semaphore.
+ ~semaphore();
+
+ // Signal the semaphore. If there are processes blocked in
+ // "wait", exactly one will be permitted to proceed.
+ void signal();
+
+ // Wait until the semaphore is signaled.
+ void wait();
+
+ private:
+ int sem_set_;
+
+ pid_t pid_;
+ };
+
+ // For use in 22_locale/time_get and time_put.
+ tm test_tm(int sec, int min, int hour, int mday, int mon,
+ int year, int wday, int yday, int isdst);
+
+} // namespace __gnu_test
+
+#endif // _GLIBCXX_TESTSUITE_HOOKS_H
+
--- /dev/null
+// -*- C++ -*-
+// Testing streambuf/filebuf/stringbuf for the C++ library testsuite.
+//
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#ifndef _GLIBCXX_TESTSUITE_IO_H
+#define _GLIBCXX_TESTSUITE_IO_H
+
+#include <fstream>
+#include <sstream>
+
+namespace __gnu_test
+{
+ // Used to verify the constraints/requirements on get and put areas
+ // as defined in
+ // 27.5.1 - Stream buffer requirements: get and put areas
+ // 27.8.1.1 - Template class basic_filebuf p 3
+ // If the file is not open (ios_base::in) -> input seq. cannot be read
+ // If the file is not open (ios_base::out) -> output seq. cannot be written
+ // Joint file position
+ // 27.8.1.4 - Overridden virtual functions p9
+ // If unbuffered, pbase == pptr == NULL
+ // 27.7.1.1 - Basic_stringbuf constructors p 1
+ // 27.8.1.2 - Basic_filebuf constructors p 1
+ // ... , initializing the base class with basic_streambuf() 27.5.2.1
+ template<typename T>
+ class constraint_buf
+ : public T
+ {
+ public:
+ bool
+ write_position()
+ {
+ bool one = this->pptr() != NULL;
+ bool two = this->pptr() < this->epptr();
+ return one && two;
+ }
+
+ bool
+ read_position()
+ {
+ bool one = this->gptr() != NULL;
+ bool two = this->gptr() < this->egptr();
+ return one && two;
+ }
+
+ bool
+ unbuffered()
+ {
+ bool one = this->pbase() == NULL;
+ bool two = this->pptr() == NULL;
+ return one && two;
+ }
+
+ bool
+ check_pointers()
+ {
+ bool one = this->eback() == NULL;
+ bool two = this->gptr() == NULL;
+ bool three = this->egptr() == NULL;
+
+ bool four = this->pbase() == NULL;
+ bool five = this->pptr() == NULL;
+ bool six = this->epptr() == NULL;
+ return one && two && three && four && five && six;
+ }
+ };
+
+ typedef constraint_buf<std::streambuf> constraint_streambuf;
+ typedef constraint_buf<std::filebuf> constraint_filebuf;
+ typedef constraint_buf<std::stringbuf> constraint_stringbuf;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef constraint_buf<std::wstreambuf> constraint_wstreambuf;
+ typedef constraint_buf<std::wfilebuf> constraint_wfilebuf;
+ typedef constraint_buf<std::wstringbuf> constraint_wstringbuf;
+#endif
+
+ // Used to check if basic_streambuf::pubsync() has been called.
+ // This is useful for checking if a function creates [io]stream::sentry
+ // objects, since the sentry constructors call tie()->flush().
+ template<typename T>
+ class sync_buf
+ : public T
+ {
+ private:
+ bool m_sync_called;
+
+ public:
+ sync_buf()
+ : m_sync_called(false)
+ { }
+
+ bool sync_called() const
+ { return m_sync_called; }
+
+ protected:
+ int sync()
+ {
+ m_sync_called = true;
+ return 0;
+ }
+ };
+
+ typedef sync_buf<std::streambuf> sync_streambuf;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef sync_buf<std::wstreambuf> sync_wstreambuf;
+#endif
+
+ // Throws on all overflow and underflow calls.
+ struct underflow_error: std::exception { };
+ struct overflow_error: std::exception { };
+ struct positioning_error: std::exception { };
+
+ template<typename T>
+ struct fail_buf
+ : public T
+ {
+ typedef typename T::char_type char_type;
+ typedef typename T::int_type int_type;
+ typedef typename T::off_type off_type;
+ typedef typename T::pos_type pos_type;
+
+ private:
+ char_type p[2];
+
+ public:
+ fail_buf()
+ {
+ p[0] = char_type('s');
+ p[1] = char_type();
+ setg(p, p, p + 1);
+ }
+
+ virtual int_type underflow()
+ {
+ throw underflow_error();
+ return int_type();
+ }
+
+ virtual int_type uflow()
+ {
+ throw underflow_error();
+ return int_type();
+ }
+
+ virtual int_type
+ overflow(int_type)
+ {
+ throw overflow_error();
+ return int_type();
+ }
+
+ virtual pos_type
+ seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode)
+ {
+ throw positioning_error();
+ return pos_type(off_type(-1));
+ }
+
+ virtual pos_type
+ seekpos(pos_type, std::ios_base::openmode)
+ {
+ throw positioning_error();
+ return pos_type(off_type(-1));
+ }
+
+ virtual int
+ sync()
+ {
+ throw positioning_error();
+ return 0;
+ }
+ };
+
+ typedef fail_buf<std::streambuf> fail_streambuf;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef fail_buf<std::wstreambuf> fail_wstreambuf;
+#endif
+
+ // Facets that throw an exception for every virtual function.
+ struct facet_error: std::exception { };
+
+ template<typename T>
+ class fail_num_get
+ : public std::num_get<T>
+ {
+ typedef std::ios_base ios_base;
+ typedef typename std::num_get<T>::iter_type iter_type;
+
+ protected:
+ iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ unsigned short&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ unsigned int&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ unsigned long&) const
+ { throw facet_error(); return iter_type(); }
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ long long&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ unsigned long long&) const
+ { throw facet_error(); return iter_type(); }
+#endif
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ float&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ double&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ long double&) const
+ { throw facet_error(); return iter_type(); }
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ void*&) const
+ { throw facet_error(); return iter_type(); }
+ };
+
+ typedef fail_num_get<char> fail_num_get_char;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef fail_num_get<wchar_t> fail_num_get_wchar_t;
+#endif
+
+ template<typename T>
+ class fail_num_put
+ : public std::num_put<T>
+ {
+ typedef std::ios_base ios_base;
+ typedef typename std::num_put<T>::iter_type iter_type;
+ typedef typename std::num_put<T>::char_type char_type;
+
+ protected:
+ iter_type
+ do_put(iter_type, ios_base&, char_type, bool) const
+ { throw facet_error(); return iter_type(NULL); }
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, long) const
+ { throw facet_error(); return iter_type(NULL); }
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, unsigned long) const
+ { throw facet_error(); return iter_type(NULL); }
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, long long) const
+ { throw facet_error(); return iter_type(NULL); }
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, unsigned long long) const
+ { throw facet_error(); return iter_type(NULL); }
+#endif
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, double) const
+ { throw facet_error(); return iter_type(NULL); }
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, long double) const
+ { throw facet_error(); return iter_type(NULL); }
+
+ virtual iter_type
+ do_put(iter_type, ios_base&, char_type, const void*) const
+ { throw facet_error(); return iter_type(NULL); }
+ };
+
+ typedef fail_num_put<char> fail_num_put_char;
+#ifdef _GLIBCXX_USE_WCHAR_T
+ typedef fail_num_put<wchar_t> fail_num_put_wchar_t;
+#endif
+}; // namespace __gnu_test
+
+#endif // _GLIBCXX_TESTSUITE_IO_H
+
--- /dev/null
+// -*- C++ -*-
+// Iterator Wrappers for the C++ library testsuite.
+//
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+// This file provides the following:
+//
+// input_iterator_wrapper, output_iterator_wrapper
+// forward_iterator_wrapper, bidirectional_iterator_wrapper and
+// random_access_wrapper, which attempt to exactly perform the requirements
+// of these types of iterators. These are constructed from the class
+// test_container, which is given two pointers to T and an iterator type.
+
+#include <testsuite_hooks.h>
+#include <iterator>
+
+#ifndef _TESTSUITE_ITERATORS
+#define _TESTSUITE_ITERATORS
+
+#ifdef DISABLE_ITERATOR_DEBUG
+#define ITERATOR_VERIFY(x)
+#else
+#define ITERATOR_VERIFY(x) VERIFY(x)
+#endif
+
+namespace __gnu_test
+{
+ /**
+ * @brief Simple container for holding two pointers.
+ *
+ * Note that input_iterator_wrapper changes first to denote
+ * how the valid range of == , ++, etc. change as the iterators are used.
+ */
+ template<typename T>
+ struct BoundsContainer
+ {
+ T* first;
+ T* last;
+ BoundsContainer(T* _first, T* _last)
+ : first(_first), last(_last)
+ { }
+ };
+
+ // Simple container for holding state of a set of output iterators.
+ template<typename T>
+ struct OutputContainer : public BoundsContainer<T>
+ {
+ T* incrementedto;
+ bool* writtento;
+ OutputContainer(T* _first, T* _last)
+ : BoundsContainer<T>(_first, _last), incrementedto(_first)
+ {
+ writtento = new bool[this->last - this->first];
+ for(int i = 0; i < this->last - this->first; i++)
+ writtento[i] = false;
+ }
+
+ ~OutputContainer()
+ { delete[] writtento; }
+ };
+
+ // Produced by output_iterator to allow limited writing to pointer
+ template<class T>
+ class WritableObject
+ {
+ T* ptr;
+
+ public:
+ OutputContainer<T>* SharedInfo;
+ WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
+ ptr(ptr_in), SharedInfo(SharedInfo_in)
+ { }
+
+ template<class U>
+ void
+ operator=(const U& new_val)
+ {
+ ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
+ SharedInfo->writtento[ptr - SharedInfo->first] = 1;
+ *ptr = new_val;
+ }
+ };
+
+ /**
+ * @brief output_iterator wrapper for pointer
+ *
+ * This class takes a pointer and wraps it to provide exactly
+ * the requirements of a output_iterator. It should not be
+ * instansiated directly, but generated from a test_container
+ */
+ template<class T>
+ struct output_iterator_wrapper: public std::iterator
+ <std::output_iterator_tag, T, ptrdiff_t, T*, T&>
+ {
+ typedef OutputContainer<T> ContainerType;
+ T* ptr;
+ ContainerType* SharedInfo;
+
+ output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+ :ptr(_ptr), SharedInfo(SharedInfo_in)
+ {
+ ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
+ }
+
+ output_iterator_wrapper(const output_iterator_wrapper& in)
+ :ptr(in.ptr), SharedInfo(in.SharedInfo)
+ { }
+
+ WritableObject<T>
+ operator*() const
+ {
+ ITERATOR_VERIFY(ptr < SharedInfo->last);
+ ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
+ return WritableObject<T>(ptr, SharedInfo);
+ }
+
+ output_iterator_wrapper&
+ operator=(const output_iterator_wrapper& in)
+ {
+ ptr = in.ptr;
+ SharedInfo = in.SharedInfo;
+ return *this;
+ }
+
+ output_iterator_wrapper&
+ operator++()
+ {
+ ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
+ ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
+ ptr++;
+ SharedInfo->incrementedto=ptr;
+ return *this;
+ }
+
+ output_iterator_wrapper
+ operator++(int)
+ {
+ output_iterator_wrapper<T> tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ };
+
+ /**
+ * @brief input_iterator wrapper for pointer
+ *
+ * This class takes a pointer and wraps it to provide exactly
+ * the requirements of a input_iterator. It should not be
+ * instansiated directly, but generated from a test_container
+ */
+ template<class T>
+ class input_iterator_wrapper:public std::iterator
+ <std::input_iterator_tag, T, ptrdiff_t, T*, T&>
+ {
+ protected:
+ input_iterator_wrapper()
+ { }
+
+ public:
+ typedef BoundsContainer<T> ContainerType;
+ T* ptr;
+ ContainerType* SharedInfo;
+
+ input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+ : ptr(_ptr), SharedInfo(SharedInfo_in)
+ { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
+
+ input_iterator_wrapper(const input_iterator_wrapper& in)
+ : ptr(in.ptr), SharedInfo(in.SharedInfo)
+ { }
+
+ bool
+ operator==(const input_iterator_wrapper& in) const
+ {
+ ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
+ ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
+ return ptr == in.ptr;
+ }
+
+ bool
+ operator!=(const input_iterator_wrapper& in) const
+ {
+ return !(*this == in);
+ }
+
+ T&
+ operator*() const
+ {
+ ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
+ ITERATOR_VERIFY(ptr >= SharedInfo->first);
+ return *ptr;
+ }
+
+ T*
+ operator->() const
+ {
+ return &**this;
+ }
+
+ input_iterator_wrapper&
+ operator=(const input_iterator_wrapper& in)
+ {
+ ptr = in.ptr;
+ SharedInfo = in.SharedInfo;
+ return *this;
+ }
+
+ input_iterator_wrapper&
+ operator++()
+ {
+ ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
+ ITERATOR_VERIFY(ptr>=SharedInfo->first);
+ ptr++;
+ SharedInfo->first=ptr;
+ return *this;
+ }
+
+ void
+ operator++(int)
+ {
+ ++*this;
+ }
+ };
+
+
+ /**
+ * @brief forward_iterator wrapper for pointer
+ *
+ * This class takes a pointer and wraps it to provide exactly
+ * the requirements of a forward_iterator. It should not be
+ * instansiated directly, but generated from a test_container
+ */
+ template<class T>
+ struct forward_iterator_wrapper:public input_iterator_wrapper<T>
+ {
+ typedef BoundsContainer<T> ContainerType;
+ typedef std::forward_iterator_tag iterator_category;
+ forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+ :input_iterator_wrapper<T>(_ptr, SharedInfo_in)
+ { }
+
+ forward_iterator_wrapper(const forward_iterator_wrapper& in)
+ :input_iterator_wrapper<T>(in)
+ { }
+
+ forward_iterator_wrapper()
+ {
+ this->ptr = NULL;
+ this->SharedInfo = NULL;
+ }
+
+ T&
+ operator*() const
+ {
+ ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+ return *(this->ptr);
+ }
+
+ T*
+ operator->() const
+ { return &**this; }
+
+ forward_iterator_wrapper&
+ operator++()
+ {
+ ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+ this->ptr++;
+ return *this;
+ }
+
+ forward_iterator_wrapper
+ operator++(int)
+ {
+ forward_iterator_wrapper<T> tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ };
+
+ /**
+ * @brief bidirectional_iterator wrapper for pointer
+ *
+ * This class takes a pointer and wraps it to provide exactly
+ * the requirements of a forward_iterator. It should not be
+ * instansiated directly, but generated from a test_container
+ */
+ template<class T>
+ struct bidirectional_iterator_wrapper:public forward_iterator_wrapper<T>
+ {
+ typedef BoundsContainer<T> ContainerType;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+ :forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
+ { }
+
+ bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
+ :forward_iterator_wrapper<T>(in)
+ { }
+
+ bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
+ { }
+
+ bidirectional_iterator_wrapper&
+ operator=(const bidirectional_iterator_wrapper& in)
+ {
+ this->ptr = in.ptr;
+ this->SharedInfo = in.SharedInfo;
+ return *this;
+ }
+
+ bidirectional_iterator_wrapper&
+ operator++()
+ {
+ ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+ this->ptr++;
+ return *this;
+ }
+
+ bidirectional_iterator_wrapper
+ operator++(int)
+ {
+ bidirectional_iterator_wrapper<T> tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bidirectional_iterator_wrapper&
+ operator--()
+ {
+ ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
+ this->ptr--;
+ return *this;
+ }
+
+ bidirectional_iterator_wrapper
+ operator--(int)
+ {
+ bidirectional_iterator_wrapper<T> tmp = *this;
+ --*this;
+ return tmp;
+ }
+ };
+
+ /**
+ * @brief random_access_iterator wrapper for pointer
+ *
+ * This class takes a pointer and wraps it to provide exactly
+ * the requirements of a forward_iterator. It should not be
+ * instansiated directly, but generated from a test_container
+ */
+ template<class T>
+ struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper<T>
+ {
+ typedef BoundsContainer<T> ContainerType;
+ typedef std::random_access_iterator_tag iterator_category;
+ random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
+ : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
+ { }
+
+ random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
+ : bidirectional_iterator_wrapper<T>(in)
+ { }
+
+ random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
+ { }
+
+ random_access_iterator_wrapper&
+ operator=(const random_access_iterator_wrapper& in)
+ {
+ this->ptr = in.ptr;
+ this->SharedInfo = in.SharedInfo;
+ return *this;
+ }
+
+ random_access_iterator_wrapper&
+ operator++()
+ {
+ ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
+ this->ptr++;
+ return *this;
+ }
+
+ random_access_iterator_wrapper
+ operator++(int)
+ {
+ random_access_iterator_wrapper<T> tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ random_access_iterator_wrapper&
+ operator--()
+ {
+ ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
+ this->ptr--;
+ return *this;
+ }
+
+ random_access_iterator_wrapper
+ operator--(int)
+ {
+ random_access_iterator_wrapper<T> tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ random_access_iterator_wrapper&
+ operator+=(ptrdiff_t n)
+ {
+ if(n > 0)
+ {
+ ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
+ this->ptr += n;
+ }
+ else
+ {
+ ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
+ this->ptr += n;
+ }
+ return *this;
+ }
+
+ random_access_iterator_wrapper&
+ operator-=(ptrdiff_t n)
+ { return *this += -n; }
+
+ random_access_iterator_wrapper
+ operator-(ptrdiff_t n) const
+ {
+ random_access_iterator_wrapper<T> tmp = *this;
+ return tmp -= n;
+ }
+
+ ptrdiff_t
+ operator-(const random_access_iterator_wrapper<T>& in) const
+ {
+ ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
+ return this->ptr - in.ptr;
+ }
+
+ T&
+ operator[](ptrdiff_t n) const
+ { return *(*this + n); }
+
+ bool
+ operator<(const random_access_iterator_wrapper<T>& in) const
+ {
+ ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
+ return this->ptr < in.ptr;
+ }
+
+ bool
+ operator>(const random_access_iterator_wrapper<T>& in) const
+ {
+ return in < *this;
+ }
+
+ bool
+ operator>=(const random_access_iterator_wrapper<T>& in) const
+ {
+ return !(*this < in);
+ }
+
+ bool
+ operator<=(const random_access_iterator_wrapper<T>& in) const
+ {
+ return !(*this > in);
+ }
+ };
+
+ template<typename T>
+ random_access_iterator_wrapper<T>
+ operator+(random_access_iterator_wrapper<T> it, ptrdiff_t n)
+ { return it += n; }
+
+ template<typename T>
+ random_access_iterator_wrapper<T>
+ operator+(ptrdiff_t n, random_access_iterator_wrapper<T> it)
+ { return it += n; }
+
+
+ /**
+ * @brief A container-type class for holding iterator wrappers
+ * test_container takes two parameters, a class T and an iterator
+ * wrapper templated by T (for example forward_iterator_wrapper<T>.
+ * It takes two pointers representing a range and presents them as
+ * a container of iterators.
+ */
+ template <class T, template<class T> class ItType>
+ struct test_container
+ {
+ typename ItType<T>::ContainerType bounds;
+ test_container(T* _first, T* _last):bounds(_first, _last)
+ { }
+
+ ItType<T>
+ it(int pos)
+ {
+ ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
+ return ItType<T>(bounds.first + pos, &bounds);
+ }
+
+ ItType<T>
+ it(T* pos)
+ {
+ ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
+ return ItType<T>(pos, &bounds);
+ }
+
+ ItType<T>
+ begin()
+ { return it(bounds.first); }
+
+ ItType<T>
+ end()
+ { return it(bounds.last); }
+ };
+}
+#endif
--- /dev/null
+// -*- C++ -*-
+// Testing performance utilities for the C++ library testsuite.
+//
+// Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#ifndef _GLIBCXX_PERFORMANCE_H
+#define _GLIBCXX_PERFORMANCE_H
+
+#include <sys/times.h>
+#include <sys/resource.h>
+#include <cstdlib>
+#include <string>
+#include <fstream>
+#include <iomanip>
+
+#ifdef __linux__
+#include <malloc.h>
+#elif defined (__FreeBSD__)
+extern "C"
+{
+ struct mallinfo
+ {
+ int uordblks;
+ int hblkhd;
+ };
+
+ struct mallinfo
+ mallinfo(void)
+ {
+ struct mallinfo m = { (((size_t) sbrk (0) + 1023) / 1024), 0 };
+ return m;
+ }
+}
+#elif !defined (__hpux__)
+extern "C"
+{
+ struct mallinfo
+ {
+ int uordblks;
+ int hblkhd;
+ };
+
+ struct mallinfo empty = { 0, 0 };
+
+ struct mallinfo
+ mallinfo(void)
+ { return empty; }
+}
+#endif
+
+namespace __gnu_test
+{
+ class time_counter
+ {
+ private:
+ clock_t elapsed_begin;
+ clock_t elapsed_end;
+ tms tms_begin;
+ tms tms_end;
+
+ public:
+ explicit
+ time_counter() : elapsed_begin(), elapsed_end(), tms_begin(), tms_end()
+ { }
+
+ void
+ clear() throw()
+ {
+ elapsed_begin = clock_t();
+ elapsed_end = clock_t();
+ tms_begin = tms();
+ tms_end = tms();
+ }
+
+ void
+ start()
+ {
+ this->clear();
+ elapsed_begin = times(&tms_begin);
+ const clock_t err = clock_t(-1);
+ if (elapsed_begin == err)
+ std::__throw_runtime_error("time_counter::start");
+ }
+
+ void
+ stop()
+ {
+ elapsed_end = times(&tms_end);
+ const clock_t err = clock_t(-1);
+ if (elapsed_end == err)
+ std::__throw_runtime_error("time_counter::stop");
+ }
+
+ size_t
+ real_time() const
+ { return elapsed_end - elapsed_begin; }
+
+ size_t
+ user_time() const
+ { return tms_end.tms_utime - tms_begin.tms_utime; }
+
+ size_t
+ system_time() const
+ { return tms_end.tms_stime - tms_begin.tms_stime; }
+ };
+
+ class resource_counter
+ {
+ int who;
+ rusage rusage_begin;
+ rusage rusage_end;
+ struct mallinfo allocation_begin;
+ struct mallinfo allocation_end;
+
+ public:
+ resource_counter(int i = RUSAGE_SELF) : who(i)
+ { this->clear(); }
+
+ void
+ clear() throw()
+ {
+ memset(&rusage_begin, 0, sizeof(rusage_begin));
+ memset(&rusage_end, 0, sizeof(rusage_end));
+ memset(&allocation_begin, 0, sizeof(allocation_begin));
+ memset(&allocation_end, 0, sizeof(allocation_end));
+ }
+
+ void
+ start()
+ {
+ if (getrusage(who, &rusage_begin) != 0 )
+ memset(&rusage_begin, 0, sizeof(rusage_begin));
+ malloc(0); // Needed for some implementations.
+ allocation_begin = mallinfo();
+ }
+
+ void
+ stop()
+ {
+ if (getrusage(who, &rusage_end) != 0 )
+ memset(&rusage_end, 0, sizeof(rusage_end));
+ allocation_end = mallinfo();
+ }
+
+ int
+ allocated_memory() const
+ { return ((allocation_end.uordblks - allocation_begin.uordblks)
+ + (allocation_end.hblkhd - allocation_begin.hblkhd)); }
+
+ long
+ hard_page_fault() const
+ { return rusage_end.ru_majflt - rusage_begin.ru_majflt; }
+
+ long
+ swapped() const
+ { return rusage_end.ru_nswap - rusage_begin.ru_nswap; }
+ };
+
+ inline void
+ start_counters(time_counter& t, resource_counter& r)
+ {
+ t.start();
+ r.start();
+ }
+
+ inline void
+ stop_counters(time_counter& t, resource_counter& r)
+ {
+ t.stop();
+ r.stop();
+ }
+
+ inline void
+ clear_counters(time_counter& t, resource_counter& r)
+ {
+ t.clear();
+ r.clear();
+ }
+
+ void
+ report_performance(const std::string file, const std::string comment,
+ const time_counter& t, const resource_counter& r)
+ {
+ const char space = ' ';
+ const char tab = '\t';
+ const char* name = "libstdc++-performance.sum";
+ std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1;
+ std::string testname(i, file.end());
+
+ std::ofstream out(name, std::ios_base::app);
+
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ testname.append("-thread");
+#endif
+
+ out.setf(std::ios_base::left);
+ out << std::setw(25) << testname << tab;
+ out << std::setw(25) << comment << tab;
+
+ out.setf(std::ios_base::right);
+ out << std::setw(4) << t.real_time() << "r" << space;
+ out << std::setw(4) << t.user_time() << "u" << space;
+ out << std::setw(4) << t.system_time() << "s" << space;
+ out << std::setw(8) << r.allocated_memory() << "mem" << space;
+ out << std::setw(4) << r.hard_page_fault() << "pf" << space;
+
+ out << std::endl;
+ out.close();
+ }
+
+ void
+ report_header(const std::string file, const std::string header)
+ {
+ const char space = ' ';
+ const char tab = '\t';
+ const char* name = "libstdc++-performance.sum";
+ std::string::const_iterator i = file.begin() + file.find_last_of('/') + 1;
+ std::string testname(i, file.end());
+
+ std::ofstream out(name, std::ios_base::app);
+
+#ifdef __GTHREADS
+ if (__gthread_active_p ())
+ testname.append("-thread");
+#endif
+
+ out.setf(std::ios_base::left);
+ out << std::setw(25) << testname << tab;
+ out << std::setw(40) << header << tab;
+
+ out << std::endl;
+ out.close();
+ }
+}; // namespace __gnu_test
+
+#endif // _GLIBCXX_PERFORMANCE_H
+
--- /dev/null
+// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <string>
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
+#include <ext/mt_allocator.h>
+
+// libstdc++/22309
+extern "C" void
+try_allocation()
+{
+ typedef char value_t;
+
+ typedef __gnu_cxx::__mt_alloc<value_t> allocator_t;
+
+ typedef std::char_traits<value_t> traits_t;
+ typedef std::basic_string<value_t, traits_t, allocator_t> string_t;
+
+ string_t s;
+ s += "west beach, indiana dunes";
+}
+
+// libstdc++/23591
+extern "C" void
+try_throw_exception()
+{
+ try
+ {
+ throw std::bad_exception();
+ }
+ catch (const std::exception& e)
+ { }
+}
+
+extern "C" void
+try_function_random_fail()
+{
+ long seed = lrand48();
+ if (seed < 2000)
+ seed = 2000;
+
+ {
+ std::ostringstream s;
+ s << "random_throw, seed: " << seed << std::endl;
+ std::cout << s.str();
+ }
+
+ while (--seed > 0)
+ {
+ try_throw_exception();
+ }
+
+ // Randomly throw. See if other threads cleanup.
+ throw std::bad_exception();
+}
--- /dev/null
+// -*- C++ -*-
+// Testing utilities for the tr1 testsuite.
+//
+// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// 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.
+
+#ifndef _GLIBCXX_TESTSUITE_TR1_H
+#define _GLIBCXX_TESTSUITE_TR1_H
+
+#include <bits/cpp_type_traits.h>
+
+namespace __gnu_test
+{
+ // For tr1/type_traits.
+ template<template<typename> class Category,
+ typename Type>
+ bool
+ test_category(bool value)
+ {
+ bool ret = true;
+ ret &= Category<Type>::value == value;
+ ret &= Category<const Type>::value == value;
+ ret &= Category<volatile Type>::value == value;
+ ret &= Category<const volatile Type>::value == value;
+ ret &= Category<Type>::type::value == value;
+ ret &= Category<const Type>::type::value == value;
+ ret &= Category<volatile Type>::type::value == value;
+ ret &= Category<const volatile Type>::type::value == value;
+ return ret;
+ }
+
+ template<template<typename> class Property,
+ typename Type>
+ bool
+ test_property(typename Property<Type>::value_type value)
+ {
+ bool ret = true;
+ ret &= Property<Type>::value == value;
+ ret &= Property<Type>::type::value == value;
+ return ret;
+ }
+
+ // For testing tr1/type_traits/extent, which has a second template
+ // parameter.
+ template<template<typename, unsigned> class Property,
+ typename Type,
+ unsigned Uint>
+ bool
+ test_property(typename Property<Type, Uint>::value_type value)
+ {
+ bool ret = true;
+ ret &= Property<Type, Uint>::value == value;
+ ret &= Property<Type, Uint>::type::value == value;
+ return ret;
+ }
+
+ template<template<typename, typename> class Relationship,
+ typename Type1, typename Type2>
+ bool
+ test_relationship(bool value)
+ {
+ bool ret = true;
+ ret &= Relationship<Type1, Type2>::value == value;
+ ret &= Relationship<Type1, Type2>::type::value == value;
+ return ret;
+ }
+
+ // Test types.
+ class ClassType { };
+ typedef const ClassType cClassType;
+ typedef volatile ClassType vClassType;
+ typedef const volatile ClassType cvClassType;
+
+ class DerivedType : public ClassType { };
+
+ enum EnumType { };
+
+ struct ConvType
+ { operator int() const; };
+
+ class AbstractClass
+ {
+ virtual void rotate(int) = 0;
+ virtual ~AbstractClass();
+ };
+
+ class PolymorphicClass
+ {
+ virtual void rotate(int);
+ virtual ~PolymorphicClass();
+ };
+
+ class DerivedPolymorphic : public PolymorphicClass { };
+
+ union UnionType { };
+
+ class IncompleteClass;
+
+ int truncate_float(float x) { return (int)x; }
+ long truncate_double(double x) { return (long)x; }
+
+ struct do_truncate_float_t
+ {
+ do_truncate_float_t()
+ {
+ ++live_objects;
+ }
+
+ do_truncate_float_t(const do_truncate_float_t&)
+ {
+ ++live_objects;
+ }
+
+ ~do_truncate_float_t()
+ {
+ --live_objects;
+ }
+
+ int operator()(float x) { return (int)x; }
+
+ static int live_objects;
+ };
+
+ int do_truncate_float_t::live_objects = 0;
+
+ struct do_truncate_double_t
+ {
+ do_truncate_double_t()
+ {
+ ++live_objects;
+ }
+
+ do_truncate_double_t(const do_truncate_double_t&)
+ {
+ ++live_objects;
+ }
+
+ ~do_truncate_double_t()
+ {
+ --live_objects;
+ }
+
+ long operator()(double x) { return (long)x; }
+
+ static int live_objects;
+ };
+
+ int do_truncate_double_t::live_objects = 0;
+
+ struct X
+ {
+ int bar;
+
+ int foo() { return 1; }
+ int foo_c() const { return 2; }
+ int foo_v() volatile { return 3; }
+ int foo_cv() const volatile { return 4; }
+ };
+
+ // For use in 8_c_compatibility.
+ template<typename R, typename T>
+ typename std::__enable_if<bool, std::__are_same<R, T>::__value>::__type
+ check_ret_type(T)
+ { return true; }
+
+} // namespace __gnu_test
+
+#endif // _GLIBCXX_TESTSUITE_TR1_H
--- /dev/null
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+
+// This library 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 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.
+
+#include <typeinfo>
+#include <stdexcept>
+#include <sstream>
+#include <fstream>
+#include <cxxabi.h>
+#include <testsuite_performance.h>
+
+// Ah, we wish it wasn't so...
+bool first_container = false;
+extern const char* filename;
+
+typedef std::string::size_type (*callback_type) (std::string&);
+
+template<typename Container, int Iter, bool Thread>
+ void
+ write_viz_container(callback_type find_container, const char* filename)
+ {
+ typedef std::string string;
+
+ // Create title.
+ {
+ const char ws(' ');
+ std::ostringstream title;
+
+ std::string titlename(filename);
+ std::string::size_type n = titlename.find('.');
+ if (n != string::npos)
+ titlename = std::string(titlename.begin(), titlename.begin() + n);
+
+ title << titlename;
+ title << ws;
+ title << Iter;
+ title << ws;
+#if 0
+ title << "thread<";
+ std::boolalpha(title);
+ title << Thread;
+ title << '>';
+#endif
+
+ titlename += ".title";
+ std::ofstream titlefile(titlename.c_str());
+ if (!titlefile.good())
+ throw std::runtime_error("write_viz_data cannot open titlename");
+ titlefile << title.str() << std::endl;
+ }
+
+ // Create compressed type name.
+ Container obj;
+ int status;
+ std::string type(abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status));
+
+ // Extract fully-qualified typename.
+ // Assumes "set" or "map" are uniquely determinate.
+ string::iterator beg = type.begin();
+ string::iterator end;
+ string::size_type n = (*find_container)(type);
+
+ // Find start of fully-qualified name.
+ // Assume map, find end.
+ string::size_type nend = type.find('<', n);
+ if (nend != string::npos)
+ end = type.begin() + nend;
+
+ string compressed_type;
+ compressed_type += '"';
+ compressed_type += string(beg, end);
+ compressed_type += '<';
+#if 0
+ typename Container::key_type v;
+ compressed_type += typeid(v).name();
+#else
+ compressed_type += "int";
+#endif
+ compressed_type += ", A>";
+
+ // XXX
+ if (Thread == true)
+ compressed_type += " thread";
+ compressed_type += '"';
+
+ std::ofstream file(filename, std::ios_base::app);
+ if (!file.good())
+ throw std::runtime_error("write_viz_data cannot open filename");
+
+ file << compressed_type;
+ first_container = false;
+ }
+
+
+void
+write_viz_data(__gnu_test::time_counter& time, const char* filename)
+{
+ std::ofstream file(filename, std::ios_base::app);
+ if (!file.good())
+ throw std::runtime_error("write_viz_data cannot open filename");
+
+ // Print out score in appropriate column.
+ const char tab('\t');
+ int score = time.real_time();
+ file << tab << score;
+}
+
+void
+write_viz_endl(const char* filename)
+{
+ std::ofstream file(filename, std::ios_base::app);
+ if (!file.good())
+ throw std::runtime_error("write_viz_endl cannot open filename");
+ file << std::endl;
+}
+
+
+#if 0
+// cons
+write_viz_container<container_type, Iter, Thread>(&sequence_find_container,
+ filename);
+#endif
+
+#if 0
+// dtor
+write_viz_endl(filename)
+#endif